【问题标题】:Use one single instance of QApplication in python unit test在 python 单元测试中使用一个 QApplication 实例
【发布时间】:2017-09-03 00:57:28
【问题描述】:
如何创建QApplication 的单个实例?
背景:
我正在单元测试中测试几个实现QWidget 的小部件。为此,我必须创建一个QApplication 的实例。第二次调用QApplication的构造函数导致异常。
它有以下缺点:
- 小部件和
QApplication 在setUpClass(cls) 中创建,标记为@classmethod。对于测试的创建和维护,这很痛苦,因为每个测试都必须处理相同的小部件实例。
- 一旦我必须执行多个测试用例,就会创建多个
QApplication 实例,我又面临 RuntimeError...
我的第一个工作想法是用try except 包围对QApplication() 的每个调用。但我对此并不满意......
我尝试调用app.quit(),设置self.app = None 和gc.collect()。他们都没有工作。
技术事实:
- Python 3.4
- PySide
- 模块
unittest
- 在 PyCharm 和控制台/脚本中执行
【问题讨论】:
标签:
python
pyqt
pyside
python-unittest
【解决方案1】:
对测试脚本中的所有单元测试使用相同的 QApplication 实例。
要使用相同的QApplication 实例,请在单元测试脚本的全局范围内实例化QApplication。
为每个单元测试使用唯一的QWidget。
要使用唯一的QWidget 实例,请在unittest.TestCase.setUp() 中实例化QWidget
这是从控制台运行的完整测试脚本示例。
我的环境和你的差不多,只是我用的是:
- PyQt5 代替 PySide
- Jupyter QtConsole 代替 PyCharm
#! /usr/bin/env python
import sys
import unittest
from PyQt5.QtWidgets import QApplication
"""All tests use the same single global instance of QApplication."""
from PyQt5.QtWidgets import QWidget
"""The tests individually instantiate the top-level window as a QWidget."""
# Create an application global accessible from all tests.
app= QApplication( sys.argv )
# Define setUp() code used in all tests.
class PyQt_TestFixture( unittest.TestCase ):
def create_application_window( self ):
w= QWidget()
return w
def setUp( self ):
self.window= self.create_application_window()
class TestPyQt( PyQt_TestFixture ):
"""Suite of tests. See test fixture for setUp()."""
def test_QWidget_setWindowTitle( self ):
"""Test that PyQt setWindowTitle() sets the title of the window."""
# Operate.
self.window.setWindowTitle( 'Test setWindowTitle' )
# Check.
self.assertEqual( self.window.windowTitle(), 'Test setWindowTitle' )
def test_eachTestUsesUniqueQWidgets( self ):
"""Test that the other test of PyQt setWindowTitle() is not affecting this test."""
# Check.
self.assertNotEqual( self.window.windowTitle(), 'Test setWindowTitle' )
"""The windowTitle() is an empty string '' if setWindowTitle() is not called."""
def test_QWidget_resize( self ):
"""Another example: test that PyQt resize() resizes the window."""
# Operate.
self.window.resize( 123, 456 )
# Check.
from PyQt5.QtCore import QSize
size= QSize( 123, 456 )
self.assertEqual( self.window.size(), size )
if __name__ == '__main__':
unittest.main()