In pytest, you can declare fixtures not only in conftest.py, but also in any Python module you wish, and then simply import that module wherever needed. Additionally, you can use fixtures similarly to how you use the setUp method in unittest.
Here’s an example:
@pytest.fixture(scope='class')
def input(request):
request.cls.varA = 1
request.cls.varB = 2
request.cls.varC = 3
request.cls.modified_varA = 2
@pytest.usefixtures('input')
class TestClass:
def test_1(self):
do_something_with(self.varA, self.varB)
def test_2(self):
do_something_with(self.modified_varA, self.varC)
Alternatively, you can define separate fixtures for each variable:
@pytest.fixture()
def fixture_a():
return 1 # varA
@pytest.fixture()
def fixture_b():
return 2 # varB
@pytest.fixture()
def fixture_c():
return 3 # varC
@pytest.fixture()
def fixture_mod_A():
return 2 # modified_varA
Or, you can create one fixture that returns all the variables together:
@pytest.fixture()
def all_variables():
return {'varA': 1, 'varB': 2, 'varC': 3, 'modified_varA': 2}
If you have many configurations, you can even use an indirect parametrized fixture to return variables by your choice, though this can be a bit more complex:
@pytest.fixture()
def parametrized_input(request):
vars = {'varA': 1, 'varB': 2, 'varC': 3}
var_names = request.param
return (vars[var_name] for var_name in var_names)
@pytest.mark.parametrize('parametrized_input', [('varA', 'varC')], indirect=True)
def test_1(parametrized_input):
varA, varC = parametrized_input
# your test logic here
Alternatively, you could create a fixture factory that generates fixtures dynamically. While this is an overkill for a small number of tests, it can be useful if you have many test cases with different variable configurations.
If you want to manage shared variables across multiple test files, you can create a separate variables.py file and import them in the test files that need them.
However, I recommend not directly importing this file into your test files but instead using a command-line option to specify which file to import. This approach allows you to choose different variable files without modifying your code, keeping your test configuration flexible.
Regarding the organization of tests, it’s important to note that pytest doesn’t discourage using classes for organizing tests.
You can still use classes in pytest, especially if you’re migrating from other frameworks like unittest or nose. I use classes in my tests because I migrated from nosetest, and I haven’t encountered any issues with using classes in pytest.
In situations where you need to use the result of one function in another, you can follow this approach:
def some_actions(a, b):
# perform actions here
result = a + b # just an example action
return result
def test():
result = some_actions(1, 2)
assert result == 3
@pytest.fixture()
def some_fixture():
return some_actions(1, 2)
In this solution, the logic of the function is reusable as both a fixture and in individual tests. This avoids directly relying on another test, which is generally not a good practice.