このチュートリアルでは、単体テストの概念を学習するためのサンプル ソリューションを段階的に構築する対話型エクスペリエンスについて説明します。 事前構築済みのソリューションを使用してチュートリアルに従う場合は、開始 する前にサンプル コードを表示またはダウンロード してください。 ダウンロード手順については、 サンプルとチュートリアルを参照してください。
この記事では、.NET Core プロジェクトのテストについて説明します。 もし ASP.NET Core プロジェクトをテストする場合は、ASP.NET Core の統合テストを参照してください。
[前提条件]
- .NET 8 SDK 以降のバージョン。
- 任意のテキスト エディターまたはコード エディター。
ソース プロジェクトを作成する
シェル ウィンドウを開きます。 ソリューションを保持するために 、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 nunit -lang "F#"
このコマンドは、テスト フレームワークとして NUnit を使用するテスト プロジェクトを作成します。 生成されたテンプレートは、 MathServiceTests.fsproj でテスト ランナーを構成します。
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>
テスト プロジェクトでは、単体テストを作成して実行するために他のパッケージが必要です。
dotnet new
前の手順で NUnit と NUnit テスト アダプターを追加しました。 次に、 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
MathService.Tests.fsproj
unit-testing-with-fsharp ディレクトリで次のコマンドを実行します。
dotnet sln add .\MathService.Tests\MathService.Tests.fsproj
最初のテストを作成する
失敗したテストを 1 つ記述し、合格させ、プロセスを繰り返します。 UnitTest1.fs を開き、次のコードを追加します。
namespace MathService.Tests
open System
open NUnit.Framework
open MathService
[<TestFixture>]
type TestClass () =
[<Test>]
member this.TestMethodPassing() =
Assert.That(true, Is.True)
[<Test>]
member this.FailEveryTime() = Assert.That(false, Is.True)
[<TestFixture>]
属性は、テストを含むクラスを表します。
[<Test>]
属性は、テスト ランナーによって実行されるテスト メソッドを表します。
unit-testing-with-fsharp ディレクトリから、dotnet test
を実行してテストとクラス ライブラリをビルドし、テストを実行します。 NUnit テスト ランナーには、テストを実行するためのプログラム エントリ ポイントが含まれています。
dotnet test
を実行すると、作成した単体テスト プロジェクトを使用してテスト ランナーが開始されます。
これら 2 つのテストは、最も基本的な合格テストと失敗したテストを示しています。
My test
が渡され、 Fail every time
が失敗します。 次に、 squaresOfOdds
メソッドのテストを作成します。
squaresOfOdds
メソッドは、入力シーケンスの一部であるすべての奇数整数値の 2 乗のシーケンスを返します。 これらの関数をすべて一度に記述するのではなく、機能を検証するテストを繰り返し作成できます。 各テスト パスの手段を作成するには、メソッドに必要な機能を作成します。
記述できる最も簡単なテストは、すべての偶数で squaresOfOdds
を呼び出す方法です。結果は空の整数シーケンスである必要があります。 そのテストを次に示します。
[<Test>]
member this.TestEvenSequence() =
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.That(actual, Is.EqualTo(expected))
expected
シーケンスがリストに変換されていることに注意してください。 NUnit フレームワークは、多くの標準的な .NET 型に依存しています。 この依存関係は、パブリック インターフェイスと予想される結果が、ICollectionではなくIEnumerableをサポートすることを意味します。
テストを実行すると、テストが失敗することがわかります。 これは、実装をまだ作成していないためです。 動作する MathService プロジェクトの Library.fs クラスに最も単純なコードを記述して、このテストを成功させる。
let squaresOfOdds xs =
Seq.empty<int>
unit-testing-with-fsharp ディレクトリで、dotnet test
をもう一度実行します。
dotnet test
コマンドは、MathService
プロジェクトのビルドを実行してから、MathService.Tests
プロジェクトに対してビルドを実行します。 両方のプロジェクトをビルドすると、テストが実行されます。 2 つのテストが合格しました。
要件を満たす
テストが1つ成功したので、さらに多くのテストケースを書きましょう。 次の単純なケースは、唯一の奇数が1
であるシーケンスで動作します。 1 の 2 乗は 1 であるため、数値 1 の方が簡単です。 次のテストを次に示します。
[<Test>]
member public this.TestOnesAndEvens() =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.That(actual, Is.EqualTo(expected))
dotnet test
を実行すると、新しいテストが失敗します。 この新しいテストを処理するには、 squaresOfOdds
メソッドを更新する必要があります。 このテストを成功させるには、シーケンスからすべての偶数をフィルター処理する必要があります。 これを行うには、小さなフィルター関数を記述し、 Seq.filter
を使用します。
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
残りのステップは、すべての奇数をそれぞれ2乗することです。 まず、新しいテストを記述します。
[<Test>]
member public this.TestSquaresOfOdds() =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.That(actual, Is.EqualTo(expected))
テストを修正するには、フィルター処理されたシーケンスをマップ操作でパイプ処理し、各奇数の 2 乗を計算します。
let private square x = x * x
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square
あなたは、小さなライブラリとそのライブラリの単体テストのセットを構築しました。 新しいパッケージとテストの追加が通常のワークフローの一部になるように、ソリューションを構造化しました。 アプリケーションの目標を解決するために、ほとんどの時間と労力を集中しました。
こちらも参照ください
- dotnet reference add コマンドを使用して参照を追加します。
- dotnet test
.NET