在 PyTest 上的两个测试之间重置全局变量

poi*_*rez 7 python pytest

我对使用和修改全局变量的函数进行了测试。我想确保我的全局变量在我的测试之间重置。有什么技巧可以做到这一点吗?

主要.py:

y = 0


def inc(x):
    # side effect
    global y
    y = y + 1
    return x + y + 1
Run Code Online (Sandbox Code Playgroud)

测试_main.py:

from main import inc


def test_answer():
    assert inc(3) == 5


def test_answer_again():
    assert inc(3) == 5
Run Code Online (Sandbox Code Playgroud)
_________________________________________________________________________________________ test_answer_again __________________________________________________________________________________________

    def test_answer_again():
>       assert inc(3) == 5
E       assert 6 == 5
E        +  where 6 = inc(3)

test_main.py:8: AssertionError
====================================================================================== short test summary info =======================================================================================
FAILED test_main.py::test_answer_again - assert 6 == 5
==================================================================================== 1 failed, 1 passed in 0.01s =====================================================================================
Run Code Online (Sandbox Code Playgroud)

Pet*_*r K 4

以下是如何使用简单的固定装置来确保每次测试后 y 的值保持不变:

import pytest

import main

from main import inc


@pytest.fixture
def set_y(request):
    y_before = main.y
    y_value_to_set = getattr(request, 'param', y_before)  # optional parameter
    main.y = y_value_to_set
    yield  # allows us to have cleanup after the test
    main.y = y_before  # once test is done, revert value for next test


def test_answer(set_y):
    assert inc(3) == 5


def test_answer_again(set_y):
    assert inc(3) == 5


@pytest.mark.parametrize('set_y', [20], indirect=["set_y"])
def test_answer_with_specific_y(set_y):
    assert inc(3) == 25
Run Code Online (Sandbox Code Playgroud)

autouse=True如果您想避免在每次测试中特别提及该固定装置并防止由于缺少指定它而导致的错误,您还可以将 添加到您的固定装置中:

import pytest

import main

from main import inc


@pytest.fixture(autouse=True)
def set_y(request):
    y_before = main.y
    y_value_to_set = getattr(request, 'param', y_before)  # optional parameter
    main.y = y_value_to_set
    yield  # allows us to have cleanup after the test
    main.y = y_before  # once test is done, revert value for next test


def test_answer():
    assert inc(3) == 5


def test_answer_again():
    assert inc(3) == 5


@pytest.mark.parametrize('set_y', [20], indirect=["set_y"])
def test_answer_with_specific_y():
    assert inc(3) == 25
Run Code Online (Sandbox Code Playgroud)