Skip to content

Instantly share code, notes, and snippets.

@elowy01
Last active December 14, 2020 22:55
Show Gist options
  • Save elowy01/edc6110e51ba93fd9541be606873f4d8 to your computer and use it in GitHub Desktop.
Save elowy01/edc6110e51ba93fd9541be606873f4d8 to your computer and use it in GitHub Desktop.
###### Pytest fixtures
# Basic toy example:
import pytest
@pytest.fixture()
def before():
print('\nbefore each test')
def test_1(before):
print('test_1()')
def test_2(before):
print('test_2()')
# Fixture return a dict:
import pytest
@pytest.fixture()
def some_data():
data = {'foo':1, 'bar':2, 'baz':3}
return data
def test_foo(some_data):
assert some_data['foo'] == 1
# Scope a fixture
# 'function' is the default scope and means that the the fixture will be executed before each test
import pytest
@pytest.fixture(scope="function")
def before():
print('before each test')
def test_1(before):
print('test_1()')
def test_2(before):
print('test_2()')
## 'module' . Fixture will be executed only once
import pytest
@pytest.fixture(scope="module")
def before():
print('before each test')
def test_1(before):
print('test_1()')
def test_2(before):
print('test_2()')
## teardown code
@pytest.fixture()
def cheese_db(request):
print('\n[setup] cheese_db, connect to db')
# code to connect to your db
a_dictionary_for_now = {'Brie': 'No.', 'Camenbert': 'Ah! We have Camenbert, yessir.'}
def fin():
print('\n[teardown] cheese_db finalizer, disconnect from db')
request.addfinalizer(fin)
return a_dictionary_for_now
def test_cheese_database(cheese_db):
print('in test_cheese_database()')
for variety in cheese_db.keys():
print('%s : %s' % (variety, cheese_db[variety]))
def test_brie(cheese_db):
print('in test_brie()')
assert cheese_db['Brie'] == 'No.'
def test_camenbert(cheese_db):
print('in test_camenbert()')
assert cheese_db['Camenbert'] != 'No.'
## Fixture to generate a set of params:
import pytest
@pytest.fixture( params=[1,2,3] )
def test_data(request):
return request.param
def test_not_2(test_data):
print('test_data: %s' % test_data)
assert test_data != 2
## How to share the smae fixtures among different test files
1) Include the fixtures you want to share in a file named conftest.py
that will be placed in the test root folder. Ex:
import pytest
@pytest.fixture(scope="session")
def before():
print('before each test')
return 'a'
@pytest.fixture(scope="session")
def after():
print('after each test')
return 'b'
2) Then, write a test file named test_pytest.py that will use the fixtures in conftest.py:
import pytest
def test_1(before):
print('test_1()')
print(f"Returned: {before}")
def test_2(after):
print('test_1()')
print(f"Returned: {after}")
3) Execute:
$ pytest -s -v test_pytest.py
You will get:
collected 2 items
test_pytest.py::test_1 before each test
test_1()
Returned: a
PASSED
test_pytest.py::test_2 after each test
test_1()
Returned: b
PASSED
###### How to do a pytest with multiple params:
# 1) Containing only 2 params:
# content of test_expectation.py
import pytest
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
assert eval(test_input) == expected
# 2) Containing 3 params:
# content of test_expectation.py
import pytest
@pytest.mark.parametrize("a,b,expected", [(1,2,3), (2,4,6), (3,10,42)])
def test_eval(a,b,expected):
assert a+b == expected
//
# Selecting specific tests to run
pytest test_file.py -k 'test_one or test_two'
#####Setting env (environment) variables for the tests.
# conftest.py
import pytest
@pytest.fixture(autouse=True) # make sure that this is executed in each test
def env_setup(monkeypatch):
monkeypatch.setenv('TEST', 'foo')
# Now, we have the file that uses the fixture
# test_1.py
import pytest
import os
def test_1():
print(os.environ['TEST'])
assert 1 == 1
# check if a file has been created by a test
assert os.path.exists(outfile) == 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment