Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве показано, как создать решение, содержащее проект модульного теста и проект исходного кода. Чтобы выполнить руководство с помощью предварительно созданного решения, просмотрите или скачайте пример кода. Инструкции по скачиванию смотрите в разделах Образцы и руководства.
Создание решения
В этом разделе создается решение, содержащее исходные и тестовые проекты. Готовое решение имеет следующую структуру каталогов:
/unit-testing-using-dotnet-test
unit-testing-using-dotnet-test.sln
/PrimeService
PrimeService.cs
PrimeService.csproj
/PrimeService.Tests
PrimeService_IsPrimeShould.cs
PrimeServiceTests.csproj
Ниже приведены инструкции по созданию тестового решения. Команды для создания тестового решения, чтобы сделать это в один шаг.
Откройте окно терминала.
Выполните следующую команду:
dotnet new sln -o unit-testing-using-dotnet-test
Команда
dotnet new sln
создает новое решение в каталоге unit-testing-using-dotnet-test .Измените каталог на папку unit-testing-using-dotnet-test .
Выполните следующую команду:
dotnet new classlib -o PrimeService
Команда
dotnet new classlib
создает проект библиотеки классов в папке PrimeService . Новая библиотека классов будет содержать тестируемый код.Переименуйте Class1.cs в PrimeService.cs.
Замените код в PrimeService.cs следующим кодом:
using System; namespace Prime.Services { public class PrimeService { public bool IsPrime(int candidate) { throw new NotImplementedException("Not implemented."); } } }
В настоящее время этот код выбрасывает исключение NotImplementedException, но вы будете реализовывать этот метод позже в этом руководстве.
В каталоге unit-testing-using-dotnet-test выполните следующую команду, чтобы добавить проект библиотеки классов в решение:
dotnet sln add ./PrimeService/PrimeService.csproj
Создайте проект PrimeService.Tests , выполнив следующую команду:
dotnet new xunit -o PrimeService.Tests
Предыдущая команда создает проект PrimeService.Tests в каталоге PrimeService.Tests. Тестовый проект использует xUnit в качестве тестовой библиотеки. Команда также настраивает средство выполнения теста, добавив следующие
<PackageReference />
элементы в файл проекта:Microsoft.NET.Test.Sdk
xunit
xunit.runner.visualstudio
coverlet.collector
Добавьте тестовый проект в файл решения, выполнив следующую команду:
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
Добавьте библиотеку
PrimeService
классов в качестве зависимости в проект PrimeService.Tests :dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
Команды для создания решения
В этом разделе перечислены все команды, описанные в предыдущем разделе. Пропустите этот раздел, если вы выполнили действия, описанные в предыдущем разделе.
Следующие команды создают тестовое решение на компьютере Windows. Для macOS и Unix обновите ren
команду до версии ren
ОС, чтобы переименовать файл:
dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
Выполните инструкции по замене кода в PrimeService.cs следующим кодом в предыдущем разделе.
Создайте тест
Популярный подход к разработке на основе тестов (TDD) заключается в написании (неудачного) теста перед реализацией целевого кода. В этом руководстве используется подход TDD. Метод IsPrime
вызывается, но не реализуется. Не удается выполнить тестовый вызов IsPrime
. В TDD вы пишете тест, который заведомо проваливается. Затем вы обновляете целевой код, чтобы пройти тестовый проход. Вы продолжаете повторять этот подход: пишете провалившийся тест, а затем обновляете целевой код, чтобы он прошел.
Обновите проект PrimeService.Tests :
Удаление PrimeService.Tests/UnitTest1.cs.
Создайте файл PrimeService.Tests/PrimeService_IsPrimeShould.cs .
Замените код в PrimeService_IsPrimeShould.cs следующим кодом:
using Xunit; using Prime.Services; namespace Prime.UnitTests.Services { public class PrimeService_IsPrimeShould { [Fact] public void IsPrime_InputIs1_ReturnFalse() { var primeService = new PrimeService(); bool result = primeService.IsPrime(1); Assert.False(result, "1 should not be prime"); } } }
Атрибут [Fact]
объявляет метод тестирования, который выполняется тестовым раннером. В папке PrimeService.Tests выполните команду dotnet test
. Команда dotnet test создает оба проекта и запускает тесты. Запускатель тестов xUnit содержит точку входа программы для выполнения тестов.
dotnet test
запускает средство выполнения теста с помощью проекта модульного теста.
Тест завершается ошибкой, так как IsPrime
не был реализован. Используя подход TDD, напишите только достаточно кода, чтобы этот тест прошел. Обновите IsPrime
, включив в него следующий код.
public bool IsPrime(int candidate)
{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}
Выполните dotnet test
. Тест пройден.
Добавьте дополнительные тесты.
Добавьте тесты праймерных чисел для 0 и -1. Можно скопировать тест, созданный на предыдущем шаге, и создать копии следующего кода, чтобы проверить 0 и -1. Но не делай это, так как есть лучший способ.
var primeService = new PrimeService();
bool result = primeService.IsPrime(1);
Assert.False(result, "1 should not be prime");
Копирование тестового кода, когда изменяется только один параметр, приводит к дублированию кода и разрастанию тестов. Следующие атрибуты xUnit позволяют создавать набор аналогичных тестов:
-
[Theory]
представляет набор тестов, которые выполняют один и тот же код, но имеют разные входные аргументы. -
[InlineData]
атрибут задает значения для этих входных данных.
Вместо создания новых тестов примените предыдущие атрибуты xUnit для создания одной теории. Замените следующий код...
[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
var primeService = new PrimeService();
bool result = primeService.IsPrime(1);
Assert.False(result, "1 should not be prime");
}
... с помощью следующего кода:
[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);
Assert.False(result, $"{value} should not be prime");
}
В приведенном выше коде [Theory]
и [InlineData]
включите тестирование нескольких значений менее двух. Два — наименьшее первое число.
Добавьте следующий код после объявления класса и перед атрибутом [Theory]
:
private readonly PrimeService _primeService;
public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}
Выполните dotnet test
, и два теста не проходят. Чтобы выполнить все тесты, обновите IsPrime
метод следующим кодом:
public bool IsPrime(int candidate)
{
if (candidate < 2)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}
После подхода TDD добавьте более неудачные тесты, а затем обновите целевой код. Ознакомьтесь с готовой версией тестов и полной реализацией библиотеки.
Завершенный IsPrime
метод не является эффективным алгоритмом для тестирования примиальности.