Написание стандартов для модульного тестирования
Я планирую ввести набор стандартов для написания модульных тестов в моей команде. Но что включать?
Эти два сообщения (Unit test название лучших методов и Рекомендации по зависимостям файловой системы в тестах unit/integration) уже дали мне пищу для размышлений.
Другими доменами, которые должны быть охвачены в моих стандартах, должно быть то, как настроены тестовые классы и как их организовать. Например, если у вас есть класс под названием OrderLineProcessor, должен быть класс проверки, называемый OrderLineProcessorTest. Если в этом классе есть метод, называемый Process(), тогда должен быть тест под названием ProcessTest (возможно, больше для тестирования разных состояний).
Любые другие вещи, которые нужно включить?
Есть ли у вашей компании стандарты для модульного тестирования?
EDIT: я использую Visual Studio Team System 2008, и я развиваюсь в С#.Net
Ответы
Ответ 1
Посмотрите Michael Feathers на то, что является unit test (или что делает модульные тесты плохими модульными тестами)
Взгляните на идею "Arrange, Act, Assert", то есть идею о том, что тест выполняет только три вещи в фиксированном порядке:
- Упорядочить любые входные данные и классы обработки, необходимые для тестирования
- Выполните тестирование
- Проверьте результаты с помощью одного или нескольких утверждений. Да, это может быть несколько утверждений, если они все работают, чтобы проверить действие, которое было выполнено.
Посмотрите Behavior Driven Development, чтобы выровнять тестовые примеры с требованиями.
Кроме того, сегодня мое мнение о стандартных документах заключается в том, что вы не должны писать их, если только вам не приходится - есть много доступных ресурсов, уже написанных. Ссылка на них, а не переосмысление их содержания. Предоставьте список чтения для разработчиков, которые хотят узнать больше.
Ответ 2
Вероятно, вам стоит взглянуть на серию "Прагматическое тестирование единицы измерения". Это версия С#, но для Java есть еще одна.
Что касается вашей спецификации, я бы не пошел за борт. У вас очень хорошее начало - соглашения об именах очень важны. Мы также требуем, чтобы структура каталогов соответствовала исходному проекту. Охват также должен распространяться на граничные случаи и незаконные значения (проверка на исключения). Это очевидно, но ваша спецификация - это место, где можно записать этот аргумент, который вы неизбежно будете иметь в будущем с парнем, который не хочет проверять, что кто-то пропустил незаконную ценность. Но не делайте спецификацию более чем на несколько страниц, или никто не будет использовать ее для задачи, которая так зависит от контекста.
Обновление: я не согласен с г-ном Картофельным руководителем только по одному утверждению за Unit Test. Это теоретически звучит довольно хорошо, но на практике это приводит либо к нагрузкам в основном избыточных тестов, либо к людям, выполняющим тонны работы в настройке и срыве, которые сами должны быть протестированы.
Ответ 3
Я следую стилю BDD TDD. Видеть:
http://blog.daveastels.com/files/BDD_Intro.pdf
http://dannorth.net/introducing-bdd
http://behaviour-driven.org/Introduction
Короче говоря, это означает, что
-
Тесты не рассматриваются как "тесты", а как характеристики поведения системы (далее называются "спецификациями" ). Целью спецификаций является не проверка того, что система работает при любых обстоятельствах. Их цель - указать поведение и управлять дизайном системы.
-
Названия методов спецификации написаны как полные английские предложения. Например, спецификации для шара могут включать в себя "шар круглый" и "когда мяч попадает на пол, тогда он отскакивает".
-
Не существует принудительной связи 1:1 между производственными классами и классами спецификаций (и создание тестового метода для каждого метода производства будет безумным). Вместо этого существует соотношение 1:1 между поведением системы и спецификациями.
Некоторое время назад я написал учебник TDD (где вы начинаете писать игру Tetris с помощью предоставленных тестов), который показывает этот стиль написания тестов как спецификации. Вы можете загрузить его из http://www.orfjackal.net/tdd-tutorial/tdd-tutorial_2008-09-04.zip Инструкции о том, как делать TDD/BDD, по-прежнему отсутствуют в этом учебнике, но код примера готов, поэтому вы можете увидеть, как организованы тесты и записать код, который их передает.
Вы заметите, что в этом уроке производственные классы называются такими, как Board, Block, Piece и Tetrominoe, которые сосредоточены вокруг концепций игры Tetris. Но тестовые классы сосредоточены вокруг поведения игры Tetris: FallingBlocksTest, RotatingPiecesOfBlocksTest, RotatingTetrominoesTest, FallingPiecesTest, MovingAFallingPieceTest, RotatingAFallingPieceTest и т.д.
Ответ 4
- Попытайтесь использовать как можно меньше утверждений для каждого тестового метода. Это гарантирует, что цель теста хорошо определена.
- Я знаю, что это будет противоречиво, но не проверяйте компилятор - время, потраченное на тестирование Java Bean, аксессоры и мутаторы лучше потратить на другие тесты.
- Попробуйте, где возможно, использовать TDD вместо написания ваших тестов после вашего кода.
Ответ 5
Я обнаружил, что большинство тестовых соглашений можно применять с помощью стандартного базового класса для всех ваших тестов. Принуждение тестера переопределить методы, чтобы все они имели одинаковое имя.
Я также выступаю за Arrange-Act-Assert (AAA) стиль тестирования, так как вы можете создать довольно полезную документацию из своих тестов. Это также заставляет вас подумать о том, какое поведение вы ожидаете из-за стиля именования.
Ответ 6
Еще один элемент, который вы можете добавить в свои стандарты, - это попытаться сохранить размер unit test маленьким. Это сами методы тестирования. Если вы не выполняете полную интеграцию unit test, обычно нет необходимости в больших модульных тестах, например, более 100 строк. Я дам вам это на всякий случай, если у вас будет много настроек, чтобы добраться до вашего теста. Однако, если вы это сделаете, вы должны его реорганизовать.
Люди также говорят о рефакторинге кода, чтобы убедиться, что люди понимают, что модульные тесты тоже являются кодом. Так рефакторинг, рефакторинг, рефакторинг.
Я нахожу, что самая большая проблема в использовании, которую я видел, заключается в том, что люди не склонны распознавать, что вы хотите, чтобы ваши модульные тесты были легкими и проворными. В конце концов, вы не хотите монолитного зверя для своих тестов. Имея это в виду, если у вас есть метод, который вы пытаетесь проверить, вы не должны проверять все возможные пути в одном unit test. Вы должны иметь несколько модульных тестов для учета всех возможных путей метода.
Да, если вы правильно выполняете свои модульные тесты, вы должны в среднем иметь больше строк кода unit test, чем ваше приложение. Хотя это звучит как большая работа, это сэкономит вам много времени, в конце концов, когда придет время для неизбежного изменения бизнес-требований.
Ответ 7
Пользователи полнофункциональной среды IDE обнаруживают, что "некоторые из них" имеют довольно подробную поддержку для создания тестов в определенном шаблоне. Учитывая этот класс:
public class MyService {
public String method1(){
return "";
}
public void method2(){
}
public void method3HasAlongName(){
}
}
Когда я нажимаю ctrl-shift-T в intellij IDEA, я получаю этот тестовый класс после ответа на 1 диалоговое окно:
public class MyServiceTest {
@Test
public void testMethod1() {
// Add your code here
}
@Test
public void testMethod2() {
// Add your code here
}
@Test
public void testMethod3HasAlongName() {
// Add your code here
}
}
Таким образом, вы можете внимательно изучить поддержку инструмента, прежде чем писать свои стандарты.
Ответ 8
Я использую почти простой английский для имен функций unit test. Помогает определить, что они делают точно:
TEST( TestThatVariableFooDoesNotOverflowWhenCalledRecursively )
{
/* do test */
}
Я использую С++, но соглашение об именах можно использовать где угодно.
Ответ 9
Обязательно укажите, что не является модульным тестом. См. Что не следует проверять, когда дело доходит до тестирования модулей?
Включите руководство, чтобы тесты интеграции были четко идентифицированы и могут выполняться отдельно от модульных тестов. Это важно, потому что вы можете завершить набор "единичных" тестов, которые очень медленны, если модульные тесты смешиваются с другими типами тестов.
Проверьте это для получения дополнительной информации об этом: Как я могу улучшить свои тесты junit... особенно второе обновление.
Ответ 10
Если вы используете инструменты из семейства Junit (OCunit, SHunit,...), имена тестов уже следуют некоторым правилам.
Для своих тестов я использую пользовательские теги doxygen, чтобы собрать их документацию на определенной странице.