Каковы лучшие практики для именования классов юнит-тестов и методов тестирования?
Это обсуждалось на SO ранее, в Каковы некоторые популярные соглашения об именах для модульных тестов?
Я не знаю, является ли это очень хорошим подходом, но в настоящее время в моих проектах тестирования у меня есть взаимно-однозначные сопоставления между каждым рабочим классом и классом тестирования, например, Product
и ProductTest
.
В моих тестовых классах у меня есть методы с именами тестируемых методов, подчеркиванием, а затем ситуацией и тем, что я ожидаю, например Save_ShouldThrowExceptionWithNullName()
.
unit-testing
naming-conventions
Джеймс Ньютон-Кинг
источник
источник
test<MethodUnderTest>_<state>
например,testPop_emptyStack
google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 Названия методов. Если есть сомнения, следите за Google.Ответы:
Мне нравится стратегия именования Роя Ошерова , это следующее:
[UnitOfWork_StateUnderTest_ExpectedBehavior]
Он содержит всю необходимую информацию о названии метода и структурированно.
Единица работы может быть как один метод, класс или как несколько классов. Он должен представлять все вещи, которые должны быть проверены в этом тестовом примере и находятся под контролем.
Для сборок я использую типичное
.Tests
окончание, которое я считаю довольно распространенным и то же самое для классов (заканчивающихся наTests
):[NameOfTheClassUnderTestTests]
Ранее я использовал Fixture в качестве суффикса вместо тестов, но я думаю, что последний более распространен, тогда я изменил стратегию именования.
источник
UpdateManager.Update()
. Имея это в виду, я склонен называть свои тестыWhenUpdating_State_Behaviour
илиWhenUpdating_Behaviour_State
. Таким образом, я тестирую определенное действие класса, избегая при этом вставлять имя метода в имя теста. Но самое главное, я должен иметь представление о том, какая бизнес-логика терпит неудачу, когда я вижу название провального тестаМне нравится следовать стандарту именования «Должен» для тестов, при этом присваивая имя тестовому устройству после тестируемого модуля (т.е. класса).
Для иллюстрации (используя C # и NUnit):
Почему "должен" ?
Я считаю, что это вынуждает авторов тестов называть тест с предложением в виде строки «Должен [быть в каком-то состоянии] [после / до / когда] [действие имеет место]»
Да, написание «следует» везде становится немного повторяющимся, но, как я уже сказал, это заставляет писателей мыслить правильно (что может быть полезно для новичков). Плюс это обычно приводит к читаемому английскому имени теста.
Обновление :
Я заметил, что Джимми Богард также является поклонником «следует» и даже имеет библиотеку модульных тестов « Должен» .
Обновление (4 года спустя ...)
Для тех, кто заинтересован, мой подход к тестированию имен развивался годами. Одна из проблем с шаблоном « Должен быть» , который я описал выше, - это не просто понять, какой метод тестируется. Я думаю, что для ООП имеет смысл начинать имя теста с тестируемого метода. Для хорошо разработанного класса это должно привести к читаемым именам тестовых методов. Я сейчас использую формат, похожий на
<method>_Should<expected>_When<condition>
. Очевидно, что в зависимости от контекста вы можете заменить глаголы «Должен / Когда» на что-то более подходящее. Пример:Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()
источник
increasesBalanceWhenDepositIsMade()
.Мне нравится этот стиль именования:
и так далее. Это действительно ясно для не тестера, в чем проблема.
источник
should
я буду предпочитатьwill
такOrdersWithNoProductsWillFail()
Will
не совсем уместно, и, делая это, вы на самом деле ошибочно говорите читателю, что тест ни в коем случае не провалится ... если вы используете,Will
чтобы выразить что-то в будущем, что может не произойти, вы неправильное использование, тогда какShould
это лучший выбор, потому что это означает, что вы хотите / хотите, чтобы что-то произошло, но это не произошло или не могло, когда тест запускает, он сообщает вам, провалился ли он / успешно, поэтому вы не можете на самом деле подразумевать, что заранее, это логичное объяснение, что твое? почему вы избегаетеShould
?Кент Бек предлагает:
Один тестовый прибор на единицу (класс вашей программы). Испытательные приспособления - сами классы. Название испытательного прибора должно быть:
Тестовые случаи (методы тестового крепления) имеют такие имена, как:
Например, имея следующий класс:
Тестовое приспособление будет:
источник
Имена классов . Что касается имен тестовых приборов, я обнаружил, что «Тест» довольно распространен в вездесущем языке многих доменов. Например, в инженерной области:
StressTest
и в области косметики:SkinTest
. Извините, что не согласен с Кентом, но использование «Test» в моих тестовых приспособлениях (StressTestTest
?) Сбивает с толку.«Единица» также часто используется в доменах. Например
MeasurementUnit
. Класс называетсяMeasurementUnitTest
тестом "Measurement" или "MeasurementUnit"?Поэтому мне нравится использовать префикс "Qa" для всех моих тестовых классов. Например,
QaSkinTest
иQaMeasurementUnit
. Его никогда не путают с объектами домена, и использование префикса, а не суффикса означает, что все тестовые приборы живут вместе визуально (полезно, если в вашем тестовом проекте есть подделки или другие вспомогательные классы)Пространства имен . Я работаю в C # и держу свои тестовые классы в том же пространстве имен, что и класс, который они тестируют. Это удобнее, чем иметь отдельные тестовые пространства имен. Конечно, тестовые классы находятся в другом проекте.
Имена методов испытаний . Мне нравится называть мои методы WhenXXX_ExpectYYY. Это делает предусловие ясным и помогает с автоматизированной документацией (как TestDox). Это похоже на совет в блоге по тестированию Google, но с большим разделением предварительных условий и ожиданий. Например:
источник
Я использую понятие « дано, когда» . Взгляните на эту короткую статью http://cakebaker.42dh.com/2009/05/28/given-when-then/ . Статья описывает эту концепцию в терминах BDD, но вы можете использовать ее и в TDD без каких-либо изменений.
источник
Смотрите: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsbly.html
Для имен тестовых методов я лично нахожу использование подробных и самодокументированных имен очень полезным (наряду с комментариями Javadoc, которые дополнительно объясняют, что делает тест).
источник
Я думаю, что одна из самых важных вещей - это соблюдение соглашения об именах (и согласие с другими членами вашей команды). Много раз я видел множество различных соглашений, используемых в одном проекте.
источник
Недавно я придумал следующее соглашение для именования своих тестов, их классов и содержащих проектов, чтобы максимизировать их описание:
Допустим, я тестирую
Settings
класс в проекте вMyApp.Serialization
пространстве имен.Сначала я создам тестовый проект с
MyApp.Serialization.Tests
пространством имен.В этом проекте и, конечно, в пространстве имен я создам класс с именем
IfSettings
(сохраненный как IfSettings.cs ).Допустим, я тестирую
SaveStrings()
метод. -> Я назову тестCanSaveStrings()
.Когда я запускаю этот тест, он показывает следующий заголовок:
MyApp.Serialization.Tests.IfSettings.CanSaveStrings
Я думаю, что это очень хорошо говорит мне, что это тестирование.
Конечно, полезно, чтобы в английском языке существительное «Тесты» было таким же, как и глагол «тесты».
Вашу креативность не ограничивают в названии тестов, поэтому мы получим для них полные заголовки предложений.
Обычно имена тестов должны начинаться с глагола.
Примеры включают в себя:
DetectsInvalidUserInput
)ThrowsOnNotFound
)WillCloseTheDatabaseAfterTheTransaction
)и т.п.
Другой вариант - использовать «это» вместо «если».
Последнее спасает меня нажатие клавиш , хотя и описывает более точно , что я делаю, так как я не знаю, что тестируемое поведение присутствует, но я тестирование , если оно есть.
[ Изменить ]
После более длительного использования вышеуказанного соглашения об именах я обнаружил, что префикс If может сбивать с толку при работе с интерфейсами. Так уж получилось, что класс тестирования IfSerializer.cs очень похож на интерфейс ISerializer.cs в «вкладке« Открыть файлы »». Это может очень раздражать при переключении между тестами, тестируемым классом и его интерфейсом. В результате я бы сейчас выбрал That over If в качестве префикса.
Кроме того, теперь я использую - только для методов в моих тестовых классах, поскольку это не считается лучшей практикой где-либо еще - "_" для разделения слов в именах моих тестовых методов, как в:
Я считаю, что это легче читать.
[ Конец редактирования ]
Я надеюсь, что это порождает еще несколько идей, так как я считаю имена тестов очень важными, поскольку это может сэкономить вам много времени, которое в противном случае было бы потрачено на понимание того, что делают тесты (например, после возобновления проекта после длительного перерыва). ,
источник
В VS + NUnit я обычно создаю папки в своем проекте для группировки функциональных тестов вместе. Затем я создаю классы тестовых модулей и называю их по типу функциональности, которую я тестирую. Методы [Test] имеют следующие имена
Can_add_user_to_domain
:источник
Я должен добавить, что хранение ваших тестов в одном и том же пакете, но в параллельном каталоге с тестируемым источником, устраняет раздувание кода, как только вы готовы развернуть его, не выполняя кучу шаблонов исключения.
Мне лично нравятся лучшие практики, описанные в "Карманном руководстве JUnit" ... трудно превзойти книгу, написанную соавтором JUnit!
источник
имя контрольного примера для класса Foo должно быть FooTestCase или что-то подобное (FooIntegrationTestCase или FooAcceptanceTestCase) - поскольку это контрольный пример. см. http://xunitpatterns.com/ для некоторых стандартных соглашений об именах, таких как test, test case, test fixture, test test и т. д.
источник