Python 如何在所有类中的所有测试之前运行方法?

Python 如何在所有类中的所有测试之前运行方法?,python,selenium,pytest,Python,Selenium,Pytest,我正在编写selenium测试,包含一组类,每个类包含几个测试。每个类当前打开然后关闭Firefox,这有两个后果: 超慢,打开firefox比在类中运行测试花费的时间更长 崩溃,因为在firefox关闭后,尝试从selenium快速重新打开它会导致“错误54” 我可能可以通过添加睡眠来解决错误54,但仍然会非常慢 所以,我想做的是在所有测试类中重用相同的Firefox实例。这意味着我需要在所有测试类之前运行一个方法,在所有测试类之后运行另一个方法。因此,“设置类”和“拆卸类”是不够的。您可

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

  • 超慢,打开firefox比在类中运行测试花费的时间更长
  • 崩溃,因为在firefox关闭后,尝试从selenium快速重新打开它会导致“错误54”
我可能可以通过添加睡眠来解决错误54,但仍然会非常慢


所以,我想做的是在所有测试类中重用相同的Firefox实例。这意味着我需要在所有测试类之前运行一个方法,在所有测试类之后运行另一个方法。因此,“设置类”和“拆卸类”是不够的。

您可能需要使用会话范围内的“自动使用”装置:


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

对于许多情况,使用session fixture(如所建议)是一个很好的解决方案, 但该装置将仅在收集所有测试后运行

这里还有两个解决方案:

抗弯钩 在
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\u configure
pytest\u 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

从2.10版开始,有一种更简洁的方法可以拆卸夹具并定义其范围。因此,您可以使用以下语法:

@pytest.fixture(scope="module", autouse=True)
def my_fixture():
    print ('INITIALIZATION')
    yield param
    print ('TEAR DOWN')
自动使用参数: 发件人:

以下是自动使用装置在其他范围内的工作方式:

  • autouse装置遵循scope=关键字参数:如果autouse装置具有scope='session',则无论在何处,它都只运行一次 它是被定义的。scope='class'表示每个类将运行一次,等等

  • 如果在测试模块中定义了自动使用夹具,则其所有测试功能将自动使用该夹具

  • 如果在conftest.py文件中定义了自动使用装置,则其目录下所有测试模块中的所有测试都将调用该装置

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

“Fixture函数可以接受请求对象来内省 正在请求“测试函数、类或模块上下文…”


conftest.py

例如:

# project/tests/conftest.py

def pytest_sessionstart(session):
    print('BEFORE')
日志:


阅读此处的更多信息:

将模块设置为
还不够?我需要一个函数在末尾运行一次以关闭webbrowser。我不想在每次课程/模块结束后关闭webbrowser。我也不希望它永远不会被关闭。这样就很容易了:使用并注册将关闭firefox的函数,以便在解释器退出之前执行。谢谢。如果可能的话,我更喜欢“py.test”的方式。你可以这样做,我使用的是会话级拆卸和设置,但不确定它们是否仍然可用。这是最好的答案。将
conftest.py
放在与您希望使用相同的
pytest_sessionstart
pytest_sessionfinish
例程运行的其他测试相同的目录中。我认为如果测试分布在多个文件中,则此操作不起作用。如果我想在其中包含一个函数范围的固定装置,则此操作将不起作用功能
# 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