2016-04-27 80 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'。如果这一切都到位,它应该起作用。如果你试图使一行不存在(注意索引 - 位置转换),那什么都不会发生。 –