У меня сейчас доучивается группа по автотестам и самая сложная неделя это вторая когда мы начинаем активно внедрять всякие архитектнурные штуки.
Почему вообще во всех тренингах я акцентирую на этом внимание, да потому что одна из самых частых причин, почему автотесты превращаются в мусор это отсутствие архитектуры.
Тесты пишутся, они даже проходят.
А потом:
- их страшно менять
- они часто падают
- тяжело понять, где что сломалось
Ниже - базовая архитектура backend-автотестов, которую я рекомендую у себя в тренингах.
Layers: Transport / API Client / Services (Helpers) / Tests
1. Transport уровень HTTP/GRPC - технический слой
На этом уровне лучше всего реализовывать логгирование, закреп attach в аллюр и тп.
class HTTPClient:
def request(*args, **kwargs) -> Response:
log.debug(f"Request send with params: {args, kwargs}")
2. API Client - уровень сервиса.
На этом уровне происходит валидация контрактов, сериализация / десериализация , структур запросов и ответов.
class PetstoreApi:
def __init__(self, client: HTTPClient) -> None:
...
def post_pet(self, request_model: PetModelRequest) -> PetModelResponse:
...
3. Services (Helpers) - уровень бизнес логики
Здесь мы можем реализовывать как методы которые просто оборачивают методы из класса Api Client. Так и реализовывать какую то "композитную логику", которая выполняет целый бизнес флоу для какого то действия.
class PetStoreHelper:
def __init__(self, petstore_api: PetstoreApi) -> None:
self._petstore_api = petstore_api
def create_pet(name: str, kind: str) -> PetModelResponse
request_model = PetModelRequest(name, kind)
self._petstore_api.post_pet(request_model=request_model)
...
4. Tests - уровень тестов
Здесь описываются уже конкретный сценарии из методов описанных в классе помощнике.
def test_create_pet(petstore_helper: PetStoreHelper) -> None:
response = petstore_helper.create_pet('sharik', 'dog')
assert response
Что нам это дает?
1. Понятные и читабельные сценарии, где ясно что происходит, легко писать тесты из готовых шагов.
2. Легче поддерживать.
1. Меняется формат логов? Достаточно это сделать на уровне транспорта и фреймворк все подтянет автоматически.
2. Меняется контракт? Достаточно внести изменения на уровне Helper
3. Меняется endpoint для Api метода, достаточно внести изменения на уровне Api Client.
То есть несмотря на кажущуюся сложность в разделении уровней и дополнительных абстракций, нам легко понять где и на каком уровне необходимо вносить изменения , а это вклад в легко поддерживаемый фреймворк и свой душевный покой.
——————————-
📱 TG-сообщество
📱 Обучение
📱 Отзывы
