20  
программирование
Search  
Always will be ready notify the world about expectations as easy as possible: job change page
27 декабря 2022 г.

Как правильно выбрать название для Unit тестов

Author:
Artem Polishchuk
Source:
Views:
2069

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

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

MethodName_StateUnderTest_ExpectedBehavior: ​

Существуют аргументы против этой стратегии, так как если имена методов изменяются после рефакторинга кода, это должно также изменить название теста, это становится трудным для понимания на более позднем этапе. Ниже приведены некоторые примеры:

public void IsAdult_AgeLessThan18_False()
{
}

 

public void WithdrawMoney_InvalidAccount_ExceptionThrown()
{
}

 

public void AdmitStudent_MissingMandatoryFields_FailToAdmit()
{
}

MethodName_ExpectedBehavior_StateUnderTest:

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

public void IsAdult_False_AgeLessThan18()
{
}

 

public void WithdrawMoney_ThrowsException_IfAccountIsInvalid()
{
}

 

public void AdmitStudent_FailToAdmit_IfMandatoryFieldsAreMissing()
{
}

Feature to be tested:

Многие полагают, что лучше просто написать тестируемую функцию, потому что в любом случае вы используете аннотации, чтобы идентифицировать метод в качестве методов тестирования. Он также рекомендуется по той причине, что он делает модульные тесты альтернативной формой документации и не так портит кода. И опять таки примеры с использованием этого метода:

public void IsNotAnAdultIfAgeLessThan18()
{
}

 

public void FailToWithdrawMoneyIfAccountIsInvalid()
{
}

 

public void StudentIsNotAdmittedIfMandatoryFieldsAreMissing()
{
}

Should_ExpectedBehavior_When_StateUnderTest:

Этот метод также используется многими, так как он легко объясняет что должна делать тестируемая функция. Примеры:

public void Should_ThrowException_When_AgeLessThan18()
{
}

 

public void Should_FailToWithdrawMoney_ForInvalidAccount()
{
}

 

public void Should_FailToAdmit_IfMandatoryFieldsAreMissing()
{
}

When_StateUnderTest_Expect_ExpectedBehavior:

Аналогично предыдущему, но условие теперь стоит перед ожидаемым выполнением. Примеры:

public void When_AgeLessThan18_Expect_isAdultAsFalse()
{
}

 

public void When_InvalidAccount_Expect_WithdrawMoneyToFail()
{
}

 

public void When_MandatoryFieldsAreMissing_Expect_StudentAdmissionToFail()
{
}

​​​Given_Preconditions_When_StateUnderTest_Then_ExpectedBehavior:

Этот подход основан на стандартах именовании, разработанном как часть Behavior-Driven Development (BDD). Идея состоит в том, чтобы разбить тесты на три части таким образом, чтобы можно было найти предварительные условия, проверка состояния во время теста и ожидаемое поведение, которое должно быть написано в вышеуказанном формате. Ниже приведен пример того, как если бы эти имена использовались с использованием этого метода:

public void Given_UserIsAuthenticated_When_InvalidAccountNumberIsUsedToWithdrawMoney_Then_TransactionsWillFail()
{
}

MethodName_WithStateUnderTest_ShouldExpectedBehavior: ​ 

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

Давайте рассмотрим пример:

[Test]
public void Login_WithDisabledTwoFactorSmsAuth_ShouldReturnSignInAndReturnRedirectToActionResult()
{
    // Arange
    var model = new LoginModel
    {
        Email = "admin@test.com",
        Password = "q1w2e3"
    };

    Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    configuration.AppSettings.Settings[key].Value = value;
    configuration.Save();
    ConfigurationManager.RefreshSection("appSettings");

    // Act
    var result = Controller.Login(model, null).Result;

    // Assert
    Assert.IsInstanceOf<RedirectToRouteResult>(result);
}
Similar
24 марта
Автор: ProQualityCommunity
В этой статье я собираюсь поделиться некоторыми идеями, которые помогли создать качественные продукты. Хотя QA не является единственным лицом, ответственным за качество, но в большинстве случаев QA является последним человеком, который проводит предварительное / сквозное тестирование, прежде чем доставлять или...
30 января 2023 г.
Автор: Ямангулов Андрей Наильевич
Какой HR (или рекрутер) не сталкивался с этой проблемой? Думаю, что все. Сколько копий сломано на эту тему? - Сейчас мы сломаем еще одно! Предполагаю, что сейчас все кадровики начнут кидать в меня тапками. Но умные и опытные вполне себе...
24 марта
Автор: Рафаил Агазода
Сегодня мы попытаемся построить и запустить магазин мороженого, при этом одновременно изучить асинхронный JavaScript. Также вы узнаете, как использовать: Callbacks. Promises. Async / Await. Вот что мы рассмотрим в этой статье: Что такое асинхронный JavaScript. Синхронный и асинхронный JavaScript. Как...
24 марта
Автор: Сергей Кушниренко
Среди множества задач, решаемых программистом, одной из самых частых является подумать и добавить новый функционал в приложение. И там уже может быть много похожего функционала, он может быть хорошо написан, хорошо документирован. Искушение заключается в том, поддаться своей лени и...
Send message
Type
Email
Your name
*Message