1) Да, это определенно плохая практика, если тесты зависят друг от друга.
Модульный тест должен быть построен таким образом, чтобы в случае неудачи он сразу указывал на определенную область в вашем коде.Хорошие юнит-тесты уменьшат время, затрачиваемое на отладку.Если тесты зависят друг от друга, вы потеряете это преимущество, потому что вы не можете определить, какая ошибка в вашем коде сделала тест неудачным.Кроме того, это кошмар обслуживания.Что если что-то изменится в вашем «общем тесте», то вам придется изменить все зависимые тесты.
Здесь вы можете найти несколько хороших советов о том, как решать проблемы взаимодействующих тестов (вся книга шаблонов тестов xUnit обязательна к прочтению!)
2) Модульное тестирование - это тестирование наименьшего возможного.
Допустим, у вас есть будильник (код C #):
public class AlarmClock
{
public AlarmClock()
{
SatelliteSyncService = new SatelliteSyncService();
HardwareClient = new HardwareClient();
}
public void Execute()
{
HardwareClient.DisplayTime = SatelliteSyncService.GetTime();
// Check for active alarms
// ....
}
}
Это не проверяется.Вам понадобится реальное спутниковое соединение и аппаратный клиент, чтобы проверить, установлено ли правильное время.
Следующее, однако, позволит вам издеваться над hardwareClient и satelliteSyncService.
public AlarmClock(IHardwareClient hardwareClient, ISatelliteSyncService satelliteSyncService)
{
SatelliteSyncService = satelliteSyncService;
HardwareClient = hardwareClient;
}
Однако вы никогда не должны высмеивать объект, который вы на самом деле тестируете (звучит логично, но иногда я вижу, что это происходит).
Итак, как далеко вы должны идти с насмешкой.Вы должны издеваться над всем, от чего зависит ваш класс тестирования.Таким образом, вы можете проверить свой класс в полной изоляции.И вы можете контролировать результат ваших зависимостей, чтобы вы могли убедиться, что ваша SUT будет проходить через все пути кода.
Например, пусть SatelliteSyncService
сгенерирует исключение, пусть вернет недопустимое время и выключитКонечно, пусть он вернет правильное время, а затем в определенные моменты, чтобы вы могли проверить, активирован ли ваш будильник в нужный момент.
Для создания ваших тестовых данных маршрута.Подумайте об использовании Builder Pattern. Это поможет вам установить только то, что требуется для успешного прохождения теста.Это сделает ваши тесты более выразительными и их будет легче читать другим.Это также снизит уровень обслуживания вашего теста, поскольку у вас меньше зависимостей.
Я написал сообщение в блоге о модульном тестировании, которое расширяет идеи, упомянутые здесь.Для объяснения понятий используется C #, но он применим ко всем языкам.