【问题标题】:JUnit-testing of NatTableNatTable 的 JUnit 测试
【发布时间】:2016-08-21 15:44:49
【问题描述】:

我想对 NatTable 内容进行简单的 UI 测试(即不使用 SWTBot 或其他 UI 测试框架)。

我的方法是创建一个 shell,添加我的自定义 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)
}

要测试我的其他组件,只需创建外壳和父组合就足够了;我的测试不需要打包和设置可见。 然而,对于 NatTable,如果单元格不可见,getCellByPosition() 将返回 null - 所以我添加了代码来打包并将 shell 设置为可见。这适用于小表(有 2 行和几列)。

遗憾的是,它不适用于大桌子。我怀疑这是因为视口层不会创建不在可见区域中的单元格(我知道,这就是 NatTable 的优势——它只根据需要创建所需的结构)。这当然是正常运行时行为所需要的。

但是有没有(其他)方法可以保证获取单元格(换句话说,我可以让 NatTable/ViewportLayer 相信该单元格是可见的,所以我不会得到null,只要单元格是否存在内容?)

当然,我可以直接测试我的标签累加器、数据提供者等,但我想在这里更多地从黑盒的角度来解决这个问题。

【问题讨论】:

  • 我没有你的问题的答案,但通常的建议是保持最顶层的 View/UI 层尽可能薄和愚蠢,并测试其他所有内容。在您的情况下,这确实意味着测试您的各个 NatTable 组件(累加器、提供程序、事件处理程序),并相信 NatTable 能够正确显示它。

标签: java junit swt eclipse-rcp nattable


【解决方案1】:

这个问题本身就是矛盾的。您要求使用黑盒方法来测试 NatTable,但您想更改 NatTable 在测试中的行为。这不是黑盒方法!

如果你真的想用黑盒方法进行测试,你需要确保单元格被渲染。这可以通过触发滚动来完成,例如通过执行ShowCellInViewportCommand。这是真正的黑盒方法,因为为不可见的单元格返回 null 是正确的结果。

如果您需要介于真正的黑匣子方法和利用内部知识(您所要求的)的方法之间的东西,您必须找到实现目标的方法。

  1. ViewportLayer 下方的层上操作。通常可以使用SelectionLayer。但当然这并不意味着什么,因为层堆栈可能因设置而异。 ViewportLayer 是将虚拟特性引入 NatTable 和滚动功能的一种。它避免了对底层的访问。因此,询问其中之一将返回您期望的值。

  2. 通过执行 TurnViewportOffCommand 禁用 ViewportLayer。这基本上是一种黑客攻击,可能会在后面触发您可能不想要的其他事情。但我在其他情况下看到过这个建议,因此想在这里命名。反正我也不建议用!

请注意,当我们谈论黑盒测试时,这两种方法都更像是黑客攻击,因为您是在对组合进行假设。由于各种配置能力,它们不能被普遍应用。

关于为什么需要将 Shell 设置为可见的隐藏问题。好吧,基本上是因为需要触发用于绘制和调整大小的 SWT 事件,以便根据 Shell 状态正确启动 NatTable 的大小计算和打印。在我们的示例(也是普通的 SWT)中,我们调用 Shell#open()

作为对您的实现的最后评论,我不明白您为什么要对NatTable 进行子类化。我们的 API 从未打算这样做。我想你这样做是为了做一些静态的预配置,例如层堆栈。但就个人而言,我不喜欢这种方法。每次有人扩展我们的类以覆盖一些内部方法时,它都会因为行为发生变化而出现问题或错误报告。但我认为这通常是一个开放 API 的问题,以便为开发人员提供最大可能的定制灵活性。

【讨论】:

  • 感谢 Dirk,您的详细回答。你是对的,我的方法实际上不是黑盒,我只是想从顶部访问模型,或多或少......关于你的最后一句话:我没有继承NatTable;在压缩我的发布代码时,这个细节刚刚被模糊了。我使用了一个我称之为AbstractNatTableViewer 的类,它包装了一个NatTable,并提供了层和配置设置,这对于我们的应用程序中的多个NatTables 来说是常见的,所以我们有一个NatTables 的可重用基础实现和它们的共同点代码...
【解决方案2】:

我也在尝试从 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

widget 对应 nattable 实例。

调用后,UI 中没有任何反应。单元格不显示。 我还需要做什么吗?

我应该如何去阅读 nattable 的隐形单元格。

【讨论】:

  • 我也想将此视为一个新问题。我也无法用给定的信息回答问题。您的层堆栈看起来如何?你有多少行,你试图让哪一行可见? ShowCellInViewportCommand 由注册到ViewportLayerShowCellInViewportCommandHandler 处理。如果一切就绪,它应该可以工作。如果您尝试使不存在的行可见(注意索引位置转换),则不会发生任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2023-04-08
  • 2010-11-10
  • 2010-10-15
  • 2017-05-05
  • 1970-01-01
相关资源
最近更新 更多