Created
January 23, 2020 20:50
-
-
Save JacobCallahan/d6c816e34663d3affe582c7327f73ded to your computer and use it in GitHub Desktop.
Fixture demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Pytest fixtures | |
Fixtures give you a convenient way to perform setup actions outside of a test. | |
By limiting or expanding the scope of a fixture, you can cut down on costly setup tasks. | |
""" | |
import pytest | |
import random | |
import unittest2 # please never | |
NUM = "0123456789" | |
ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
def dummy(val): | |
"""This is the target of our tests (ideally in a separate file)""" | |
return int(val) * 5 | |
"""pytest searches for these next two named methods in each file. | |
if present, setup_module will run before tests are ran | |
teardown_module will run after | |
you don't need to do anything special to trigger this | |
""" | |
def setup_module(module): | |
print("==================== Setting things up ====================") | |
def teardown_module(module): | |
print("==================== Tearing things down ====================") | |
@pytest.fixture | |
def good_int(): | |
"""The most basic fixture. This will provide a new value for each test.""" | |
return random.randint(0, 100) | |
@pytest.fixture | |
def good_str(): | |
"""By default, a fixture's scope is at the test/function level. | |
This means that random return values will be different for each test | |
""" | |
res = "" | |
for i in range(5): | |
res += random.choice(NUM) | |
return res | |
@pytest.fixture(scope="module") | |
def bad_str(): | |
"""To share a common random value (or object), set the scope to module. | |
Each test in this file, accepting bad_str will then have the same value | |
""" | |
res = "" | |
for i in range(5): | |
res += random.choice(ALPHA) | |
return res | |
@pytest.fixture(scope="session") | |
def common_int(): | |
"""A scope of session will use the same value for all tests in the same pytest run""" | |
return random.randint(0, 100) | |
@pytest.fixture(scope="module") | |
def important_thing(): | |
"""If things don't go well during a fixture, you can skip any test that expects a value.""" | |
thing = random.choice([True, False]) | |
if not thing: | |
# I don't want to get a false failure, so skip dependent tests | |
pytest.skip("Setup failed. Skipping test...") | |
return thing | |
@pytest.fixture(scope="class") | |
def my_cool_thing(request, bad_str): | |
"""You can even add attributes to a test class (unittest style) using fixtures | |
note that this fixture also takes in the value of another fixture! | |
""" | |
request.cls.my_thing = bad_str | |
# tests in the class can then reference the value with: self.my_thing | |
def test_positive_dummy(): | |
"""basic test. uses no fixtures""" | |
assert dummy(5) == 25 | |
def test_positive_dummy_int(common_int): | |
"""Experiement with switching common_int to good_int, then check output""" | |
print(common_int) | |
result = dummy(common_int) | |
assert result == common_int * 5 | |
def test_positive_dummy_int2(common_int): | |
"""Experiement with switching common_int to good_int, then check output""" | |
print(common_int) | |
result = dummy(common_int) | |
assert result == common_int * 5 | |
def test_positive_dummy_str(good_str): | |
print(good_str) | |
result = dummy(good_str) | |
assert isinstance(result, int) | |
def test_negative_dummy_str(bad_str): | |
print(bad_str) | |
try: | |
result = dummy(good_str) | |
assert not isinstance(result, int) | |
except: | |
assert True | |
def test_positive_thing(important_thing): | |
"""This test has a 50% chance of being skipped""" | |
assert important_thing | |
# broken, but you can play around with it | |
@pytest.mark.usefixtures("my_cool_thing") | |
class UnittestSucks(unittest2.TestCase): | |
"""Use pytest.mark.usefixtures to accept the previously define class-scoped fixture""" | |
def __init__(self, *args, **kwargs): | |
print(args) | |
print(kwargs) | |
self.whatever = "sure" | |
def test_dont_use_unittest(self): | |
print(self.my_thing) | |
assert self.my_thing != self.whatever |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
run with
pytest -sv fixtures.py
for the best experience