我想对NatTable内容进行普通的UI测试(即,不使用SWTBot或其他UI测试框架)。
我的方法是创建一个外壳,添加我的自定义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
-因此,我添加了代码以打包并设置外壳可见。这适用于小型表(具有2行和几列)。可悲的是,它不适用于大表。我怀疑这是因为视口层不会创建不在可见区域中的单元格(我知道,这是NatTable的优势-它仅根据需要创建所需的结构)。当然,这对于正常的运行时行为是必需的。
但是有没有一种(另一种)方式可以保证方式获得单元格(换句话说,我可以让NatTable / ViewportLayer相信该单元格是可见的,所以只要该单元格在内容方面存在,我就不会获得
null
?)当然,我可以直接测试我的标签累加器,数据提供者等,但是我想在这里从黑匣子的角度进行更多的研究。
最佳答案
这个问题本身是矛盾的。您正在要求一种用于测试NatTable的黑盒方法,但是您想更改NatTable在测试中的行为。那不是黑匣子的方法!
如果您真的想使用黑盒方法进行测试,则需要确保已渲染该单元格。这可以通过触发滚动来完成,例如通过执行ShowCellInViewportCommand
。那是真正的黑匣子方法,因为为不可见的单元格返回null是正确的结果。
如果您需要介于真正的黑匣子方法和利用内部知识(您要的知识)之间的某种东西,那么您必须设法达到目标。
ViewportLayer
下方的层上操作。通常,可以使用SelectionLayer
。但这当然不需要什么意思,因为层堆栈在设置之间可能有所不同。 ViewportLayer
是一种将虚拟性质引入NatTable并具有滚动功能的代码。它避免了对底层的访问。因此,询问其中之一将返回您期望的值。 TurnViewportOffCommand
禁用ViewportLayer。从根本上讲,这是一种黑客行为,并且可能在您的背后触发其他您可能不想要的事情。但是我已经在其他情况下看到了该建议,因此想在这里命名。我不建议使用它! 请注意,当我们谈论黑匣子测试时,这两种方法都更像骇客,因为您是在对组成进行假设。由于各种配置功能,它们通常不能应用。
关于为什么需要将Shell设置为可见的隐藏问题。好吧,基本上是因为需要触发绘画和调整大小的SWT事件,以便根据Shell状态正确启动NatTable的大小计算和打印。在我们的示例(也是普通的SWT)中,我们称为
Shell#open()
。最后,关于您的实现,我不明白为什么您要对
NatTable
进行子类化。我们的API从未打算这样做。我想你这样做是为了进行一些静态的预配置,例如层堆栈。但是我个人不喜欢这种方法。每当有人扩展我们的类以覆盖某些内部方法时,由于行为改变,它最终会出现问题或错误报告。但是我认为这通常是开放API的问题,它可以为开发人员提供最大程度的自定义灵活性。