Лучшие практики именования модульных тестов [закрыто]

каковы наилучшие методы для именования классов модульных тестов и методов тестирования?

об этом шла речь на Поэтому, прежде чем, на Каковы некоторые популярные соглашения об именах для модульных тестов?

Я не знаю, очень ли это хороший подход, но в настоящее время в моих тестовых проектах у меня есть сопоставления один к одному между каждым производственным классом и тестовым классом, например Product и ProductTest.

в моих тестовых классах у меня тогда есть методы с имена методов, которые я тестирую, подчеркивание, а затем ситуация и то, что я ожидаю, например Save_ShouldThrowExceptionWithNullName().

12 ответов


мне нравится стратегия именования Роя Ошерова, это следующее:

[UnitOfWork_StateUnderTest_Expectedbehavior]

Он имеет всю необходимую информацию о имени метода и структурированным образом.

единица работы может быть как малые, как один метод, класс или как большой, как несколько классов. Он должен представлять все вещи, которые должны быть проверены в этом тестовом случае и находятся под контролем.

для сборки я использую типичный .Tests окончание, которое, я думаю, довольно распространено и то же самое для классов (заканчивая Tests):

[NameOfTheClassUnderTestTests]

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


Я люблю "следует" стандарт именования для тесты называя тест приспособление после испытываемого устройства (т. е. класса).

чтобы проиллюстрировать (используя C# и NUnit):

[TestFixture]
public class BankAccountTests
{
  [Test]
  public void Should_Increase_Balance_When_Deposit_Is_Made()
  {
     var bankAccount = new BankAccount();
     bankAccount.Deposit(100);
     Assert.That(bankAccount.Balance, Is.EqualTo(100));
  }
}

почему "следует"?

Я нахожу, что это заставляет тестовых авторов называть тест предложением по строкам " должен [быть в некотором состоянии] [после/До / когда] [действие принимает место]"

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

обновление:

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

обновление (4 года позже...)

для тех, кто заинтересован, мой подход к именованию тестов развивался на протяжении многих лет. Одна из проблем, с должны шаблон, который я описал выше, как его нелегко узнать с первого взгляда, какой метод тестируется. Для ООП я думаю, что имеет смысл начать имя теста с тестируемого метода. Для хорошо спроектированного класса это должно привести к читаемым именам методов тестирования. Теперь я использую формат, подобный <method>_Should<expected>_When<condition>. Очевидно, в зависимости от контекста может хотите заменить глаголы Should/When чем-то более подходящим. Образец: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()


Мне нравится этот стиль именования:

OrdersShouldBeCreated();
OrdersWithNoProductsShouldFail();

и так далее. Это действительно ясно для не-тестера, в чем проблема.


Кент Бек предлагает:

  • одно приспособление теста в "блок" (класс вашей программы). Тестовые светильники-это сами классы. Название испытательного приспособления должно быть:

    [name of your 'unit']Tests
    
  • тестовые случаи (методы приспособления теста) имеют имена как:

    test[feature being tested]
    

например, следующий класс:

class Person {
    int calculateAge() { ... }

    // other methods and properties
}

тестовая фикстура будет:

class PersonTests {

    testAgeCalculationWithNoBirthDate() { ... }

    // or

    testCalculateAge() { ... }
}

Имена Классов. Для имен тестовых приспособлений я нахожу ,что" тест " довольно распространен на вездесущем языке многих доменов. Например, в инженерной области:StressTest, а в косметическом домене:SkinTest. Извините, что не согласен с Кентом, но использование "Test" в моих тестовых светильниках (StressTestTest?) сбивает с толку.

"Unit" также используется много в доменах. Е. Г. MeasurementUnit. Класс называется MeasurementUnitTest испытание "измерения " или"MeasurementUnit"?

поэтому Мне нравится использовать префикс "Qa" для всех моих тестовых классов. Е. Г. QaSkinTest и QaMeasurementUnit. Его никогда не путают с объектами домена, и использование префикса, а не суффикса означает, что все тестовые светильники живут вместе визуально (полезно, если у вас есть подделки или другие классы поддержки в тестовом проекте)

пространства имен. Я работаю в C#, и я сохраняю свои тестовые классы в том же пространстве имен, что и класс, который они тестируют. Это удобнее, чем иметь отдельные тестовые пространства имен. Из конечно, тестовые классы находятся в другом проекте.

имена методов испытаний. Мне нравится называть свои методы WhenXXX_ExpectYYY. Это делает предварительное условие ясным и помогает с автоматизированной документацией (a la TestDox). Это похоже на советы по тестированию блога Google, но с большим разделением предварительных условий и ожиданий. Например:

WhenDivisorIsNonZero_ExpectDivisionResult
WhenDivisorIsZero_ExpectError
WhenInventoryIsBelowOrderQty_ExpectBackOrder
WhenInventoryIsAboveOrderQty_ExpectReducedInventory

посмотреть: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html

для имен методов тестирования я лично считаю, что использование подробных и само документированных имен очень полезно (наряду с комментариями Javadoc, которые далее объясняют, что делает тест).


недавно я придумал следующее Соглашение для именования моих тестов, их классов и содержащих проектов, чтобы максимизировать их дескриптивы:

допустим, я тестирую настройки класс в проекте в MyApp.Сериализация пространство имен.

сначала я создам тестовый проект с помощью MyApp.Сериализация.Тесты пространство имен.

в рамках этого проекта и конечно пространство я создам класс IfSettings (сохранено как IfSettings.цезий.)

допустим, я тестирую SaveStrings () метод. - >Я назову тест CanSaveStrings ().

когда я запускаю этот тест покажет следующий заголовок:

MyApp.Сериализация.Тесты.IfSettings.CanSaveStrings

Я думаю, что это говорит мне очень хорошо, что это тестирование.

конечно, полезно, что на английском языке существительное " тесты "совпадает с глаголом"тесты".

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

обычно Testnames придется начинать с глагола.

примеры:

  • обнаруживает (например, DetectsInvalidUserInput)
  • Броски (например, ThrowsOnNotFound)
  • воли (напр. WillCloseTheDatabaseAfterTheTransaction)

etc.

другой вариант-использовать "это "вместо"Если".

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

[редактировать]

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

кроме того, теперь я использую-только для методов в моих тестовых классах, поскольку это не считается лучшей практикой нигде - " _ " для разделения слов в именах моих тестовых методов, как в:

  • [Test] public void detects_invalid_User_Input() *

Я считаю, что это легче читать.

[Редактирование]

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


Я использую Дано-Когда-То концепции. Взгляните на эту короткую статью http://cakebaker.42dh.com/2009/05/28/given-when-then/. Статья описывает это понятие в терминах BDD, но вы можете использовать его и в TDD без каких-либо изменений.


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


в VS + NUnit я обычно создаю папки в своем проекте, чтобы сгруппировать функциональные тесты вместе. Затем я создаю классы приспособлений модульного теста и называю их после типа функциональности, которую я тестирую. Методы [Test] называются по строкам Can_add_user_to_domain:

- MyUnitTestProject   
  + FTPServerTests <- Folder
   + UserManagerTests <- Test Fixture Class
     - Can_add_user_to_domain  <- Test methods
     - Can_delete_user_from_domain
     - Can_reset_password

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

Мне лично нравятся лучшие практики, описанные в "JUnit Карманный Гид" ... трудно превзойти книгу, написанную соавтором JUnit!


имя тестового набора для класса Foo должно быть FooTestCase или что - то вроде него (FooIntegrationTestCase или FooAcceptanceTestCase) - поскольку это тестовый случай. см.http://xunitpatterns.com/ для некоторых стандартных именуя конвенций как тест, тестовый случай, приспособление теста, метод теста, ЕТК.