Я изучаю модульное тестирование и задаюсь вопросом, является ли этот поток программы модульного тестирования правильным? как в Arrange, Act, Assert
Я изучаю модульное тестирование и задаюсь вопросом, является ли этот поток программы модульного тестирования (как в Arrange, Act, Assert) правильным?
[TestFixture]
public class unitTest2
{
private CoffeeMaker coffemaker;
[Test]
public void TestMethod1() // Testa metoden för kaffe med mjölk. Uppgift 2(b)
{
coffemaker = new CoffeeMaker(); //Arrange
string res = coffemaker.MakeDrink(new Coffee(true, false)); //Act
StringAssert.Contains("Coffee with milk", res); //Assert
}
}
3 ответа
Делай и не делай
ДЕЛАТЬ
Назовите тесты с указанием ожидаемого результата и соответствующих сведений о состоянии или входе, который тестируется.
НЕ
Дайте названия тестов, которые ничего не говорят, кроме названия тестируемого метода, за исключением тривиальных случаев.
Структура Структура тестов в трех отдельных блоков - упорядочить, действовать и утверждать.
Модульные тесты, как правило, имеют очень регулярную структуру. Распространенным способом ссылки на эту структуру является упорядочение, действие, утверждение: каждый тест должен упорядочивать состояние мира для тестирования, воздействовать на тестируемый класс, вызывая методы, и утверждать, что мир впоследствии находится в ожидаемом состоянии.
Блок упорядочения предназначен для настройки деталей внешнего мира, специфичных для тестируемой ситуации. Это включает в себя такие вещи, как создание локальных переменных, которые будут повторно использоваться в тесте, и иногда создание экземпляра тестируемого объекта с конкретными аргументами. Этот шаг не должен включать какие-либо обращения к тестируемому объекту (делать это во время блока действия) или проверки исходного состояния (делать это во время утверждения, возможно, в другом тесте). Обратите внимание, что общая настройка, необходимая для всех или многих тестов, должна выполняться в методе setUp теста. Если ваш тест не зависит от какого-либо конкретного внешнего состояния, вы можете пропустить блок аранжировки.
Блок act - это место, где вы фактически делаете вызовы тестируемому классу, чтобы вызвать поведение, которое тестируется. Часто этот блок будет одним вызовом метода, но если тестируемое поведение охватывает несколько методов, то каждый из них будет вызываться здесь. Простые аргументы могут быть встроены как часть вызова метода, но более сложные выражения аргументов иногда лучше извлекать в блок упорядочения, чтобы не отвлекать внимание от намерений блока. Блок действия также может присваивать возвращаемое значение метода локальной переменной, чтобы его можно было установить позже.
Блок assert - это место для создания утверждений о возвращаемых значениях и проверки любых взаимодействий с фиктивными объектами. Он также может создавать значения, необходимые для утверждений и проверок. В очень простых тестах блоки act и assert иногда объединяются путем включения вызовов тестируемого класса в оператор assert.
Эти блоки должны отличаться друг от друга - тест не должен выполнять какую-либо дополнительную настройку или заглушку, когда он выполняет вызовы к тестируемому классу в блоке действия, и он не должен делать дальнейшие вызовы к тестируемому классу, как только проверка начинается в Утвердить блок.
Это должно быть ясно при взгляде на тест, где каждый блок начинается и заканчивается. Обычно это можно сделать, добавив одну пустую строку между каждым блоком (хотя в простых тестах это не требуется, когда блоки состоят из одной или двух строк в каждом). В особенно сложных тестах, особенно в тех, где вам нужно настроить несколько различных объектов, вы можете использовать пустые строки внутри блоков, чтобы сделать их более удобочитаемыми. В этом случае один из вариантов различения блоков - пометить каждый из них комментариями, такими как // Arrange, // Act и // Assert.
Тесты, которые подчеркивают эту структуру, являются более понятными, поскольку они облегчают навигацию по различным частям теста, и с большей вероятностью будут выполнены, поскольку регулярная структура помогает гарантировать, что детали тестируемого поведения не будут скрыты или опущены.
Поддельные рамки взаимодействуют с этой структурой по-разному. Большинство современных фреймворков, таких как Mockito, позволяют конфигурировать заглушки в блоке размещения вместе с определением локальных переменных и проверять макеты в блоке assert вместе с выполнением утверждений. К сожалению, некоторые более старые фреймворки, такие как EasyMock, требуют указания ожидаемого поведения mocks перед вызовом тестируемого кода - для этого требуется четвертый "ожидаемый" блок перед блоком act, который работает аналогично блоку assert.
Хорошо выглядит, некоторые незначительные улучшения:
[TestFixture]
public class CoffeeMakerUnitTests
{
[Test]
public void Test_MakeCoffeeWithMilk_Succeeds()
{
// Arrange
var coffemaker = new CoffeeMaker();
// Act
string res = coffemaker.MakeDrink(new Coffee(true, false));
// Assert
StringAssert.Contains("Coffee with milk", res);
}
}
Шаблон Arrange/Act/Assert более виден таким образом. И вы хотите избежать всего, что не является локальным для вашей тестовой функции, потому что это вызовет проблемы только после того, как у вас будет вторая тестовая функция.
Ваша функция должна называться "Что происходит и каков ожидаемый результат", потому что тогда вы сможете увидеть, что не получилось в результатах вашего теста. "Ошибка UnitTest1" не очень наглядна.
Arrange - это место, где вы все настроили для своего теста. Act - это то, где вы выполняете какое-либо действие на тестируемой системе. Утвердите, где вы проверяете результат этого действия.
Ваш тест вписывается в это рассуждение? Ага.
Вам также следует учитывать соглашение об именах, которое вы используете. Вот тот, который следует MethodName_Scenario_ExpectedResult
для имен методов испытаний:
[TestFixture]
public class CoffeeMakerTests
{
[Test]
public void MakeDrink_CoffeeWithMilk_ReturnsCorrectString() // Testa metoden för kaffe med mjölk. Uppgift 2(b)
{
// Arrange
var coffeemaker = new CoffeeMaker();
var coffeeWithMilk = new Coffee(true, false));
// Act
var resultString = coffeemaker.MakeDrink(coffeeWithMilk);
// Assert
StringAssert.Contains("Coffee with milk", resultString);
}
}