使用 QProcess 测试 PySide 应用程序

Posted

技术标签:

【中文标题】使用 QProcess 测试 PySide 应用程序【英文标题】:Testing PySide Application using QProcess 【发布时间】:2014-07-01 18:28:54 【问题描述】:

我有一个 PySide 应用程序,它在 QProcess 中生成一个工作应用程序。工作人员执行模拟并创建结果文件以供主应用程序读取。我想产生工人,给它工作的时间,然后检查输出。在我的测试函数中(我正在使用 py.test,如果有帮助的话),我找不到在不阻塞主线程的情况下等待工作进程的方法,因此不允许工作进程启动和运行。

def test_worker_thread():
    application = Application()  # Waits for and loads result files
    application.worker.start()  # Runs in a new process

    # How to wait right here without blocking thread?

    <wait_code>

    assert_correct_data(application.worker.results)

对于名为“wait_code”的部分,我已经尝试过:

使用一个名为done 的属性创建一个本地对象。我将worker.finished 信号连接到将done 设置为True。然后我使用了time.sleep 循环来阻止等待工作人员完成。

class WaitObject:

    def __init__(self):
        self.condition = False

    def set_true(self):
        self.condition = True

wait = WaitObject()
application.worker.finished(wait.set_true)

while not wait.condition:
    time.sleep(1)

我在谷歌上搜索了测试异步 Qt 代码的方法,发现了 QTest.qWait,我可以用它代替 time.sleep(),而不会阻塞事件循环。但是,qWait 不包含在 PySide 中。

我也尝试过创建一个新的事件循环,例如this thread。但是,这似乎阻塞了application 的事件循环,因此我们无法在worker 运行时完成worker.start 函数并加载数据。

loop = QtCore.QEventLoop()
application.worker.finished(loop.quit)
loop.exec_()

有什么建议吗?

【问题讨论】:

【参考方案1】:

事实证明,选项 3 确实有效。由于不相关的错误,我的工人没有开始。这是一些完整的框架代码:

def test_worker_thread():
    application = Application()  # Waits for and loads result files
    application.worker.start()  # Runs in a new process

    loop = QtGui.QEventLoop()
    application.worker.finished(loop.quit)  # Resume when worker done
    loop.exec_()  # Blocks at this line until loop quits

    assert_correct_data(application.worker.results)

我将研究这种模式的抽象。我将使用连接到loop.quit 的单次触发QTimer 添加超时,以防永远不会调用worker.finished

编辑:这是blog post 更详细地解释。

【讨论】:

基本上你使用了一个信号。这样你就不再等待线程,而是线程告诉它何时完成。而这确实是一个很好的解决方案。

以上是关于使用 QProcess 测试 PySide 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PySide 中获取 QProcess 运行的命令的输出?

无法使用 pyside Qprocess 启动 exe 文件

单元和功能测试基于 PySide 的应用程序?

使用 Qt 的 QProcess 作为 popen(使用 ffmpeg rawvideo)

使用 PyInstaller 打包后 PySide2 应用程序中的路径错误

PySide:让 SVG 图像跟随鼠标而无需拖放?