Які існують популярні угоди про іменування для тестів одиниць? [зачинено]


203

Загальні

  • Дотримуйтесь однакових стандартів для всіх тестів.
  • Будьте зрозумілі, що таке кожен тестовий стан.
  • Будьте конкретні щодо очікуваної поведінки.

Приклади

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 ()

Інший

  • Кінцеві назви методів за допомогою тесту
  • Імена методу запуску з назвою класу

Відповіді:


94

Я майже з вами на цьому одному чоловікові. Використані угоди про іменування:

  • Ясно про те, що таке кожен тестовий стан.
  • Конкретно щодо очікуваної поведінки.

Що ще потрібно від тестового імені?

Всупереч відповіді Рея, я не думаю, що приставка тесту необхідна. Це тестовий код, ми це знаємо. Якщо вам потрібно зробити це для ідентифікації коду, у вас є більші проблеми, ваш тестовий код не повинен змішуватися з вашим виробничим кодом.

Що стосується довжини та використання підкреслення, його тестовий код , кого, до біса, хвилює? Лише ви та ваша команда побачать це, поки воно читабельне та зрозуміле, що робиться тест, продовжуйте! :)

Це сказало, я все ще досить новачка для тестування та ведення блогів своїх пригод з ним :)


20
Незначне протиріччя "до тих пір, поки воно читабельне і зрозуміле" та "кого ... хвилює". Добре, що всі хвилюються, коли це не зрозуміло та зрозуміло, тому це важливо. :-)
Давид Віктор

1
Ще один аргумент для префікса. Під час пошуку файлу в IDE ви можете легко шукати тестові справи, починаючи з Testімені вашого класу. Якщо назва класу та назва тестового класу однакові, нам завжди доведеться робити паузу та читати шлях двох файлів
ЦЕ ПОТРІБНИЙ ПОТРІБНО ДОПОМОГА

@THISUSERNEEDSHELP Я думаю, що ваш погляд можна легко подолати, маючи хорошу структуру папок, як src / libs & src / тести . Я знаю, що для деяких фреймворків тестового бігуна потрібен такий префікс, як тест для ідентифікації тестового коду, тому в цих випадках цього не уникнути, але для решти це може бути повторюваний не потрібний префікс.
negrotico19

@ negrotico19 Я думаю про випадок, як в IntelliJ, коли ви Search Everywhere(shift shift) або 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, а всі тести для 1 методу згруповані разом.


У будь-якому випадку мені подобається розділяти основні розділи назви тесту з підкресленнями, на відміну від кожного слова , тому що я думаю, що це полегшує читання і отримує точку тесту впоперек.

Іншими словами, мені подобається: Sum_ThrowsException_WhenNegativeNumberAs1stParamкраще, ніж Sum_Throws_Exception_When_Negative_Number_As_1st_Param.


22

Я називаю свої методи тестування, як інші методи, використовуючи "PascalCasing" без жодних підкреслень або роздільників. Я залишаю тест Postfix для методу, тому що він не додає значення. На те, що метод є тестовим методом, вказується атрибут TestMethod .

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

Через те, що кожен тестовий клас повинен протестувати лише один клас, а ім’я класу залишити поза назвою методу. Ім'я класу, який містить методи тестування, називається подібно до тестуваного класу з постфіксом "Тести".

[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: Тестові конвенції та рекомендації щодо найменування" Брайана Кука. Я вважав цю статтю дуже корисною.


1
+1 для посилання на мою публікацію - хоча в тестах використовувати префікс "Тест". Будьте впевнені, що ваші тести визначають очікувану поведінку. Наприклад, CanRetrieveProperCountWhenAddingMultipleItems ()
bryanbcook

2
Мені це не подобається, оскільки воно не включає очікувану поведінку
Йоханнес Рудольф

5

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

Я також схильний десь включати "Тест" або в ім'я функції, або в додаючу область імен або клас.


2
@Frank methodName = camelCase MethodName = PascalCase
Metro Smurf

@ metro-smurf: цікава відмінність, я жодного разу не чув термін PascalCase, який я вживав, і цим займаюся вже давно. Я бачу, що термін PascalCase з'являється в колах розробників Microsoft. Це ви робите?
Франк Щебер

Історія навколо паскальського кожуха та верблюжої кожухи (від: Бред Абрамс - blogs.msdn.com/brada/archive/2004/02/03/67024.aspx ) ... "У початковому дизайні Рамок ми мали сотні годин дискусія з приводу іменування стилю. Для полегшення цих дебатів ми створили ряд термінів. З Андерсом Хайльсбергом (оригінальним дизайнером Turbo Pascal) ключовим членом команди дизайнерів, не дивно, що ми обрали термін Pascal Casing для стилю корпусу популяризована мовою програмування Паскаля ".
Геліяк

-3

Поки ви дотримуєтесь однієї практики, це насправді не має значення. Як правило, я пишу тест на єдину одиницю для методу, який охоплює всі варіанти для методу (у мене є прості методи;), а потім пишу більш складні набори тестів для методів, які цього вимагають. Моя структура імен, таким чином, зазвичай є тестовою (перенесення від JUnit 3).


-8

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

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

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

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

Це схоже на інтерфейси, що називають конвенцію (я маю на увазі, ви не плутаєтесь із речами, що починаються з «Я», і не будете з «T»).

Просто складати з тестами або без них.

Теоретично це добре в будь-якому випадку і працює досить добре для невеликих проектів.


3
Цікавий підхід. Деякі люди можуть стверджувати, що префікс T суперечить умові, яку ви використовуєте в генеріках (наприклад, func (T1, T2, TResult)), але мене особисто не хвилює, якщо в команді є консенсус. Назви короткі, що також робить речі більш читабельними.
вжалений

Надто угорська (позначення) для мене. Крім того, у оголошеній заяві, префікс T використовується для загальних параметрів типу.
Денні Варод

Я погоджуюсь, угорська нотація була вилучена, і оскільки конфлікт із стандартними параметрами загального типу, я не бачу в цьому випадку виключення, що застосовується (як, наприклад, для інтерфейсів).
SonOfPirate
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.