Python 如何在所有类的所有测试之前运行一个方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17801300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run a method before all tests in all classes?
提问by Hugh Perkins
I'm writing selenium tests, with a set of classes, each class containing several tests. Each class currently opens and then closes Firefox, which has two consequences:
我正在编写 selenium 测试,有一组类,每个类包含几个测试。每个类当前打开然后关闭 Firefox,这有两个后果:
- super slow, opening firefox takes longer than running the test in a class...
- crashes, because after firefox has been closed, trying to reopen it really quickly, from selenium, results in an 'Error 54'
- 超级慢,打开 Firefox 比在课堂上运行测试需要更长的时间......
- 崩溃,因为在关闭 Firefox 后,尝试从 selenium 中快速重新打开它,导致“错误 54”
I could solve the error 54, probably, by adding a sleep, but it would still be super slow.
我可以通过添加睡眠来解决错误 54,但它仍然会非常慢。
So, what I'd like to do is reuse the same Firefox instances across alltest classes. Which means I need to run a method before all test classes, and another method after all test classes. So, 'setup_class' and 'teardown_class' are not sufficient.
所以,我想做的是在所有测试类中重用相同的 Firefox 实例。这意味着我需要在所有测试类之前运行一个方法,在所有测试类之后运行另一个方法。所以,'setup_class' 和 'teardown_class' 是不够的。
采纳答案by hpk42
You might want to use a session-scoped "autouse" fixture:
您可能想要使用会话范围的“自动使用”装置:
# content of conftest.py or a tests file (e.g. in your tests or root directory)
@pytest.fixture(scope="session", autouse=True)
def do_something(request):
# prepare something ahead of all tests
request.addfinalizer(finalizer_function)
This will run ahead of all tests. The finalizer will be called after the last test finished.
这将在所有测试之前运行。最后一个测试完成后将调用终结器。
回答by draganHR
Using session fixture as suggested by hpk42is great solution for many cases, but fixture will run only after all tests are collected.
对于许多情况,使用hpk42建议的会话夹具是很好的解决方案,但夹具只有在收集了所有测试后才会运行。
Here are two more solutions:
这里还有两个解决方案:
conftest hooks
比赛挂钩
Write a pytest_configure
or pytest_sessionstart
hook in your conftest.py
file:
在你的文件中写一个pytest_configure
或pytest_sessionstart
钩子conftest.py
:
# content of conftest.py
def pytest_configure(config):
"""
Allows plugins and conftest files to perform initial configuration.
This hook is called for every plugin and initial conftest
file after command line options have been parsed.
"""
def pytest_sessionstart(session):
"""
Called after the Session object has been created and
before performing collection and entering the run test loop.
"""
def pytest_sessionfinish(session, exitstatus):
"""
Called after whole test run finished, right before
returning the exit status to the system.
"""
def pytest_unconfigure(config):
"""
called before test process is exited.
"""
pytest plugin
pytest 插件
Create a pytest pluginwith pytest_configure
and pytest_unconfigure
hooks.
Enable your plugin in conftest.py
:
使用和钩子创建一个pytest 插件。
启用您的插件:pytest_configure
pytest_unconfigure
conftest.py
# content of conftest.py
pytest_plugins = [
'plugins.example_plugin',
]
# content of plugins/example_plugin.py
def pytest_configure(config):
pass
def pytest_unconfigure(config):
pass
回答by Pavel Rogovoy
Starting from version 2.10 there is a cleaner way to tear down the fixture as well as defining its scope. So you may use this syntax:
从版本 2.10 开始,有一种更简洁的方式来拆除夹具并定义其范围。所以你可以使用这个语法:
@pytest.fixture(scope="module", autouse=True)
def my_fixture():
print ('INITIALIZATION')
yield param
print ('TEAR DOWN')
The autouse parameter:From documentation:
autouse 参数:来自文档:
Here is how autouse fixtures work in other scopes:
autouse fixtures obey the scope= keyword-argument: if an autouse fixture has scope='session' it will only be run once, no matter where it is defined. scope='class' means it will be run once per class, etc.
if an autouse fixture is defined in a test module, all its test functions automatically use it.
if an autouse fixture is defined in a conftest.py file then all tests in all test modules below its directory will invoke the fixture.
...
以下是 autouse 夹具在其他范围内的工作方式:
autouse fixtures 遵守 scope= 关键字参数:如果 autouse fixture 有 scope='session' 它只会运行一次,无论它在哪里定义。scope='class' 表示每个类都会运行一次,等等。
如果在测试模块中定义了自动使用装置,则其所有测试功能都会自动使用它。
如果在 conftest.py 文件中定义了 autouse 夹具,则其目录下所有测试模块中的所有测试都将调用该夹具。
...
The "request" parameter:Note that the "request" parameter is not necessary for your purpose although you might want to use it for other purposes. From documentation:
“请求”参数:请注意,“请求”参数对于您的目的不是必需的,尽管您可能希望将其用于其他目的。从文档:
"Fixture function can accept the request object to introspect the “requesting” test function, class or module context.."
“Fixture 函数可以接受请求对象来内省‘请求’测试函数、类或模块上下文..”