如何从 QTest 单元测试中编辑 QTableView 单元格?

Posted

技术标签:

【中文标题】如何从 QTest 单元测试中编辑 QTableView 单元格?【英文标题】:How can you edit a QTableView cell from a QTest unit test? 【发布时间】:2012-09-26 15:03:11 【问题描述】:

我正在使用QTestLib framework 在 QTableView 中为自定义验证器编写单元测试。最基本的测试用例之一可以这样描述:

双击第三列第四行的表格单元格,将数字“5”附加到其内容中。

仅仅改变模型或任何东西中的值是不够的,测试用例应该像这样执行它:

    双击表格单元格将其设置为编辑模式 按 [结束] 键。 按 [5] 键。

注意:This question 有一个关于如何从代码中将表格单元格设置为编辑模式的答案,但是单元测试应尽量坚持人类用户的可能性,即鼠标/键盘操作。

我发现可以使用QTableView::columnViewportPosition( int ) 和QTableView::rowViewportPosition( int ) 检索单元格的 X/Y 位置。 但是,使用QTest::mouseDClick(...) 双击指定位置既不会选择单元格,也不会将其设置为编辑模式:

// Retrieve X/Y coordinates of the cell in the third column and the fourth row
int xPos = m_pTableView->columnViewportPosition( 2 );
int yPos = m_pTableView->rowViewportPosition( 3 );

// This does not work
QTest::mouseDClick( m_pTableView, Qt::LeftButton, QPoint( xPos, yPos ) );

我怎样才能实现我上面描述的测试用例,只使用鼠标/键盘操作?

PS:我正在 Windows XP 32 位和 Qt 4.6.1 下尝试此操作

【问题讨论】:

【参考方案1】:

尝试通过模拟事件在 QTableView 中进行编辑时需要考虑几件事:

QTableView 不直接显示它的单元格,它使用它的viewport() 来显示。同样,双击事件必须发送到视口而不是表视图本身。

当你这样做时

QTest::mouseDClick( m_pTableView->viewport(), Qt::LeftButton, 
                    NULL, QPoint( xPos, yPos ) );

单元格将被选中,但不会处于编辑模式(与人为启动的双击不同,即使表格视图之前没有焦点,也会立即将单元格置于编辑模式)。但是,如果您在双击之前在同一位置单击一次,它会起作用!

如果您随后将 [End] 按键发送到视口,则光标不会跳转到表格单元格内容的末尾,而是会选择当前行中的最后一个单元格。 为了更改表格单元格内容,您必须改为将事件发送到当前编辑器小部件。最简单的方法是使用QWidget::focusWidget()

QTest::keyClick( m_pTableView->viewport()->focusWidget(), Qt::Key_End );

请注意,尽管 focusWidget() 可以返回 NULL,但这样使用它可能是不安全的。


有了这些知识,测试用例可以编写如下:

// Note: The table view must be visible at this point

// Retrieve X/Y coordinates of the cell in the third column and the fourth row
int xPos = m_pTableView->columnViewportPosition( 2 ) + 5;
int yPos = m_pTableView->rowViewportPosition( 3 ) + 10;

// Retrieve the viewport of the table view
QWidget* pViewport = m_pTableView->viewport();

// Double click the table cell to set it into editor mode
// Note: A simple double click did not work, Click->Double Click works, however
QTest::mouseClick ( pViewport, Qt::LeftButton, NULL, QPoint( xPos, yPos ) );
QTest::mouseDClick( pViewport, Qt::LeftButton, NULL, QPoint( xPos, yPos ) );

// Simulate [End] keypress
QTest::keyClick( pViewport->focusWidget(), Qt::Key_End );

// Simulate [5] keypress
QTest::keyClick( pViewport->focusWidget(), Qt::Key_5 );

(注意:如果要验证这一点,可以在每个事件后添加 QTest::qWait(1000) 命令)


如果您使用here 所述的_data() 函数,请注意在创建数据时无法检索focusWidget()。 我通过创建一个只有纯虚拟“execute()”函数的自定义接口ITestAction 解决了这个问题。然后我添加了具有与QTest::mouseClick(...) etc 函数类似的构造函数的子类。这些类只调用 QTest 函数,但使用小部件本身或其焦点小部件作为参数,这取决于附加的布尔标志。 _data() 槽然后为每个数据行存储一个 QList,实际的测试槽迭代该列表并在执行验证之前对每个项目调用 execute()。

【讨论】:

这正是我需要的答案,非常感谢:) in - int xPos = m_pTableView->columnViewportPosition( 2 ) + 5 的 + 5 和 + 10 是多少; int yPos = m_pTableView->rowViewportPosition( 3 ) + 10; @NiladriBose:这些是像素数。当我们模拟点击时,我们可能希望点击单元格内部的某个位置,而不是其边界,以确保选择了正确的单元格。 除了通过 x-y 坐标选择单元格之外,您还可以使用 edit 插槽。与view->edit(index).

以上是关于如何从 QTest 单元测试中编辑 QTableView 单元格?的主要内容,如果未能解决你的问题,请参考以下文章

QTest 覆盖漆法

Qtest与DevOps首度合作!!!

如何在 PyQt 中测试拖放行为?

QTest大会Qunit新标签-你值得拥有

如何从 iOS 单元测试中获取不同的 info-plist?

如何对依赖于 ActivatedRoute 参数的组件进行单元测试?