TGViewer
Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL @aqa_engineer · 1.52K subscribers
Post #381 577
Лонгрид.

Наша платформенная команда старается помочь, как можем, но не нарушая хорошие практики.
У нас есть платформенный фреймворк, который может применяться для всего: для ML, разработки, тестов.
У него очень крутая концепция и очень крутой интерфейс.

Представьте, что вы пишете автотесты, и любой клиент, который вам нужен, можно получить, просто проставив декоратор.

Например:
@nuke_test
async def test_something(client: MyClient):
await client.do_something()

То есть вам даже не нужно писать фикстуру, вы можете сделать любой класс-хелпер.
Просто поставить аннотацию, и он будет работать, не надо никаких инстансов — всё работает.

Даже если ваш клиент имеет кучу зависимостей типа:
class MyClient(Client):
api1: Api1
api2: Api2
api3: Api3
...
apiN: ApiN

Вам эти зависимости не нужно передавать — тест будет работать так же просто, как в первом примере.

Потому что у нашей платформы написан свой DI и определённый механизм, который скрыто для пользователя создаёт все зависимости.

Круто? Очень круто.

Удобно? Безумно удобно, интерфейс предельно простой.

Работает ли это на практике?

Не у всех. Почему? Потому что огромные ошибки проектирования тестов, оверинжиниринг, наследование не там, где нужно, нарушение принципов программирования.

Сегодня встречался ещё с одной командой, у которых тысячи тестов.
Вроде бы вся сложность реализации скрыта, но всё просто капец какое ломучее.
И ни один стандартный наш подход не работает. Почему?

Например:
from lib import clients

@dataclass
class BaseOrder:
id: int

class Order(BaseOrder):
@staticmethod
def do_something():
clients.do_something()

def test_order():
Order(id=1).do_something()

Что здесь не так?
1. Нарушение принципа SRP (Single Responsibility Principle)

Почему это плохо:
• Order должен представлять бизнес-сущность заказа.
• Но он также знает о том, как вызывать внешние сервисы.
• Это два разных уровня ответственности.

А что если завтра clients.do_something() изменит сигнатуру? Потребует аутентификацию? Появится новый клиент? Вам придётся менять модель Order.

Что хорошего?
Код простой — да. Но он не расширяемый. Попробуйте написать тест с моком или заменить clients на другую реализацию.

2. Нарушение принципа DIP (Dependency Inversion Principle)
from lib import clients — жёсткая зависимость

Почему это плохо:
• Order зависит от конкретной реализации, а не от абстракции.
• Невозможно заменить clients на другую реализацию без изменения Order.
• Нарушается принцип «зависеть от абстракций, а не от конкретики».

А что если понадобится другой clients для тестов?
А если clients переедет в другой модуль?
А если нужно будет добавить логирование или метрики вокруг вызовов?

3. Сильная связность

Почему это плохо:
• Order не может существовать без clients.
• clients нельзя заменить или замокать.
• Тестирование возможно только с реальным clients.

Если clients падает, падают все тесты Order.
Сложно тестировать логику Order изолированно.

4. Использование глобальной переменной, которая хранит все объекты.

Почему это плохо:
• Глобальное состояние может изменяться между тестами.
• Сложно контролировать состояние clients.
• Побочные эффекты между тестами.

Теперь представим, что мы хотим использовать наш подход с декоратором или фикстурой — и не можем.
Нам придётся явно передавать зависимости в каждый инстанс Order, что для тысячи тестов очень тяжело. У нас куча входных точек в каждом тесте.

Захотим немного поменять clients — есть вероятность разломать кучу тестов, потому что они ультра сильно связаны.

Как я считаю, можно было бы сделать правильно:

Сделать OrderHelper:
class OrderHelper:
def __init__(self, client):
self.client = client

def make_order(self, id):
self.client.do_something()

Тем самым мы получаем только ту зависимость, которая нам нужна, и не тащим за собой весь скоуп.

Продолжение следует...
Telegram Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL Преимущества: 1. SRP соблюдён — OrderHelper занимается только логикой работы с заказами. 2. DIP соблюдён — зависит от переданного client, а не от конкретной реализации. 3. Слабая связанность — можно подставить любой client. 4. Тестируемость —…
  • ❤ 1
  • 🔥 1
More from @aqa_engineer
  1. Sep 2, 2026💙💙💙💙💙 Маленькое напоминание о большой дате: где стоит провести День программиста⬆️ Ар…
  2. Sep 2, 2026Привет, давно меня не было пригар по работе, что совсем не успеваю ничего. За что прошу пр…
  3. Jul 16, 2026👩‍💻 В мае-июне я проходила курс «Автоматизация тестирования Rest API Advanced (Python)»…
  4. Jun 10, 2026Привет! Уже на следующей неделе у меня стартуют. Автоматизация тестирования брокеров сообщ…
  5. Jun 8, 2026Несколько месяцев назад я спросил, какой технический тренинг вам был бы действительно инте…
  6. Jun 6, 2026Материалы для тех, кто в теме. Одна из самых больших проблем при развитии в IT - это возмо…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →