Pull to refresh
5
0
Идальго Диас Николай @NikolayHD

Разработчик инфраструктуры автотестов

Send message

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

Таких планов не было, но идея интересная, подумаем.
В контексте некоторой глубины, при которой вопрос не риторический, не могли бы вы уточнить, чего много и некрасиво?
Не понял, это был риторический вопрос или что?
Что же, мы расходимся в оценке того, хороши или плохи некоторые настройки автоформатирования. Я нахожу те настройки, которые есть удовлетворительными. Я и сам мог бы указать на те или иные хотелки, которые сделаны не так, как мне хотелось бы больше всего, однако на всех сразу не угодишь. Во всяком случае, такого ужаса как вы привели выше

logger.error(
                    'Failed to decode subprocess output', with_exc=True,
                )


они не делают, это был просто кривой копипаст, в действительности бывает такое

logger.error(
    'Failed to decode subprocess output', with_exc=True,
)
Python элегантный язык, приятно изучать и пользоваться :)
Помимо Яндекс.Такси, мы используем testsuite при разработке некоторых сервисов Яндекс.Лавки. Основной потребитель всё ещё Яндекс.Такси, потому что именно в Такси разработали testsuite, мы изначально используем его для всех сервисов.
В самом деле, автоматически отформатированный код не так же приятен глазу, как тщательно продуманное ручное форматирование.

В данном случае по шкале Максимальная элегантность <----> Минимальное время, затраченное на форматирование сделано предпочтение в пользу скорости. Когда я добавляю новый код, мне это не нравится, но когда приходится вносить большие правки в чужой код, править кофликты слияний и т.п. то наоборот, нравится.

Когда над кодовой базой работают сотни людей, возможность отформатировать правки автоматически является решающей для того, чтобы разрешать конфликты с новыми правками быстрее, чем появляются новые.
И я правильно понимаю, что теперь и тем кто хочет использовать вашу балалайку везде надо будет забавляться с асинкоайо даже если оно им и не нужно?

Без async / await не обойтись в коде тестов. Если под везде подразумевается что-то ещё кроме кода тестов, то нет, не везде. В частности, сервис не обязан использовать async, а может вообще быть написан на другом языке, скажем C++.

В таком количестве как у вас оно не бывает оправданным. Магическое значение есть магическое значение

Я готов согласиться, что где-то магические строки / числа по коду не нужны, но, ещё раз, это верно не всегда. Часто бывает так, пишешь вначале тест с константами, получается лаконично, но сходу не понятно, что проверяется. Заменяешь константы на значения, и стало понятнее.

У вас доверительное тестирование чтоль? А если разработчик налажает в схеме и допустит ошибку?

Конечно нет, разработчик должен выписать ожидаемый в ответе json отдельно, но речь о другом. Мы не навязываем конкретный способ, которым это будет сделано. Можно просто сравнить dict в питоне, можно прикрутить фреймворк на ваш вкус.
Если уж вы его причесали форматером с дефолтными настройками, а судя по всему это было что-то вроде yapf -i -r yandex-taxi-testsuite/testsuite, то надо было хотя бы допустить размер строки до 120 символов, дабы не плодились попусту уродские переносы строк.

Мы форматируем код по pep8, с длиной строки в 79 символов.

Вот так делать нельзя в публичном коде, да и в обычном. Пролюбите строчку какую важную. Сделайте line.decode('utf-8', errors='replace') и удалите вон того Франкенштеина, что выше.

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

Из кода также надо вычистить всякие дефолты в ноль для значения портов (как это вообще возможно?) и отрефачить код.

0 означает, что операционная система выберет любой порт. Это стандартное значение для bind(2).
Проект забахан совсем недавно и одним коммитом => не ясна его дальнейшая судьба

Но как публичный проект — громоздкий, ...

Проект действительно enterprise, появился и развивается решая конкретные задачи. Это верно сейчас, это будет верно и в будущем, когда проект будет и декомпозирован, и почищен, и так далее, будем заниматься этим, обязательно.
Благодарю за подробный комментарий!

асинхронщина в тестах всегда должна быть оправдана. Зачем оно вам, и тем более, в демонстрационном примере для статьи?

Асинхронные обработчики нужны, например, чтобы моксервер отвечал на запросы, пока тест ожидает ответ сервиса, без асихнронности никак.

по коду куча констант и в том числе строковых. Magic number же?

Бывает, особенно часто в предусловиях и проверках, что код оказывается проще и понятнее, если не выделять константу.

очень много работы с относительными путями, что само по себе не айс

Согласен, но это необходимо написать только один раз. Обычно мы используем кодогенерацию и пути подставляются на этапе cmake.

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

Действительно, значительная часть кода ещё не покрыта аннотациями, это наследие тех времён, когда проект работал на python2.7/gevent. Мы постепенно добавляем аннотации в имеющийся код и используем их в новом.

* обычный assert очень не информативен — к нему в таких тестах надо либо подписывать сообщение, либо использовать какой-либо матчер вроде hamcrest

pytest патчит assert-ы таким образом, что к ним можно подключить свои собственные обработчики, получается довольно удобно.

Погодите! В начале же обещали, что тесты смогут «поднимать и наливать базу данных»

Сервис chat-backend не взаимодействует с базой, за это отвечает другой сервис, chat-storage-postgres, вот когда мы тестируем chat-storage-postgres, тогда и наливаем базу.

Погодите, так вы все таки умеете готовить докер и все работает через контейнеры? А как же «запускать в этом окружении тестируемый сервис». Так все таки все работает через контейнеры или в одном окружении? Из статьи крайне не ясно.

Действительно, testuite может поднимать базу самостоятельно и «запускать в этом окружении тестируемый сервис», а может воспользоваться и готовым окружением, в том числе поднятым в docker, что удобно в CI. Мы в Яндекс.Такси используем оба решения.

Не тянет тезисной описание на список фич фреймворка. Не очень понятно зачем он нужен как отдельная сущность, а не как горсть плагинов для пайтеста или как отдельный мок-сервис. Вообще, солянка какая-то: первый тезис описывает http-клиент, второй мок-сервис, в третьем все про тот же мок-сервис(?), всё что написано в четвёртом — можно сделать yield фикстурами пайтеста.

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

Вот тут надо уточнять, что вы вкладываете в эти понятия и почему неправильно.

Потому что они прендазначены для решения другого типа задач. Статья про testsuite, а не юнит тесты, поэтому здесь мы не будем углубляться.

Что это за чудо-переменная?

Тут есть несколько вариантов, как это обойти: можно передавать пути через аргументы, через переменные окружения или вычислять их на ходу. В данном случае мы добивались того, чтоб тесты запусальись без указания дополнительных параметров. PYTHON3 необходима для того, чтобы можно было запускать тесты в окружении отличном от окружения самого testsuite.

А в общем: согласен, что не очень красиво — поправим.

Во-первых, не массива, а списка. Во-вторых, крайне не рекомендую такой способ инициализации чего-либо, если допустимо использование с питоном версии меньшей чем 3,7.

В самом деле, list :)

В примере, вставленном в статью синтаксическая ошибка

Спасибо, исправили.

Я вас умоляю… Зачем пинать композ через мэйк?

С помощью make-файла мы показываем, как можно запустить нужные команды, мы не настаиваем на использование make.

Напрашивается валидация тела ответа через marshmallow.

Мы стремимся, насколько возможно, не навязывать пользователю выбор инструментов, поэтому testsuite предоставляет базовую функциональность. Поддержку валидации, скажем через marshmallow, можно добавить в своем проекте. Например, в Яндекс.Такси все ручки описаны с помощью yaml-схем, поэтому дополнительная валидация нам в этом месте не очень полезна.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity