Reputation: 733
I am currently working on some unit test cases and test fixtures using py.test
I have some code that does this:
# my py.test file
import pytest
@pytest.fixture
def fixture_1():
f = open("file_one.txt", 'rb')
f_str = f.read()
yield f_str
f.close()
def test_function_1(fixture_1):
assert fixture_1.startswith("some_test_data") # example test
This is all good and works fine.
Now let's say I write another test function that works with input stored in another file (let's say file_two.txt
and my function is like this:
# in same py file as above
def test_function_2(fixture_1):
#some test with data from file_two.txt
assert something_for_fun
In the test_function_2
above, i want to fixture_1
to do the same operations as before but on file_two.txt
instead of file_one.txt
.
EDIT : I also played with parametrizing fixtures but that invokes my test_function_* as many times as the number of arguments to the fixture, which doesn't work since the test_functions are specific to the input from a file.
I read about the the request fixture, but not sure how to use it to inspect the context of a test function.
If anyone has that figured out, please let me know. Meanwhile I will post as soon as i get it working!
EDIT 2: I also know about inspect
and introspect
BUT i am looking for a cleaner way to do this, preferably by using some pytest
magic~
Thanks!
Upvotes: 4
Views: 1262
Reputation: 66171
You can parametrize the fixture from test and read the passed parameter via request.param
:
import pytest
@pytest.fixture
def fixture_1(request):
filename = request.param
with open(filename) as f:
f_str = f.read()
yield f_str
@pytest.mark.parametrize('fixture_1', ['file_one.txt'], indirect=True)
def test_function_1(fixture_1):
assert fixture_1.startswith("some_test_data") # example test
@pytest.mark.parametrize('fixture_1', ['file_two.txt'], indirect=True)
def test_function_2(fixture_1):
assert something_for_fun
Test run should yield:
test_module.py::test_function_1[file_one.txt] PASSED
test_module.py::test_function_2[file_two.txt] PASSED
You can also set up a default fixture value for the filename and parametrize on demand:
@pytest.fixture
def fixture_1(request):
filename = getattr(request, 'param', 'file_one.txt')
with open(filename) as f:
f_str = f.read()
yield f_str
def test_function_1(fixture_1):
assert fixture_1.startswith("some_test_data") # example test
@pytest.mark.parametrize('fixture_1', ['file_two.txt'], indirect=True)
def test_function_2(fixture_1):
assert fixture_1.startswith('bar')
Now test_function_1
stays unparametrized:
test_module.py::test_function_1 PASSED
test_module.py::test_function_2[file_two.txt] PASSED
Upvotes: 3