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