使用 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 文件
使用 Qt 的 QProcess 作为 popen(使用 ffmpeg rawvideo)