Совместное использование устройства для тестирования - PullRequest
6 голосов
/ 16 августа 2011

Я пишу модульные тесты для проекта (написанного на PHP с использованием PHPUnit), в котором вся его среда (загруженные компоненты, события, конфигурация, кэш, отдельные среды и т. Д.) Содержится в объекте, в котором все компоненты использовать для взаимодействия друг с другом (с использованием шаблона посредника).

Чтобы ускорить выполнение модульных тестов, я делюсь объектом среды и некоторыми другими объектами (например, в моем тестовом примере для объекта представления [как в V MVC], объект менеджера представления [который действует как фабрика для объектов представления и отвечает за фактическое отображение]) среди тестов в одном и том же тестовом примере (используя setUpBeforeClass() и статические свойства PHPUnit).

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

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

Что ты думаешь? Можете ли вы определить какие-либо недостатки, чтобы я убедил себя в том, что стоит больше времени выполнения? Или я просто чрезмерно реагирую, и это совершенно нормально?

Ответы [ 3 ]

5 голосов
/ 16 августа 2011

Я разделяю ваши чувства, поэтому, возможно, я просто изложу свои цели и свое решение, когда столкнулся с этой проблемой:

  • У разработчиков должен быть набор тестов, который работает очень быстро
  • По крайней мере, одиночные тесты должны выполняться менее чем за секунду
  • Я действительно хочу убедиться, что у меня нет взаимозависимостей в моих тестовых примерах

Я предполагаю, что у вас запущен сервер непрерывной интеграции. Если не cronjob может сделать, но рассмотрите возможность настройки Дженкинс , это действительно очень просто .


Для обычного использования:

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

Я бы предложил вспомогательные методы getFoo() { if(!self::$foo) .... create ... return $foo;} сверх setUpBeforeClass, потому что это может облегчить совместное использование, но в основном из-за следующего пункта.

Один раз за ночь:

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

Это может работать 6 часов (отключите покрытие кода для этого!), Но как это заботится. Ваши приборы будут воссозданы для каждого теста, поскольку это новый процесс php, а статические переменные не существуют.


Используя этот способ, вы можете быть уверены, что не создали зависимых один раз в день. Это достаточно хорошо, чтобы вспомнить, что вы сделали (и вы можете запустить с помощью --filter и --process-изоляция, если вам нужно что-то исправить).

2 голосов
/ 27 августа 2011

Как и при написании «нормального» кода, когда вы пишете тестовые случаи, хорошо полагаться на знание того, как работают объекты фикстуры.

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

Это помогает помнить о ключевой цели написания модульных тестов.Вы хотите через 5-10 минут узнать, сломали ли вы сборку.Таким образом, вы можете пойти на обед, пойти на встречу, домой и т. Д. После того, как вы получите «все ясно».Если вы знаете, что некоторую часть прибора можно использовать повторно, не создавая взаимодействия, вам следует использовать эти знания, чтобы сделать свои тесты еще более всеобъемлющими в течение этого 5-10-минутного окна.Я понимаю пуристический импульс здесь, но он ничего не покупает с точки зрения независимости теста и неоправданно ограничивает то, что ваш набор тестов сделает для вас.

1 голос
/ 27 августа 2011

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

Пусть тесты будут выполняться быстро, и когда будет обнаружена ошибка (которая неизбежна при интеграционном тестировании), у вас есть причина потратить время на локализацию одного конкретного теста или набора тестов. Если у вас есть инструментарий, который работает для общего случая, я бы оставил его как есть.

...