68

我正在编写带有一组类的硒测试,每个类都包含几个测试。每个类当前打开然后关闭 Firefox,这有两个后果:

  • 超级慢,打开firefox比在课堂上运行测试要长...
  • 崩溃,因为在关闭 firefox 后,尝试从 selenium 快速重新打开它会导致“错误 54”

我可以通过添加睡眠来解决错误 54,但它仍然会非常慢。

所以,我想做的是在所有测试类中重用相同的 Firefox 实例。这意味着我需要在所有测试类之前运行一个方法,并在所有测试类之后运行另一个方法。所以,'setup_class' 和 'teardown_class' 是不够的。

4

4 回答 4

95

在许多情况下,使用hpk42建议的会话夹具是很好的解决方案,但夹具只有在收集完所有测试后才会运行。

这里还有两个解决方案:

conftest 钩子

在你的文件中写一个pytest_configurepytest_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 插件

使用和钩子创建一个pytest 插件。 启用您的插件:pytest_configurepytest_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
于 2016-02-14T16:39:52.900 回答
83

您可能想要使用会话范围的“自动使用”固定装置:

# 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)

这将在所有测试之前运行。终结器将在最后一次测试完成后被调用。

于 2013-07-24T21:14:51.307 回答
27

从 2.10 版本开始,有一种更简洁的方式来拆除夹具并定义其范围。所以你可以使用这个语法:

@pytest.fixture(scope="module", autouse=True)
def my_fixture():
    print ('INITIALIZATION')
    yield param
    print ('TEAR DOWN')

autouse 参数: 来自文档

以下是 autouse 固定装置在其他范围内的工作方式:

  • autouse 固定装置遵守 scope= 关键字参数:如果 autouse 固定装置的 scope='session' ,它只会运行一次,无论它在哪里定义。scope='class' 意味着它将在每个类中运行一次,等等。

  • 如果在测试模块中定义了 autouse 夹具,它的所有测试函数都会自动使用它。

  • 如果在 conftest.py 文件中定义了 autouse 夹具,则其目录下所有测试模块中的所有测试都将调用该夹具。

    ...

“请求”参数: 请注意,“请求”参数对于您的目的不是必需的,尽管您可能希望将其用于其他目的。从文档

“夹具函数可以接受请求对象来内省“请求”测试函数、类或模块上下文..”

于 2016-10-20T13:17:16.070 回答
8

尝试pytest_sessionstart(session)使用conftest.py

例子:

# project/tests/conftest.py

def pytest_sessionstart(session):
    print('BEFORE')
# project/tests/tests_example/test_sessionstart.py

import pytest


@pytest.fixture(scope='module', autouse=True)
def fixture():
    print('FIXTURE')


def test_sessonstart():
    print('TEST')

日志:

BEFORE
============================================================================ test session starts =============================================================================
platform darwin -- Python 3.7.0, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- /Library/Frameworks/Python.framework/Versions/3.7/bin/python3
cachedir: .pytest_cache
rootdir: /Users/user/Documents/test, inifile: pytest.ini
plugins: allure-pytest-2.8.12, env-0.6.2
collected 1 item                                                                                                                                                             

tests/6.1/test_sessionstart.py::test_sessonstart FIXTURE
TEST
PASSED

在此处阅读更多信息:https ://docs.pytest.org/en/latest/reference.html#_pytest.hookspec.pytest_sessionstart

于 2020-06-10T15:33:41.913 回答