如何使用 Qt Test 控制 QFileDialog?
How to control a QFileDialog using Qt Test?
我有两个问题:
如何使用 Qt 测试模块访问 QFileDialog
并在 "File name" 字段中写入文件路径?
我问这个是因为我正在 Qt 中开发一些 GUI 测试,现在我需要打开一个文本文件。以下代码创建 QFileDialog
并获取文件路径:
QString filePath = QFileDialog::getOpenFileName(
this,
"Open",
"",
tr("Text Files (*.txt)") );
如果我使用线程 (QThread
) 加载此文本文件中的内容,我如何等待此线程完成我的 GUI 测试?
我知道我可以使用 QTest::qSleep( milliseconds );
命令,但我认为在这种情况下这不是一个好的做法。
如果可能的话,请给我举个例子。
遗憾的是,无法使用 Qt 测试模块。您有多种选择:
添加绕过该对话框的测试挂钩:您需要检测您的代码以使其可测试。你可以例如在请求文件的对象上设置 testFile
属性 到文件路径,如果设置 属性 对象可以跳过请求文件。
const char k_testFile[] = "k_testFile";
MyClass::foo() {
...
auto testFile = property(k_testFile);
auto filePath = testFile.isNull()
? QFileDialog::getOpenFilePath(...)
: testFile.toString();
...
}
使用非本机对话框,然后它是一个普通的小部件,您可以使用 Qt 测试进行测试。
使用特定于平台的方式查找本机对话框并与之交互。您需要为您打算测试的每个平台实施它。
您应该在文件加载后发出信号。测试可以等待该信号。您甚至不需要使用显式线程来加载文件,异步加载文件的惯用方式是:
QString filePath = ...;
QtConcurrent::run(ioPool, [this, filePath]{
auto data = MyLoader::load(filePath);
emit haveFileData(data);
});
您调用此代码的 class 应该有一个 haveFileData
信号,表示一些其他代码连接到并按需要进行。 ioPool
是用于 I/O 绑定操作的线程池,如果您希望全局池成为 I/O 池,它可以是 QThredPool::globalInstance()
。 CPU- 和 I/O- 绑定的线程池应该是分开的。
我有两个问题:
如何使用 Qt 测试模块访问
QFileDialog
并在 "File name" 字段中写入文件路径?我问这个是因为我正在 Qt 中开发一些 GUI 测试,现在我需要打开一个文本文件。以下代码创建
QFileDialog
并获取文件路径:QString filePath = QFileDialog::getOpenFileName( this, "Open", "", tr("Text Files (*.txt)") );
如果我使用线程 (
QThread
) 加载此文本文件中的内容,我如何等待此线程完成我的 GUI 测试?我知道我可以使用
QTest::qSleep( milliseconds );
命令,但我认为在这种情况下这不是一个好的做法。
如果可能的话,请给我举个例子。
遗憾的是,无法使用 Qt 测试模块。您有多种选择:
添加绕过该对话框的测试挂钩:您需要检测您的代码以使其可测试。你可以例如在请求文件的对象上设置
testFile
属性 到文件路径,如果设置 属性 对象可以跳过请求文件。const char k_testFile[] = "k_testFile"; MyClass::foo() { ... auto testFile = property(k_testFile); auto filePath = testFile.isNull() ? QFileDialog::getOpenFilePath(...) : testFile.toString(); ... }
使用非本机对话框,然后它是一个普通的小部件,您可以使用 Qt 测试进行测试。
使用特定于平台的方式查找本机对话框并与之交互。您需要为您打算测试的每个平台实施它。
您应该在文件加载后发出信号。测试可以等待该信号。您甚至不需要使用显式线程来加载文件,异步加载文件的惯用方式是:
QString filePath = ...; QtConcurrent::run(ioPool, [this, filePath]{ auto data = MyLoader::load(filePath); emit haveFileData(data); });
您调用此代码的 class 应该有一个
haveFileData
信号,表示一些其他代码连接到并按需要进行。ioPool
是用于 I/O 绑定操作的线程池,如果您希望全局池成为 I/O 池,它可以是QThredPool::globalInstance()
。 CPU- 和 I/O- 绑定的线程池应该是分开的。