Тестирование в Python может быть сложно Так что я изложил, что работает для меня. Мне нравится использовать pteest с Pytest-factoryboy генерировать данные тестирования. Pytest-factoryboy
Простой способ проверить, чем на необходимость поддержания приспособлений в тестовой базе данных.
Определите фабрики. Они выглядят очень похожи на модели.
# tests/factories.py import factory from faker import Factory as FakerFactory from django.contrib.auth.models import User from django.utils.timezone import now from app.models import Game, Message, GamePlayer, Round, Move faker = FakerFactory.create() class UserFactory(factory.django.DjangoModelFactory): class Meta: model = User email = factory.Faker("safe_email") username = factory.LazyAttribute(lambda x: faker.name()) @classmethod def _prepare(cls, create, **kwargs): password = kwargs.pop("password", None) user = super(UserFactory, cls)._prepare(create, **kwargs) if password: user.set_password(password) if create: user.save() return user class GameFactory(factory.django.DjangoModelFactory): room_name = factory.LazyAttribute(lambda x: faker.name()) game_status = "active" created_at = factory.LazyAttribute(lambda x: now()) updated_at = factory.LazyAttribute(lambda x: now()) round_started = False is_joinable = True class Meta: model = Game class GamePlayerFactory(factory.django.DjangoModelFactory): followers = 0 selfies = 3 user = factory.SubFactory(UserFactory) started = False game = factory.SubFactory(GameFactory) class Meta: model = GamePlayer class MessageFactory(factory.django.DjangoModelFactory): game = factory.SubFactory(GameFactory) username = None message = factory.LazyAttribute(lambda x: faker.sentence()) created_at = factory.LazyAttribute(lambda x: now()) message_type = None class Meta: model = Message # etc
В файле Conftest.py я регистрирую фабрики.
Светильники, определенные в Conftest.py
Файл будет распознан в любом тестовом файле. ” Регистрация «Фабрики позволяет вам ввести их в ваши тесты с помощью имени класса Class offerscore | В этом же файле я определяю приспособления с @ pytest.fixture () Что я буду использовать в моем тестах, и вводить их на фабрики, которые я только что зарегистрирован.
# tests/conftest.py import pytest from pytest_factoryboy import register from .factories import ( UserFactory, GameFactory, GamePlayerFactory, MoveFactory, RoundFactory, ) register(UserFactory) register(GameFactory) register(GamePlayerFactory) register(MoveFactory) register(RoundFactory) @pytest.fixture() def game(game_factory): return game_factory() @pytest.fixture() def rnd(game, round_factory): return round_factory(game=game, started=True) @pytest.fixture() def p_1(game, user_factory, game_player_factory): return game_player_factory(game=game, user=user_factory(), started=True) #etc...more player fixtures defined
Написать тесты
Здесь я пишу тесты. Я передаю данные о моем методе прибора в мой тестовый метод, а также прохождение на заводе под названием двигаться
Потому что это то, что я в основном проверяю здесь. Для того, чтобы тестировать движения проигрывателя, мне сначала нужно было создать игроков, игру и раунд, что я сделал в моем Conftest.py
файл. Мне нужно только сделать это один раз, и мне не нужно импортировать светильники, потому что все, что заявлено в Conftest.py
виден для тестовых файлов.
# tests/test_round_service.py import pytest from app.services.round_service import ( RoundTabulation, LEAVE_COMMENT, CALL_IPHONE, DISLIKE, GO_LIVE, POST_SELFIE, DONT_POST, NO_MOVE, DISLIKE_DM, POST_SELFIE_PTS, POST_SELFIE_DM, GO_LIVE_DM, NO_MOVE_DM, ) from app.services import round_service, message_service from app.models import Move, Message, GamePlayer @pytest.mark.django_db def test_iphone_go_live_do_selfie(rnd, p_1, p_2, p_3, move_factory): """if a girl calls a girl who is trying to take a selfie, she sustains go live damage""" move_factory(round=rnd, action_type=GO_LIVE, player=p_1, victim=None) move_factory(round=rnd, action_type=CALL_IPHONE, player=p_2, victim=p_3) move_factory(round=rnd, action_type=POST_SELFIE, player=p_3, victim=None) tab = RoundTabulation(rnd).tabulate() assert tab[p_1.id] == 0 assert tab[p_2.id] == GO_LIVE_DM assert tab[p_3.id] == GO_LIVE_DM @pytest.mark.django_db def test_go_live_with_call(rnd, p_1, p_2, p_3, p_4, p_5, move_factory): """message was created, points are corrected, player is removed from player points array, they have one less story""" move_factory(round=rnd, action_type=GO_LIVE, player=p_1, victim=None) move = move_factory(round=rnd, action_type=CALL_IPHONE, player=p_2, victim=p_1) move_factory(round=rnd, action_type=DISLIKE, player=p_3, victim=p_1) move_factory(round=rnd, action_type=DISLIKE, player=p_4, victim=p_1) move_factory(round=rnd, action_type=LEAVE_COMMENT, player=p_5, victim=p_1) tab = RoundTabulation(rnd).tabulate() assert message(rnd.game, p_2.user.username) in message_service.iphone_msg( move, p_1.user.username ) p_1 = GamePlayer.objects.get(id=p_1.id) assert p_1.go_live == 1 assert tab[p_1.id] == -50
Выполнить тесты
Теперь ваши тесты могут работать с тестовыми данными!
[17:59:32] (master) selfies 🙋 docker exec -it 5c93db3f3183 bash root@5c93db3f3183:/selfies# pytest app/tests/test_round_service.py ======================================= test session starts ======================================== platform linux -- Python 3.7.4, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 Django settings: selfies.settings (from ini file) rootdir: /selfies, inifile: pytest.ini plugins: factoryboy-2.0.3, django-3.5.1 collected 15 items app/tests/test_round_service.py ...............
Оригинал: “https://dev.to/aduranil/writing-tests-with-pytest-and-factory-k7”