Pytest“run-around-tests”装置在一个类中的所有测试之前只运行一次

Nor*_*din 5 python selenium automated-tests pytest

我正在使用 pytest + selenium 测试 Web 解决方案的用户消息功能。测试将向测试用户生成测试消息,然后登录该用户以验证该消息确实为该用户显示。

  • 我需要通过内部 API 生成这些消息。
  • 为了能够访问这个 API,我首先必须通过不同的 API 生成一个 AUTH 令牌。

所以测试场景基本上是:

  1. 在测试启动时,通过 API 辅助函数生成新的 AUTH 令牌。
  2. 向另一个 API 发送请求以设置新消息(需要 AUTH 令牌)
  3. 向另一个 API 发送请求以将此消息“映射”到指定用户(需要 AUTH 令牌)
  4. 登录测试用户并验证新消息是否确实显示。

我的问题是我想避免每次运行我的测试类中的每个测试时都创建一个新的 AUTH 令牌 - 一旦所有测试在同一个测试运行中使用,我想创建一个新令牌。

在调用所有测试时生成一个新访问令牌的最聪明的解决方案是什么?

现在我想出了这样的东西,每次运行任何单独的测试时都会生成一个新的令牌:

import pytest
import helpers.api_access_token_helper as token_helper
import helpers.user_message_generator_api_helper as message_helper
import helpers.login_helper as login_helper
import helpers.popup_helper as popup_helper

class TestStuff(object):

    @pytest.yield_fixture(autouse=True)
    def run_around_tests(self):
        yield token_helper.get_api_access_token()

    def test_one(self, run_around_tests):
        auth_token = run_around_tests
        message_helper.create_new_message(auth_token, some_message_data)
        message_helper.map_message_to_user(auth_token, user_one["user_id"])
        login_helper.log_in_user(user_one["user_name"], user_one["user_password"])
        assert popup_helper.user_message_is_displaying(some_message_data["title"])

    def test_two(self, run_around_tests):
        auth_token = run_around_tests
        message_helper.create_new_message(auth_token, some_other_message_data)
        message_helper.map_message_to_user(auth_token, user_two["user_id"])
        login_helper.log_in_user(user_two["user_name"], user_two["user_password"])
        assert popup_helper.user_message_is_displaying(some_other_message_data["title"])
Run Code Online (Sandbox Code Playgroud)

我已经用“运行测试”夹具来回努力了一点,但还没有找到解决方案。

hoe*_*ing 12

您必须调整固定范围以缓存测试运行中的所有测试 ( scope='session')、模块中的所有测试 ( scope='module')、类中的所有测试(unittest仅旧式测试,scope='class')或单个测试(scope='function';这是默认值)的结果一)。例子:

夹具功能

@pytest.fixture(scope='session')
def token():
    return token_helper.get_api_access_token()


class Tests(object):

    def test_one(self, token):
        ...

    def test_two(self, token):
        ...


class OtherTests(object):

    def test_one(self, token):
        ...
Run Code Online (Sandbox Code Playgroud)

令牌将在第一次请求时计算一次,并在整个测试运行期间保存在缓存中,因此所有三个测试Tests::test_one,Tests::test_twoOtherTests::test_one将共享相同的令牌值。

夹具类方法

如果您打算编写旧式测试类而不是测试函数,并且希望固定装置成为类方法(就像在代码中一样),请注意,您只能使用作用域class,以便固定装置值仅在之间共享课堂上的测试:

class TestStuff(object):

    @pytest.fixture(scope='class')
    def token(self):
        return token_helper.get_api_access_token()

    def test_one(self, token):
        ...

    def test_two(self, token):
        ...
Run Code Online (Sandbox Code Playgroud)

抛开事情:

  1. pytest.yield_fixture已弃用并替换为pytest.fixture;
  2. 您不需要设置,autouse=True因为您在测试参数中明确请求了夹具。无论如何它都会被调用。