Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
27 декабря 2022 г.

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

Автор:
Artem Polishchuk
Источник:
Просмотров:
2066

Часто бывает что вам нужно протестировать какую то функцию или метод, однако подобрать имя для теста бывает часто затруднительно. Для этого в этой статье мы рассмотрим несколько самых используемых подходов к именованию 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);
}
Похожее
24 марта
В современном программном обеспечении очень часто возникает необходимость выполнять различные операции с всевозможными суммами денег. Однако до сих пор мне нигде не попадалось документации, в которой были бы сведены воедино основные правила представления сумм и реализации финансовых вычислений. В этой...
24 марта
Автор: Productivity Inside
Когда я учился в университете, Leetcode поломал мне мозг. Я смотрел на лучшие из лучших решений, которые укладывались в одну строчку малопонятного кода, и в своем заблуждении думал: «Как же мне достигнуть такого высокого уровня?» Что тут вообще происходит? Такой...
Jan 18, 2023
Author: Shubhadeep Chattopadhyay
Unit testing is one of the major parts of software testing which can be handled by the developer itself. It is used to test the smallest components of your code. The purpose of the Unit test is to validate the...
Mar 10, 2023
Author: Yohan Malshika
Writing unit test code when using the Dapper ORM tool for database operations with ASP.NET Core Web Application How to write unit tests with Dapper Writing unit tests when using the Dapper ORM tool for database operations in an ASP.NET...
Написать сообщение
Тип
Почта
Имя
*Сообщение