Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве вы познакомитесь с интерактивным процессом пошагового создания примерного решения, чтобы изучить концепции модульного тестирования. Если вы предпочитаете следовать руководству с помощью предварительно созданного решения, просмотрите или скачайте пример кода перед началом. Инструкции по скачиванию смотрите в разделах Образцы и руководства.
В этой статье описывается тестирование проекта .NET Core. Если вы тестируете проект ASP.NET Core, см. тесты интеграции в ASP.NET Core.
Создание исходного проекта
Откройте окно оболочки. Создайте каталог с именем unit-testing-with-fsharp для хранения решения.
В этом новом каталоге запустите dotnet new sln
, чтобы создать новое решение. Это упрощает управление библиотекой классов и проектом модульного теста.
В каталоге решения создайте каталог MathService. Структура каталога и файла до сих пор показана ниже:
/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Сделайте MathService текущим каталогом и запустите dotnet new classlib -lang "F#"
для создания исходного проекта. Вы создадите некорректную реализацию математического сервиса.
module MyMath =
let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))
Измените каталог обратно в каталог unit-testing-with-fsharp. Запустите dotnet sln add .\MathService\MathService.fsproj
, чтобы добавить проект библиотеки классов в решение.
Создание тестового проекта
Затем создайте каталог MathService.Tests. В следующей схеме показана структура каталога:
/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Сделайте каталог MathService.Tests текущим каталогом и создайте новый проект с помощью dotnet new xunit -lang "F#"
. При этом создается тестовый проект, использующий xUnit в качестве тестовой библиотеки. Созданный шаблон настраивает средство выполнения теста в MathServiceTests.fsproj:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
Тестовый проект требует создания и запуска модульных тестов других пакетов.
dotnet new
на предыдущем шаге добавлен xUnit и раннер xUnit. Теперь добавьте библиотеку классов MathService
в качестве другой зависимости в проект. Используйте команду dotnet reference add
:
dotnet reference add ../MathService/MathService.fsproj
Весь файл можно увидеть в репозитории примеров на сайте GitHub.
У вас есть следующий окончательный макет решения:
/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Test Source Files
MathServiceTests.fsproj
Выполните dotnet sln add .\MathService.Tests\MathService.Tests.fsproj
в каталоге unit-testing-with-fsharp.
Создание первого теста
Вы пишете один не проходящий тест, делаете его успешным, а затем повторяете процесс. Откройте Test.fs и добавьте следующий код:
[<Fact>]
let ``My test`` () =
Assert.True(true)
[<Fact>]
let ``Fail every time`` () = Assert.True(false)
Атрибут [<Fact>]
обозначает метод тестирования, выполняемый тестовым запускателем. В unit-testing-with-fsharp выполните dotnet test
для сборки тестов и библиотеки классов, а затем запустите тесты. Средство выполнения теста xUnit содержит точку входа программы для запуска ваших тестов.
dotnet test
запускает средство выполнения тестов, используя проект модульного теста, который вы создали.
Эти два теста демонстрируют наиболее простые примеры успешных и неудачных тестов.
My test
успешно проходит и Fail every time
завершается ошибкой. Теперь создайте тест для метода squaresOfOdds
. Метод squaresOfOdds
возвращает последовательность квадратов всех нечетных целых значений, которые являются частью входной последовательности. Вместо того чтобы одновременно записывать все эти функции, можно итеративно создавать тесты, проверяющие функциональные возможности. Чтобы каждый тест проходил успешно, необходимо создать соответствующую функциональность метода.
Самый простой тест, который можно написать, заключается в вызове squaresOfOdds
со всеми четными числами, где результат должен быть пустой последовательностью целых чисел. Вот этот тест:
[<Fact>]
let ``Sequence of Evens returns empty collection`` () =
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)
Ваш тест не удался. Вы еще не создали реализацию. Выполните этот тест, написав самый простой код в классе MathService
, который работает:
let squaresOfOdds xs =
Seq.empty<int>
В каталоге unit-testing-with-fsharp выполните dotnet test
еще раз. Команда dotnet test
запускает сборку для проекта MathService
, а затем для проекта MathService.Tests
. После создания обоих проектов он запускает этот единичный тест. Это проходит.
Выполнение требований
Теперь, когда вы завершили один тестовый прогон, пора писать больше тестов. Следующий простой случай работает с последовательностью, единственное нечетное число которой — 1
. Число 1 проще, так как квадрат 1 равен 1. Вот следующий тест:
[<Fact>]
let ``Sequences of Ones and Evens returns Ones`` () =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)
Выполнение dotnet test
запускает ваши тесты и показывает, что новый тест завершается ошибкой. Теперь обновите squaresOfOdds
метод для обработки этого нового теста. Вы фильтруете все четные числа из последовательности, чтобы сделать этот тест пройденным. Это можно сделать, написав небольшую функцию фильтра и используя Seq.filter
:
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
Есть еще один шаг: возвести в квадрат каждое из нечетных чисел. Начните с написания нового теста:
[<Fact>]
let ``SquaresOfOdds works`` () =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.Equal(expected, actual)
Вы можете скорректировать тест, направив отфильтрованную последовательность с помощью операции отображения для вычисления квадрата каждого нечетного числа.
let private square x = x * x
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square
Вы создали небольшую библиотеку и набор модульных тестов для этой библиотеки. Вы структурировали решение таким образом, чтобы добавление новых пакетов и тестов было частью обычного рабочего процесса. Вы сосредоточили большую часть времени и усилий на решении целей приложения.