Search
Write a publication
Pull to refresh
15
0
Сергей @KarmanovichDev

python разработчик с многолетним опытом

Send message

Спасибо за статью о dishka и разбор fastapi.

  1. Первую половину статьи вы "ругаете" fastapi за то, что он неправильный DI(dependency inversion) так как зависим от реализации, но кто сказал, что Depends про это? Depends это про DI(dependency injection), где суть во внедрении зависимостей снаружи, а не создание их внутри объектов(композиция -> агрегация). В самой документации fastapi о depends не встретил упоминания об инверсии зависимостей.

  2. Вы говорите, что dishka поможет нам внедрять(инвертировать) зависимости на разных уровнях и не только в контроллере. Правильно ли я понимаю, что у меня весь инфраструктурный код реализаций абстракций будет "усеян" этим декоратором и весь проект будет сильно привязан к этой библиотеке? В то время как с Depends мы собираем зависимости в рамках контроллера и детали реализации просто ждут снаружи требуемые им параметры?

Depends это про внедрение, а Dishka ещё и про инверсию и не только на уровне контроллера. Сравнивать их напрямую, кажется не совсем правильно. Это тот самый случай, когда DI != DI )))

Может быть разгадка кроется в названии книги? "Идеальный программист" для работодателя😅

Я говорю про ситуацию, когда результат не меняется, а объект работает и возвращает нужный результат, но тест падает.

Есть такой подход, когда мы проверяем состояние не с помощью деталей реализации, а с помощью уже имеющегося открытого API.

  • Вместо того, чтобы явно вызывать orm или sql запрос, чтобы проверить, что вы создали нужный объект, в тесте вам нужно дёрнуть метод get того же репозитория.

  • Этот подход при желании можно использовать даже при тестировании самого приложения. Сначала вы делаете test_client.save(path=..., ...), а на этапе проверки делаете test_client.get(path=..., ...)

Не совсем понял про "менять сервер в угоду тестов"

Я не совсем понимаю про что вы. Если результаты работы объекта не меняются, но тест падает, очень вероятно что ваш тест хрупкий, завязанный на детали реализации, и это ложное срабатывание так называемое.

Спасибо за статью!

Полностью согласен! Если UseCase является прокси объектом к другому механизму(репо например) или содержит минимальное кол-ло логики, то выделение UseCase приводит лишь к дополнительным тестам, а учитывая, что репо это внепроцессная зависимость, то по-хорошему и к дополнительным тестовым дублёрам(моки, фейки и т. п.).

Только нужно помнить, что это regexp под капотом и в вашем случае нужно сделать match="^object has no attribute 'name'$"

Согласен, это хороший вариант, что бы проверить текст.

Если нужно проверить, что-то большее чем первый аргумент исключения, то после with ... нужно написать "as error" и после контекстного менеджера проверить всё, что нужно )

Это лишь первая часть) В следующих частях будут углубления в тему.

Учту третий пример на будущее, спасибо.

Получается, если где-то есть первоисточник, или другая статья, то лучше не стоит писать свои мысли и опыт ?)

Возможно, у вас есть причины использовать такой подход по умолчанию.

Вам это помогало в юнит-тестах или интеграционных? Есть наглядный пример(ы), где вы нашли баг из-за рандомизации тестовых данных ?

Кажется, что код-стайл это дело каждого(каждой команды). Особенно когда он выходит за рамки стандартных линтеров и является доп. библиотеками.

Про raises упомянул в самом конце статьи.

Насчёт approx - постараюсь не забыть и упомянуть.

Насчёт последнего - сравнивать не планировал библиотеки в рамках этой серии статей, но рассказывать про возможности патчинга и создания тестовых дублёров планирую.

Причин не помню, но сам обычно использую pytest-mock библиотеку для этих вещей, ну или пишу тестовые дублёры сам.

Про raises упомянул в самом конце статьи.

Насчёт approx - постараюсь не забыть и упомянуть.

Насчёт последнего - сравнивать не планировал библиотеки в рамках этой серии статей, но рассказывать про возможности патчинга и создания тестовых дублёров планирую.

Причин не помню, но сам обычно использую pytest-mock библиотеку для этих вещей, ну или пишу тестовые дублёры сам.

Решил что для первой части будет достаточно )

Делать без класса не плохо. Тут скорее мне нравится объединять в классы тесты.

Тестовый класс объединяет в себе тесты тестируемого класса(тесты связаны одной целью).

Есть примеры, когда нет состояния, но есть класс. Например, при применении паттерна абстрактная фабрика. Или обычная фабрика, которая умеет из разных входных данных создавать или разные виды объекта. Не единственные примеры. Первое, что пришло в голову.

Искать очень удобно, когда тестовый класс называется точно так же, как класс, который он тестирует с припиской тест.

Декораторы от pytest можно навесить на класс и они применяться к каждому тесту внутри класса, что позволит не весить его на каждый метод.

Также фикстуры можно создавать единожды на класс.

Думаю, если подумать, и/или погуглить можно ещё найти причин каких-то.

Я стараюсь тестовые данные писать сам. Тесты == документация к использованию моего приложения. Часто можно показать пользователю(другому разработчику) более реальные пути использования приложения в добавок к покрытию тестами.

В любом случае ваш совет имеет место быть и может многим показать как упросить себе жизнь, спасибо!

Добрый день! В рамках ознакомительной статьи я не планировал более сложных примеров.

Если коротко, то такой UoW, о котором вы говорите, должен будет уметь держать транзакции разных БД.

Если это удалённое хранилище без возможности держать эту самую сессию, то нужно делать другой механизм отката(где мы по той же APIшке сходим в случае провала и отменим/удалим/... своё последнее действие).

Да, это может вызвать неконсистентность данных на короткий промежуток времени, но либо вас это устраивает, либо вам нужно рассмотреть вариант двухфазных транзакций(фикскаций) или другие варианты.

Я очень рад, что смог заинтересовать вас! Опыта в написании у меня мало, но стараюсь вкладывать душу :)

Спасибо, поправил. Прогоняю статью после написания через сервис. Не везде могу точно сказать, как будет правильнее(мой минус).

Information

Rating
Does not participate
Location
Россия
Registered
Activity

Specialization

Backend Developer
Lead
Python
Linux
OOP