Mam na imię Michał
Zajmuję się backendem, protokołami, bazami danych, czasem embedded
Obecnie pracuję w Vatix
Lubię chodzić po górach i DIY
@dataclass
class API:
user: User
def list_todos(self): ...
def create_todo(self, name): ...
def share_todo(self, list_uuid, user, permissions): ...
def list_items(self, list_uuid): ...
def create_item(self, list_uuid, name): ...
def retrieve_item(self, list_uuid, item_uuid): ...
def update_item(self, list_uuid, item_uuid, status: Status): ...
TodoList
TodoItem
Organisation
User
Team
class MyTestCase(TestCase):
def setUp(self):
# prepare everything
def test_something(self):
...
def test_something_else(self):
...
def tearDown(self):
# clean up after tests
class APITestCase(TestCase):
def setUp(self):
super().setUp()
self.faker = Faker()
self.my_organisation = Organisation(name=faker.company())
self.my_team = Team(
name=faker.color(),
organisation=self.my_organisation
)
self.my_user = User(
name=faker.name(),
team=self.my_team
)
class TestListTodos(APITestCase):
def test_empty(self):
self.assertListEqual(self.my_user.api.list_todos(), [])
class TestMyListMixin:
def setUp(self):
super().setUp()
self.my_todo_list = TodoList(
owner=self.my_user,
name=self.faker.bs()
)
class TestListOwner(TestMyListMixin, APITestCase):
def test_owner(self):
self.assertListEqual(
self.my_user.api.list_todos(),
[self.my_todo_list]
)
class TestListMate(TestMyListMixin, APITestCase):
def setUp(self):
super().setUp()
self.my_team_mate = User(
name=self.faker.name(),
team=self.my_team,
role=Role.USER
)
def test_mate(self):
self.assertListEqual(self.my_team_mate.api.list_todos(), [])
class TestListManager(TestMyListMixin, APITestCase):
def setUp(self):
super().setUp()
self.my_team_manager = User(
name=self.faker.name(),
team=self.my_team,
role=Role.MANAGER
)
def test_manager(self):
self.assertListEqual(
self.my_team_manager.api.list_todos(),
[self.my_todo_list]
)
class TestListAdmin(TestMyListMixin, APITestCase):
def setUp(self):
super().setUp()
self.my_admin = User(
name=self.faker.name(),
team=Team(name="Admins", organisation=self.my_organisation),
role=Role.ADMIN
)
def test_admin(self):
self.assertListEqual(
self.my_admin.api.list_todos(),
[self.my_todo_list]
)
class TestOtherTeamMixin(TestMyListMixin):
def setUp(self):
super().setUp()
self.other_team = Team(
name=self.faker.color_name(),
organisation=self.my_organisation
)
class TestOtherOrganisationMixin(TestMyListMixin):
def setUp(self):
super().setUp()
self.other_organisation = Organisation(name=self.faker.company())
self.other_organisation_team = Team(
name=self.faker.color_name(),
organisation=self.other_organisation
)
@pytest.fixture
def something():
# prepare
yield "Something"
# cleanup
@pytest.fixture
def something_else():
# prepare
yield "Something else"
# cleanup
def test_something(something):
assert something == "Something"
def test_something_else(something_else):
assert something_else == "Something else"
@pytest.fixture
def my_organisation(faker: Faker):
return Organisation(name=faker.company())
@pytest.fixture
def my_team(faker: Faker, my_organisation: Organisation):
return Team(
name=faker.color_name(),
organisation=my_organisation
)
@pytest.fixture
def my_user(faker: Faker, my_team: Team):
return User(name=faker.name(), team=my_team, role=Role.USER)
def test_empty(my_user):
assert my_user.api.list_todos() == []
@pytest.fixture
def my_todo_list(faker: Faker, my_user: User):
return TodoList(owner=my_user, name=faker.bs())
def test_owner(my_user, my_todo_list):
assert my_user.api.list_todos() == [my_todo_list]
@pytest.fixture
def my_team_mate(faker: Faker, my_team: Team):
return User(name=faker.name(), team=my_team, role=Role.USER)
def test_mate(my_team_mate, my_todo_list):
assert my_team_mate.api.list_todos() == []
@pytest.fixture
def my_team_manager(faker: Faker, my_team: Team):
return User(name=faker.name(), team=my_team, role=Role.MANAGER)
def test_manager(my_team_manager, my_todo_list):
assert my_team_manager.api.list_todos() == [my_todo_list]
@pytest.fixture
def other_organisation():
return Organisation(...)
@pytest.fixture
def other_organisation_team(other_organisation: Organisation):
return Team(..., organisation=other_organisation)
@pytest.fixture
def other_organisation_mate(other_organisation_team):
return User(..., team=other_organisation_team, role=Role.USER)
@pytest.fixture
def other_organisation_manager(other_organisation_team: Team):
return User(..., team=other_organisation_team, role=Role.MANAGER)
my org
my team
my user
my team mate
my team manager
other team
other org
other org team
other team mate
other team manager
other org mate
other org manager
other org admin
my org admin
my org
my team
my user
other user manager | user
other team
other org
other org team
other team mate
other team manager
other org mate
other org manager
other org admin
my org admin
@pytest.mark.parametrize(
'a,b,result',
[
(1,2,3),
(3,4,7),
]
)
def test_addition(a, b, result):
assert a + b == result
@pytest.fixture
def result():
return 42
@pytest.mark.parametrize(
'a,b,result',
[
(1, 2, 3),
(3, 4, 7),
]
)
def test_addition(a, b, result):
assert a + b == result
@pytest.fixture
def result(request):
param = getattr(request, 'param', 41)
return param + 1
def test_42(result):
assert result == 42
@pytest.mark.parametrize(
'a,b,result',
[
(1, 2, 2),
(3, 4, 6),
],
indirect=['result']
)
def test_addition(a, b, result):
assert a + b == result
@pytest.fixture
def other_user(request, my_team):
role = getattr(request, 'param', Role.USER)
return User(..., team=my_team, role=role)
@pytest.mark.parametrize('other_user', [
Role.USER
], indirect=['other_user'])
def test_mate(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
@pytest.mark.parametrize('other_user', [
Role.MANAGER
], indirect=['other_user'])
def test_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == [my_todo_list]
my org
my team
my user
other user
manager | user
other team
other org
other org team
other org mate
other org manager
other org admin
my org admin
@pytest.fixture
def other_user(request):
team_or_fixture = getattr(request, 'param', my_team)
if hasattr(team_or_fixture, '_pytestfixturefunction'):
team = request.getfixturevalue(team_fixture.__name__)
else:
team = team_or_fixture
return User(..., team=team)
@pytest.mark.parametrize('other_user', [
other_team,
], indirect=True)
def test_other_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
@pytest.fixture
def other_user(request):
param = getattr(request, 'param', {})
role = param.get('role', Role.USER)
team_or_fixture = param.get('team', my_team)
if hasattr(team_or_fixture, '_pytestfixturefunction'):
team = request.getfixturevalue(team_fixture.__name__)
else:
team = team_or_fixture
return User(..., team=team, role=role)
@pytest.mark.parametrize('other_user', [
dict(team=other_team, role=Role.USER),
], indirect=True)
def test_other_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
my org
my team
other team
other org
my user
other user
manager | user
@dataclass
class OtherUserParam:
role: Role = field(default=Role.USER)
team: Team = field(default_factory=my_team) # ???
@pytest.fixture
def other_user(request):
param = make_param_model(request, OtherUserParam)
return User(..., team=param.team, role=param.role)
@pytest.mark.parametrize(
'other_user',
[
dict(team=other_team, role=Role.MANAGER)
],
indirect=True
)
def test_other_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
@dataclass
class UserParam:
team: Team = field(default_factory=my_team)
role: Role = Role.USER
@parametrized_fixture(UserParam)
def my_user(request) -> User:
return User(
...,
team=request.param.team,
role=request.param.role
)
@pytest.mark.parametrize('other_user', [
dict(role=Role.USER)
], indirect=True)
def test_mate(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
@pytest.mark.parametrize('other_user', [
dict(role=Role.MANAGER)
], indirect=True)
def test_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == [my_todo_list]
@pytest.mark.parametrize('other_user', [
dict(team=other_team, role=Role.MANAGER)
], indirect=True)
def test_other_manager(self, other_user, my_todo_list):
assert other_user.api.list_todos() == []
@pytest.mark.parametrize('other_user, result', [
(
dict(role=Role.USER),
[]
),
(
dict(role=Role.MANAGER, team=other_team),
[]
),
(
dict(role=Role.MANAGER),
... # ???
),
], indirect=['other_user'])
def test_other_user(self, other_user, result):
assert other_user.api.list_todos() == result
@pytest.fixture
def result(request):
func_or_value = getattr(request, 'param', None)
if not inspect.isfunction(func_or_value):
return func_or_value
try:
signature = inspect.signature(func_or_value)
parameters = signature.parameters.values()
except ValueError:
parameters = []
kwargs = {}
for parameter in parameters:
try:
kwargs[parameter.name] = \
request.getfixturevalue(parameter.name)
except pytest.FixtureLookupError:
continue
return func_or_value(**kwargs)
@pytest.mark.parametrize('other_user, result', [
(
dict(role=Role.MANAGER),
lambda my_todo_list: [my_todo_list]
),
], indirect=['other_user', 'result'])
def test_other_user(self, other_user, result):
assert other_user.api.list_todos() == result
@parametrized_fixture
def result(request):
raise NotImplementedError
@pytest.mark.parametrize('other_user, result', [
(
dict(role=Role.USER),
[]
),
(
dict(role=Role.MANAGER, team=other_team),
[]
),
(
dict(role=Role.MANAGER),
lambda my_todo_list: [my_todo_list]
),
], indirect=['other_user', 'result']
)
def test_other_user(self, other_user, result):
assert other_user.api.list_todos() == result
def pytest_generate_tests(metafunc):
#
# use pytest API to find parametrization and add indirect=[]
# where parameters refer to our "magic" fixtures
#
# implementation is on github ;)
@pytest.mark.parametrize("other_user, result", [
(
my_user,
lambda my_todo_list: [my_todo_list]
),
(
dict(role=Role.USER),
[]
),
(
dict(role=Role.MANAGER, team=other_team),
[]
),
(
dict(role=Role.MANAGER),
lambda my_todo_list: [my_todo_list]
),
(
dict(role=Role.ADMIN),
lambda my_todo_list: [my_todo_list]
),
],
)
def test_same_organisation(self, other_team, other_user, my_todo_list, result):
assert other_user.api.list_todos() == result
@pytest.mark.parametrize("my_todo_list, other_user", [
(
dict(
collaborators=lambda other_user: {other_user: {Permission.CREATE}}
),
dict(
role=Role.USER,
team=lambda other_organisation: Team(organisation=other_organisation),
),
),
],
)
def test_share_across_organisations(self, other_user, my_todo_list):
item = other_user.api.create_item(my_todo_list.uuid, 'Buy milk')
assert item
assert my_todo_list.todoitem_set == [item]
@pytest.mark.parametrize("other_user", [
dict(role=Role.USER)
])
class TestMates:
def test_same_organisation(self, other_user):
...
@pytest.mark.parametrize("other_user", [
dict(organisation=other_organisation)
])
def test_other_organisation(self, other_user):
...
ValueError: duplicate parametrization of 'other_user'
mrzechonek/fixture_parametrization