Как стать автором
Обновить

Комментарии 31

Странно, но по картинке с котиками я подумал что пост будет от компании Badoo.
от компании котиков :))
У меня подобные изображения однозначно ассоциируются с задачей об обедающих философах.
НЛО прилетело и опубликовало эту надпись здесь
Вариант с Jenkins у вас не рассматривался?
Когда начали разрабатывать пускалку уже была развитая инфраструктура с использованием TeamCity — так что изобретать велосипед не стали.

Будем делать OpenSource — вполне вероятно, добавим модули и для Jenkins, если будет спрос (:
спрос реально есть
Судя по всему, это и будет первым доп. модулем)
С полгода назад выполнял задачу распределения юнит тестов в связке Jenkins+NAnt+.NET+NUnit
Решил не заморачиваться и разбил всю пачку на n категорий, и запускал тесты одной категории в один поток.
было — порядка 10000 тестов за 70 минут на одной машине в один поток.
стало — 10000 тестов за10-15 минут на трех машинах в два потока на каждой.
Вероятность, что новый тест не попадёт ни в одну категорию и не будет запускаться у вас отсутствует?
Для этого был предусмотрен отдельный поток — запуск всех тестов не входящих ни в одну из категорий. И в момент, когда выполнение этой пачки начинает занимать время, сравнимое с выполнением категории — можно запросто из них создать новую категорию. Поддерживая таким образом общее время выполнения в рамках допустимого.
Вы не пробовали приспособить для этого билдовую систему Waf (https://code.google.com/p/waf/)? Она хоть и называется билдовой системой, но билды — это скорее побочный продукт ее функциональности.
Задачей всё-таки было ускорить прохождение тестов, не вылезая из имеющейся инфраструктуры. Возможно, другие инструменты могли бы улучшить результат, но перекраивать имеющуюся мощную систему контроля качества только ради пускалки в наших планах не было
А ваша пускалка разве не отдельная программа/скрипт? Какая разница в данном месте какой скрипт юзать?
У нас уже использовалась билдовая система Ant (как я понимаю, Waf как раз его аналог), и его функционала вполне хватало — зачем использовать что-то дополнительно?
Ладно, я понял, что не совсем понятно объяснил суть. Я не предлагал вам менять что-то в вашей инфраструктуре, я предлагал посмотреть на Waf как на вашу пускалку тестов и только.

Кстати вопрос, я может не нашел, но на чем написана ваша утилитка?
Спасибо, теперь понял (: На самом деле, не натыкались на такую идею в процессе поиска решения — возможно, в противном случае всё могло пойти по-другому.

В принципе, большая часть трудов ушла именно на разработку системы сбора/хранения/использования статистики и распределения тестов по потокам — она ведь нигде и никак не реализована. А уж что использовать, чтобы запускать полученные потоки, уже дело отдельное — и это не такая большая работа, чтоб не написать это самому со 100% соответствиям потребностям системы.

Утилитка написана на PHP (:
Очень круто. Множество коллег, с которыми я общался, не хотели пользоваться тестами как раз из-за времени выполнения. Ну и из-за необходимости их писать, понятное дело.
Мы для .NET тестов написали приблуду, которая из тестовых проектов строит список тестовых классов и запускает параллельно копии консоля от nunit. Никак не доходят руки до реализации простейшего балансировщика.
Если кто посоветует готовое решение, мы бы велосипед не изобретали
Спасибо.
Вот если бы в интернете было какое-нибудь общедоступное и более-менее универсальное решение, то нам бы не пришлось разрабатывать вышеописаный велосипед с моторчиком (:
так что ждать nunit 3 с надеждой или загрузить новичка на работе. у нас вся эта программка писалось понемногу каждым новым «студентом» :)
Так это же доклад с ритконфа!
Каюсь, о пускалке рассказывал уже там, но тут подробнее и конструктивнее (:
юнит-тесты, если верить книжкам, НИКОГДА не должны выходить за пределы тестируемого класса, а ещё лучше ― тестируемого метода. Но много ли вы видели таких тестов?

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

Если у вас 17 тысяч тестов это не нормально — таких сложных продуктов не должно быть — необходимо разбить его на отдельные модули и работать с многоуровневым тестированием.

В общем описанные в посте проблемы решаются обычно другими способами.
Всё зависит от величины проекта. На тысячу строк 17 тысяч тестов может и перебор, но вот на миллион я бы сказал, что маловато.

И полностью изолировать тест класса и ли метода от других классов или методов редко представляется возможным малой кровью. Даже банальный сеттер setOwner(User $user) для какой-нибудь сущности требует создание экземпляра User стандартным способом (через new) или через какую-то фабрику типа loadUser, а значит о полной изоляции говорить нельзя, конструктор или фабрика тоже могут содержать ошибки и в своем тесте мы их неявно тестируем хотя бы на отсутствие fatal error. Использование моков, интерфейсов и т. п. лишь способ увеличить изоляцию, но не сделать её абсолютной — ошибки могут быть даже в интерфейсах.
В таком случае незачем писать модульные тесты, если вы не можете архитектурно подготовить к этому систему. Существует большое количество других типов тестов.

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

Всё зависит от величины проекта. На тысячу строк 17 тысяч тестов может и перебор, но вот на миллион я бы сказал, что маловато.
Ничего не маловато — у меня были проекты более чем на миллион строк кода и хватило меньшего количества тестов при почти стопроцентном покрытии.
Вопрос в количестве бизнес логики которую имеет смысл тестировать. Логика специфичная для проекта на миллион строк кода? Это очень много. Я говорю о том, что имеет смысл разбить такой проект на отдельные проекты. Это как минимум. А вообще скорее всего поэтапно выделять модули, удалять их и заменять внешними решениями.
В реальности до описанного вами сценария дойти не должно — наверняка вы могли свернуть с этой дороги где то в другом месте. И текущая ситуация вызвана другой болезнью. И лечить надо ее а не симптомы.

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

Во-первых, система могла достаться в наследство вообще без тестов и для рефакторинга ею нужно покрыть тестами. Во-вторых, тесты именно, что модульные, а не «классовые» или «методные», тестируется именно модуль, какая-то логически законченная часть приложения, а не вырванный из контекста класс или метод.
Да — моки и интерфейсы позволяют сделать изоляцию абсолютной.

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

Кто сказал, что нужно тестировать только бизнес-логику?
Несмотря на то, что моя позиция не совпадает с вашей — это не повод сливать мне карму.

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

во вторых, тесты именно, что модульные
Вероятно у нас просто разная терминология.
Тесты делят на 3 типа по объему охвата. Модульные для тестирования модулей приложения, интеграционные для тестирования модулей в связке и системные для тестирования приложения как черного ящика.
В реальности под модульными тестами обычно понимают именно тестирование методов и классов.
Чем более низкий уровень тестирования используется на проекте — тем они дороже.
То есть если вы работаете с унаследованной архитектурой — модульные тесты наверняка не окупятся. Могут окупится некоторые интеграционные тесты, но каждую ситуацию стоит рассматривать отдельно.
Тут обычно нужны системные авто тесты или хорошо построенный процесс ручного тестирования. После этого можно будет опираясь на них провести архитектурный рефакторинг и подготовить систему к модульным тестам. Если приложение не будет эволюционировать дальше, то даже это может быть слишком дорогой мерой.

Если мы говорим о системных тестах — то 17 тысяч тестов это очень много — это может быть только для систем с очень сложным бизнесом. Чаще всего требования к продукту тоже можно упростить или забить на их часть менее важную для заказчика (то есть не тестировать эту часть).

Одним словом — с ситуацией у автора что то не чисто. Он ни словом не обмолвился о многоуровневом тестировании. Я видел проекты, в которых вместо организации тестирования как такового увлекались модульными тестами, которые писали тестировщики после написания кода. Это жалкое зрелище. Модульные тесты это все таки не тестирование — а часть девелопмента. Моя мысль сводится к тому, что может и предложенный инструмент хорош. Но в проектах ситуация требующая его применения возникнуть не должна. И вероятно стоит что то другое менять в проекте если к такому пришли.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий