Вопрос

Обычно, когда говорим о стандартах кодирования, мы ссылаемся на код самой программы, но как насчет модульных тестов? Существуют ли определенные рекомендации по стандартам кодирования, которые уникальны для модульных тестов? Кто они такие?

Это было полезно?

Решение

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

В методах испытаний на наименование я следую за шаблоном shouldDoSomethingWhenSomeConditionHolds.

Внутри теста обычно следовать следующему шаблону интервалов:

@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
    // Some lines 
    // of setup code
    // go here.

    // The action being tested happens after a blank line.

    // An assertion follows another blank line.
}

Некоторые настаивают только на одном утверждении за тест, но это далеко не универсально.

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

Другие советы

Рой Осгероув рекомендует следующую шаблон для названия ваших тестов:

NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior() 

Видеть http://weblogs.asp.net/rosherove/archive/2005/04/03/testnamingstandards.aspx

Главное, чтобы помнить, что модульные тесты по сути являются мини-спецификацией. Это означает, что акцент всегда должен быть на читабельности.

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

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

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

Я просто завершу несколько рекомендаций книги:

Тестовые шаблоны XUNIT: рефакторинг кода тестирования: Отличная книга, некоторые говорят, что это немного сухо, но я так не думаю. Вдается много деталей о множестве различных способов организации тестов и о том, как сохранить их поддержание. Актуально, если вы используете что -то вроде NUNIT и т. Д.

Искусство модульного тестирования: с примерами в .net: Лучшая книга о том, что он сбит с ума по написанию и поддержанию тестов. Несмотря на то, что я действительно новичок, я нахожу насмешливые секции уже немного устаревшими, поскольку синтаксис AAA теперь довольно стандартный, а не просто еще один способ сделать это.

Растущее объектно-ориентированное программное обеспечение, руководствовавшимся тестами: Эта книга просто потрясающая! Безусловно, самая лучшая книга для тестирования модуля и единственная продвинутая, которая проводит модульные тестирование в качестве гражданина первоклассного в процессе проектирования. Читал это, когда это была публичная бета -версия, и с тех пор рекомендовал. Отличный реальный проработанный пример, используемый на протяжении всей книги. Рекомендую сначала прочитать книгу Роя.

Не ставьте логику в свои модульные тесты. Например, допустим, вы тестируете метод добавления, у вас может быть что -то вроде этого:

void MyTest_SaysHello()
{
   string name = "Bob";
   string expected = string.Format("Hello, {0}", name);
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello(name);
   Assert.AreEqual(expected, actual);
}

В этом конкретном случае вы, вероятно, повторяете ту же логику, что и в тесте, поэтому вы по сути тестируете «1 + 1 == 1 + 1», а не «1 + 1 == 2», который является «Настоящий» тест. Так что вы бы действительно хотели, чтобы ваш тестовый код выглядел:

void MyTest_SaysHello()
{
   string expected = "Hello, Bob";
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello("Bob");
   Assert.AreEqual(expected, actual);
}

Длинные, описательные имена методов. Помните, что методы испытаний никогда не вызываются из кода (их называют модульным тестовым бегуном, который обнаруживает и вызывает их с помощью отражения), поэтому можно сходить с ума и иметь имена методов 50-80 символов. Конкретное соглашение об именах (верблюжье, подчеркивание, «должно», «должно», «когда», «дается» и т. Д.) Не очень важна, если имя отвечает на три вопроса:

  • Что находится под тестированием?
  • Какие условия?
  • Каков ожидаемый результат?

Методы испытаний должны быть короткими.

Методы испытаний должны иметь Простая линейная структура. Анкет Нет, если или петля конструкции.

Методы испытаний должны следовать Узор "Arrange-Act-Assert".

Каждый тест должен Проверьте одну вещь. Анкет Обычно это означает одно утверждение за тест. Тест как { Do A; Assert B; Assert C; } должно быть переработано на два: { Do A; Assert B; } а также { Do A; Assert C; }

Избегайте случайных данных или такие вещи, как 'datetime.now'

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

Даже если вы безжалостно устраняете дублирование в своем производственном коде, дублирование кода в тестовых приспособлениях гораздо меньше.

Несколько похоже на то, что уже упомянул Farmboy, формат названия моего метода

 <MethodName>Should<actionPerformed>When<Condition>

например

 GetBalanceShouldReturnAccountBalance() {
Лицензировано под: CC-BY-SA с атрибуция
scroll top