Каковы некоторые популярные соглашения об именах для модульных тестов? [закрыто]

204

Общее

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

Примеры

1) MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

Источник: Стандарты именования для модульных тестов.

2) Разделение каждого слова подчеркиванием

Public void Sum_Negative_Number_As_1st_Param_Exception_Thrown() 

Public void Sum_Negative_Number_As_2nd_Param_Exception_Thrown () 

Public void Sum_Simple_Values_Calculated ()

Другой

  • Завершить имена методов с помощью Test
  • Начать имена методов с имени класса
ужалены
источник

Ответы:

94

Я в значительной степени с тобой в этом одном человеке. Соглашения об именах, которые вы использовали:

  • Понятно, что такое каждое тестовое состояние.
  • Конкретно об ожидаемом поведении.

Что еще нужно от имени теста?

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

Что касается длины и использования подчеркивания, его тестового кода , кого это волнует? Только вы и ваша команда увидите это, пока оно читаемо и ясно показывает, что делает тест, продолжайте! :)

Тем не менее, я все еще довольно новичок в тестировании и ведении блогов моих приключений с ним :)

Роб Купер
источник
20
Незначительное противоречие «до тех пор, пока оно читабельно и понятно» и «кому ... все равно». Ну, все заботятся, когда они не читаемы и не понятны, вот почему это важно. :-)
Дэвид Виктор
1
Еще один дополнительный аргумент для префикса. Когда вы ищете файл в IDE, вы можете легко искать тестовые случаи, начиная с имени Testвашего класса. Если имя класса и имя тестового класса совпадают, нам всегда придется останавливаться и читать путь к двум файлам
ЭТОМУ ПОЛЬЗОВАТЕЛЮ НУЖНА ПОМОЩЬ
@THISUSERNEEDSHELP Я думаю, что ваша точка зрения может быть легко преодолена с помощью хорошей структуры папок, такой как src / libs & src / tests . Я знаю, что для некоторых сред выполнения тестов требуется такой префикс, как test для идентификации тестового кода, поэтому в таких случаях этого не избежать, но в остальном это может быть повторяющийся префикс без необходимости .
negrotico19
@ negrotico19 Я имею в виду случай, как в IntelliJ, когда вы Search Everywhere(сдвиг сдвиг) или Find a Class By Name(CMD O). Я понимаю, что он будет дифференцироваться либо по структуре папок, либо по структуре модулей, но когда мы что-то ищем, мы уже знаем, что хотим искать. Например, если я ищу тест, я хочу ограничить свой поиск, testа затем искать имя, а не искать имя, а затем отфильтровать тест вручную. Это небольшое различие, но гораздо проще «проверить [имя класса]», и у него есть только одно всплывающее окно и уменьшить умственную нагрузку
ЭТОМУ ПОЛЬЗОВАТЕЛЮ НУЖНА ПОМОЩЬ
37

Это также стоит прочитать: Структурирование модульных тестов

Структура имеет тестовый класс для каждого тестируемого класса. Это не так необычно. Но для меня было необычным то, что у него был вложенный класс для каждого тестируемого метода.

например

using Xunit;

public class TitleizerFacts
{
    public class TheTitleizerMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void Name_AppendsTitle()
        {
            // Test code
        }
    }

    public class TheKnightifyMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void MaleNames_AppendsSir()
        {
            // Test code
        }

        [Fact]
        public void FemaleNames_AppendsDame()
        {
            // Test code
        }
    }
}

И вот почему:

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

Мне также нравится этот подход:

MethodName_StateUnderTest_ExpectedBehavior

Так что, возможно, приспособиться к:

StateUnderTest_ExpectedBehavior

Потому что каждый тест уже будет во вложенном классе

Люцифер
источник
2
Для тех, кто использовал тестер Resharper в Visual Studio, они исправляли ошибки, используя вложенные тестовые классы в 8.x. С тех пор это стало моей любимой структурой.
angularsen
Имеет ли значение, что имя становится действительно длинным с подходом MethodName_StateUnderTest_ExpectedBehavior? Например, «InitializeApiConfiguration_MissingApiKey_IllegalArgumentException». Это действительно хорошее название теста?
портфолио
28

Я склонен использовать соглашение, MethodName_DoesWhat_WhenTheseConditionsнапример, так:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

Тем не менее, я вижу, что название теста должно соответствовать структуре модульного тестирования:

  • организовать
  • акт
  • Утверждай

Что также соответствует синтаксису BDD / Gherkin:

  • Дано
  • когда
  • затем

который будет называть тест в виде: UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

Итак, к вашему примеру:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

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


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

Другими словами, мне нравится: Sum_ThrowsException_WhenNegativeNumberAs1stParamлучше чем Sum_Throws_Exception_When_Negative_Number_As_1st_Param.

CodingWithSpike
источник
22

Я называю свои методы тестирования, как и другие методы, использующие «PascalCasing» без подчеркивания или разделителей. Я оставляю постфиксный Test для метода, потому что он не добавляет никакой ценности. То, что метод является тестовым, указывается атрибутом TestMethod .

[TestMethod]
public void CanCountAllItems() {
  // Test the total count of items in collection.
}

В связи с тем, что каждый класс Test должен тестировать только один другой класс, я оставляю имя класса вне имени метода. Имя класса, содержащего тестовые методы, называется как тестируемый класс с постфиксом «Тесты».

[TestClass]
public class SuperCollectionTests(){
    // Any test methods that test the class SuperCollection
}

Для методов, которые проверяют исключения или действия, которые невозможны, я ставлю префикс метода теста со словом Cannot .

[TestMethod]
[ExpectedException(typeOf(ArgumentException))]
public void CannotAddSameObjectAgain() {
  // Cannot add the same object again to the collection.
}

Мое соглашение о присвоении имен основано на статье Брайана Кука «Советы TDD: условные обозначения и правила тестирования» . Я нашел эту статью очень полезной.

Jehof
источник
1
+1 за ссылку на мой пост - хотя нет необходимости использовать префикс «Тест» в своих тестах. Убедитесь, что ваши тесты определяют ожидаемое поведение. Например, CanRetrieveProperCountWhenAddingMultipleItems ()
bryanbcook
2
Мне это не нравится, потому что оно не включает ожидаемое поведение
Йоханнес Рудольф
5

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

Я также склонен включать «Test» где-нибудь, либо в имя функции, либо в пространство имен или класс.

Фрэнк Щерба
источник
2
@Frank methodName = camelCase MethodName = PascalCase
Метро Smurf
@ metro-smurf: интересное различие, я никогда не слышал термин, который использовал PascalCase, и я делал это в течение долгого времени. Я вижу только термин PascalCase, встречающийся в кругах разработчиков Microsoft, это то, что вы делаете?
Франк Щерба
История вокруг Pascal Casing и Camel Casing (от: Брэд Абрамс - blogs.msdn.com/brada/archive/2004/02/03/67024.aspx ) ... "В первоначальном дизайне Framework у нас были сотни часов дебаты о стиле именования. Чтобы облегчить эти дебаты, мы создали несколько терминов. Поскольку Андерс Хейлсберг (оригинальный дизайнер Turbo Pascal) является ключевым членом команды разработчиков, неудивительно, что мы выбрали термин Pascal Casing для стиля оболочки. популяризируется языком программирования Pascal. "
Heliac
-3

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

Мангер
источник
-8

Я использую префикс 'T' для тестовых пространств имен, классов и методов.

Я стараюсь быть аккуратным и создаю папки, которые копируют пространства имен, затем создаю папку тестов или отдельный проект для тестов и копирую производственную структуру для основных тестов:

AProj
   Objects
      AnObj
         AProp
   Misc
      Functions
         AFunc
   Tests
      TObjects
         TAnObj
            TAnObjsAreEqualUnderCondition
      TMisc
         TFunctions
            TFuncBehavesUnderCondition

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

Это выглядит так же, как соглашение об именах интерфейсов (я имею в виду, что вы не путаетесь с вещами, начинающимися с «I», и не будете с «T»).

Легко просто скомпилировать с тестами или без них.

В любом случае, это хорошо в теории, и хорошо работает для небольших проектов.

user566399
источник
3
Интересный подход. Некоторые люди могут утверждать, что префикс T конфликтует с соглашением, которое вы используете в обобщениях (например, func (T1, T2, TResult)), но мне лично все равно, пока в команде есть консенсус. Имена короткие, что делает вещи более читабельными.
ужалено
Слишком венгерский (обозначение) для меня. Кроме того, как заявлено в объявлении, префикс T используется для параметров универсального типа.
Дэнни Варод
Я согласен, венгерская нотация была ограничена и из-за конфликта со стандартными параметрами универсального типа я не вижу исключения, применяемого в этом случае (как, например, для интерфейсов).
SonOfPirate