いつも適当に使っている xUnit について整理したいなーと数年思い続け...ついに書く日が来ました。。。
気分次第ですが、複数回に分けて書く予定です。
Overview
- 1. Assert の基本(今回)
- 2. Data Driven Test (データドリブンテスト)
- 3. テスト実行時の Tips ( Attribute とかコマンド)
- 4. 環境変数の取得
- 5. Azure DevOps でのテスト実行
準備: VS でプロジェクトの作成
VS 2017 でASP.NET Core の Web のプロジェクトと、xUnit のプロジェクトを作ってみます。 手順は省きますが、「DotnetTestingSamples.NetCoreWeb」と「NetCoreWebTests」の二つのプロジェクトを作りました。
それぞれのプロジェクトに対してパッケージマネージャーコンソールで、
update-package
をして、Nuget のパッケージを最新にしました。
この時点で、Nugetのバージョンはこんな感じです。特に変哲もないターゲットフレームワークが .NET Core2.1 のアプリですね。
後は、テストプロジェクトから「DotnetTestingSamples.NetCoreWeb」プロジェクトを見えるように参照を追加します。 「NetCoreWebTests」を右クリック > 「追加」 > 「参照」をクリックし、参照マネージャーウインドウを表示させます。 左ペインでプロジェクトをクリックし、「DotnetTestingSamples.NetCoreWeb」にチェックを入れて「OK」ボタンをクリックしましょう。
また、今回多少使うサンプルとして、以下の Person
クラスを用意しました。
今回は、以下のよく使いそうな Assert を整理します。
NULL の評価
特に型はこだわらず NULL を評価するには以下のメソッドを使います。NULLについてはもうこれ以上の話はないです。
Assert.Null
Assert.NotNull
文字列の評価
文字列が同じかを評価する
まずは一番利用する以下のメソッド。
Assert.Equal
Assert.NotEqual
メソッドの 1st 引数に期待値、2nd 引数に actual な値を入れて評価する基本的な使い方が普通ですね。
文字列を評価する際このメソッドの引数には、3つ目~5つ目にデフォルト値が false
に設定されているオプションの引数が存在します。
- ignoreCase :
true
に設定すると、大文字小文字が異なっていてもエラーとしない。 - ignoreLineEndingDifferences :
true
に設定すると、改行コード(\r\n, \r, \n)が異なる場合でもエラーとしない。 - ignoreWhiteSpaceDifferences :
ture
に設定すると、スペースの数やスペースじゃなくてタブでもエラーとしない(スペースがある前提での評価で、スペースがあるものとないものを評価すればエラーになります)。
例えば ignoreCase
を true
に設定すれば、(こんなテストが良いかはさておき)大文字が含まれるプロパティに対して、小文字のみの期待値と評価してもがテストはグリーンになります。
文字列が特定の文字列から始まるか / 特定の文字列で終わるか評価する
Assert.StartsWith
Assert.EndsWith
メソッドの 1st 引数に期待値、2nd 引数に actual な値を入れて評価する単純な方法のほかに、第3引数に StringComparison
を付けて評価することができます。StringComparison
についての確認は、以下の公式ドキュメントを見るのが良いですね。
文字列に、特定の値が含まれているかを評価する
Assert.Contains
Assert.DoesNotContain
これも、メソッドの 1st 引数に期待値、2nd 引数に actual な値を入れて評価する単純な方法のほかに、第3引数に StringComparison
を付けて評価することができます。
正規表現の評価
以下を使って文字列に対して正規表現の評価ができます。
- Assert.Matches
特定の値を特定の正規表現で評価する雑なサンプルはこんな感じです。
数値の評価
数値もまずはこのメソッドで評価することが一番多いですね。
Assert.Equal
Assert.NotEqual
数値の Equal / NotEqual では、第3引数に有効桁数を指定することができますので、浮動小数点型に対してこんな評価も可能です。
数値の範囲の評価
数値なら以下のメソッドで、指定の範囲内にあるか評価できます。
InRange<T>(T actual, T low, T high)
NotInRange<T>(T actual, T low, T high)
または、Assert.True
使ってこんな感じ: Assert.True( actual > lowValue && actual < highValue)
でやると、より細かい評価も可能ですね。
bool の比較
このタイミングで書くのもなんですが、以下2つで評価ですね。引数にセットする値には、bool?
型も使えるとか、第2引数に userMessage つけれるとかありますが、これはもう他に書くこともないです。
Assert.True
Asset.False
object の評価
型の評価をする場合、以下を使えます。
Assert.IsType<T>(object actual)
Assert.IsNotType<T>(object actual)
個人的には、引数によって出力される型が異なる Factory メソッドとかで正しい型が出力されるかとかに使ったり。
また、親クラスのチェックには以下を使います(Generics じゃないメソッドもあるけど省略)。
Assert.IsAssignableFrom<T>(actual)
オブジェクトが同一インスタンスかどうかを評価するには、
Assert.Same(object expected, object actual)
Assert.NotSame(object expected, object actual)
があります。他にも、NotStrictEqual とかあるので、他に Object に対する評価をしたいときは、xUnit の実装やテストコードをみると、全部のメソッドが確認できます。
(飽きてだんだん雑になってきた...)
Collection の評価
コレクションの評価としては、まず、期待値(コレクションではない単体)がテスト対象のコレクションに含まれるかというチェックがあります。
Contains<T>(T expected, IEnumerable<T> collection)
DoesNotContain<T>(T expected, IEnumerable<T> collection)
Collection評価時の Contains
とDoesNotContain
には、引数に Predicate
Equal
や NotEqual
を使ってコレクション同士の比較をすることも可能です。また、LINQ にあるような Single
や All
もあります。
Exception の評価
特定のメソッドとかで exception を発生させるなら以下で評価きます。
- Assert.Throws
(Action)
Exception 発生時の Parameter 名を指定して動かすこともテストもできます。
独自の Exception クラスを実装しているときは、2つの評価でテストするってパターンもありますね。
// 例えば "CustomException" クラスという独自の Exception クラスを用意して、例外発生後に特定のプロパティ
CustomException ex = Assert.Throws<CustomException>(Action)
Assert.Equal(expected, ex.SomeProperty)
ログの出力
ITestOutputHelper
ってクラスを使ってログを出すことができます。大した内容はないですが詳細は公式のドキュメントにて確認できます。
using Xunit; using Xunit.Abstractions; public class MyTestClass { private readonly ITestOutputHelper _output; public MyTestClass(ITestOutputHelper output) { _output = output; } [Fact] public void MyTest() { var temp = "my class!"; _output .WriteLine($"This is output from {temp}"); } }
その他
Event 関連の Assert も色々ありますが、私が Desktop アプリをあまり作らないので省略。
チートシート
他のテストライブラリーとの Assert や Attribute の比較は、以下になります。
Comparing xUnit.net to other frameworks
チートシートなだけで、Assert のメソッドが全部乗ってるわけでもないので、細かいこと確認したいときは、
xUnit の GitHub のテストメソッドとかを見て確認すると早いかなーと思っています。
次は、テストデータの作り方入門です。