在我正在工作的项目中,我们有一个很好的自制自动化 UI 测试框架。主要应用程序是用 Qt/QML 编写的。自动化测试在另一个进程中运行,通过 gRPC/socket 基础层连接到应用程序,并提供单击 Qt 元素并读取/写入其属性的可能性。
该方法非常出色,适用于 99% 的场景,例如“与 UI 元素交互,并检查其他 UI 元素是否更改了其值/状态/内容/等”。不幸的是,有时会出现问题。
因此,想象一个具有按钮和列表的应用程序。单击该按钮将一个元素添加到列表中。有一个测试可以检查以下场景:
在某些机器上,此测试顺利通过。但有些机器比其他机器更强大,测试会在获取新值之前读取“count”属性。
有一个明显的解决方案 - 在按下按钮和读取属性之间添加 sleep() 调用。这对于单个测试来说效果很好,但在数百个测试的情况下,这确实会减慢测试执行速度(请注意,应用程序有超过 1 个按钮和 1 个列表 - 它有大量其他控件,并且在所有这些地方添加睡眠可能会显着增加测试执行时间。即使在关键点添加 0.5 秒的睡眠也会使测试执行速度减慢 3 倍)。
那么问题是:有没有办法确定 Qt 是否完成了与更改相关的所有属性的更新?也许有一个“空闲”标志,表明事件队列中所有正在进行的消息都已处理?
在主应用程序中使用计数器来维护已完成的信号计数。
当您开始从测试应用程序触发操作时重置计数器。
在您的主应用程序中,将对象完成信号连接到递增计数器的插槽。
从您的测试应用程序检查计数器值,如果它与所采取的操作数量匹配,您可以继续从主应用程序读取并验证这些值。