2016-04-27 147 views
4

我想對NatTable內容進行純粹的UI測試(即不使用SWTBot或其他UI測試框架)。NatTable的JUnit測試

我的方法是創建一個外殼,加上我的自定義NatTable,然後接入小區,檢查其內容(數據值,配置標籤​​等):

// Note: this is Xtend code 
@Before 
def void setup() 
{ 
    shell = new Shell(Display.getCurrent) 
    shell.layout = new FillLayout 
    parent = new Composite(shell, SWT.NONE) 
    parent.layout = new GridLayout 
    fixture = new MyNatTableViewer(parent) // this is my custom nattable impl under test 
    shell.pack 
    shell.visible = true 
} 

@Test 
def void testLabel() 
{ 
    assertCellLabel(2, 2, "test-label"); 
} 

def assertCellLabel(int row, int col, String expected) 
{ 
    val labels = parameterTable.getCellByPosition(col, row)?.configLabels 
    assertThat(labels).describedAs("Labels for row " + row + " col " + col).isNotNull 
    assertThat(labels.labels).describedAs("Labels for row " + row + " col " + col).contains(expected) 
} 

爲了測試我的其他組件這就足夠了創建shell和父級組合;包裝和設置可見不需要我的測試工作。 然而,如果單元格不可見,那麼使用NatTable,getCellByPosition()將返回null - 所以我添加了代碼來打包並設置外殼可見。這適用於小型表格(2行和幾列)。

不幸的是,它不適用於大型表格。我懷疑這是因爲視口圖層不會創建不在可見區域中的單元格(我知道,這是NatTable的優勢 - 它只根據需要創建所需的結構)。當然,這對於正常運行時行爲來說是期望的。

但是有沒有一種方法可以保證獲得細胞(換句話說,我可以讓NatTable/ViewportLayer相信細胞是可見的,所以我不會得到null,只要細胞是否存在內容明智嗎?)

我當然可以直接測試我的標籤累加器,數據提供者等,但我想從黑盒子的角度來看這裏。

+0

我沒有回答你的問題,但通常的建議是保持最頂層的視圖/用戶界面層儘可能薄和笨,並測試其他一切。在你的情況下,它確實意味着測試你的單獨的NatTable組件(Accumulators,Providers,Event Handler),並且信任NatTable來正確顯示它。 – jhyot

回答

1

這個問題本身就是矛盾的。您需要使用黑盒方法來測試NatTable,但是您想要在測試中更改NatTable的行爲。那不是黑匣子方法!

如果你真的想用黑盒子方法測試,你需要確保單元格被渲染。這可以通過觸發滾動來完成,例如,通過執行ShowCellInViewportCommand。這是真正的黑盒子方法,因爲爲不可見單元格返回null是正確的結果。

如果你需要一個真正的黑盒子方法和利用內部知識(你所要求的)的方法之間的事情,你必須有方法到達那裏。

  1. ViewportLayer以下的圖層上操作。通常可以使用SelectionLayer。但是,這當然不需要任何意義,因爲圖層堆棧可能因設置而異。 ViewportLayer是將虛擬本性引入到NatTable和滾動功能的一種。它避免了對底層的訪問。所以問其中的一個將會返回你期望的值。

  2. 通過執行TurnViewportOffCommand來禁用ViewportLayer。這基本上是一種黑客攻擊,可能會觸發你可能不想要的其他事情。但是我在其他情況下看到了這個建議,因此想在這裏命名。無論如何,我不建議使用它!

請注意,當我們談論黑盒測試時,這兩種方法更像是黑客,因爲您正在對構圖進行假設。由於各種配置能力,它們不能一般應用。

關於爲什麼需要設置Shell可見的隱藏問題。基本上,因爲需要觸發繪畫和調整大小的SWT事件,才能根據Shell狀態正確啓動NatTable的大小計算和打印。在我們的例子中(這也是簡單的SWT),我們稱之爲Shell#open()

並且作爲您的實施的最後一個評論,我不明白你爲什麼分類NatTable。我們的API從未打算這樣做。我想你會這樣做一些靜態的預先配置,例如層堆棧。但我個人不喜歡這種方法。每次有人將我們的課程擴展到重寫某些內部方法時,它會以問題或錯誤報告結束,因爲行爲會發生變化。但我認爲這通常是一個開放式API的問題,可爲開發人員提供定製時最大的靈活性。

+0

謝謝,德克,您的詳細解答。你是對的,我的方法實際上並不是黑箱,我只是想從頂部訪問模型,或多或少......關於你最後的評論:我不是繼承'NatTable';這些細節在凝結我的發佈代碼時剛剛變得模糊。我使用了一個叫'AbstractNatTableViewer'的類,它封裝了一個'NatTable',並提供了在我們的應用程序中多個'NatTables'通用的圖層和配置設置,因此我們像'NatTable's和它們的常見的可重用基本實現代碼... –

0

我也試圖從nattable的不可見單元格讀取數據。我試圖用ShowCellInViewportCommand如下:

widget.doCommand(new ShowCellInViewportCommand(gridlayer.getBodyLayer(), column, row)); 
//where row is say 50 and column is 20 and the cell is invisible. 

我也試過,

widget.doCommand(new ShowRowInViewportCommand(widget.getLayer(), row)); 
//here the default value given by nattable.getLayer is passed 

部件corrosponds到nattable實例。

調用之後,UI中沒有任何反應。單元格不顯示。 我需要做其他事嗎?

我該如何去閱讀nattable的隱形單元。

+0

我也想看到這是一個新的問題。我也無法用給定的信息回答問題。你的圖層堆棧是怎樣的?你有多少行,你試圖讓哪一行可見? 'ShowCellInViewportCommand'由'ViewCaleInViewportCommandHandler'處理,它被註冊到'ViewportLayer'。如果這一切都到位,它應該起作用。如果你試圖使一行不存在(注意索引 - 位置轉換),那什麼都不會發生。 –