目次
MsTest
でユニットテストを書く場合はユニットテスト用のプロジェクトを作成し、
UnitTestFramework
と テストしたい物 の参照を追加すればテストできる。
[テスト] -> [実行] -> [ソリューションのすべてのテスト] でテスト実行できる。
[追記 20151018] マルチプラットフォームで実行可能にしたい場合
プロジェクトの作成時に、「単体テストプロジェクト」
を選択するとMSTestによるテストプロジェクトが作られるが、
このプロジェクトは Xamarin.Mac
で開けなかった。
Xamarin.Mac
でも開けるようにするため
「クラス ライブラリ」のプロジェクトを作成して、
以下のようにテストプロジェクトを編集
NuGet
のpackages.config
にNUnit
を追加[Visual Studio] Microsoft.VisualStudio.TestTools.UnitTestFramework
の参照を追加
また Visual Studio
に NUnit Test Adapter
の拡張機能をインストールする。
テストコードを記述する際は、
以下の様に切り替えれば簡単にMSTEstとNUnitに両対応できる。#define
よりプロジェクト設定のコンパイラーシンボルで切り替えたほうがいいかな?
#define USING_NUNIT
#if USING_NUNIT
using NUnit.Framework;
using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
using TestMethodAttribute = NUnit.Framework.TestAttribute;
using ClassInitializeAttribute = NUnit.Framework.TestFixtureSetUpAttribute;
using ClassCleanupAttribute = NUnit.Framework.TestFixtureTearDownAttribute;
using TestInitializeAttribute = NUnit.Framework.SetUpAttribute;
using TestCleanupAttribute = NUnit.Framework.TearDownAttribute;
using TestCategoryAttribute = NUnit.Framework.CategoryAttribute;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif
TimeoutAttribute, DescriptionAttribute, IgnoreAttribute
などは同名なので名前空間をインポートしていればそのまま使える。
[追記おわり]
Assert
クラスのスタティックメソッドでテストを行う
Assert.AreEqual
Assert.AreNotEqual
Assert.AreSame
Assert.IsFalse
Assert.IsTrue
Assert.IsNull
Assert.Inconclusive
Assert.IsInstanceOfType
などなど。
例外を投げるメソッドのテストはこんなメソッド作っとくと便利
private E GetException<E>(Action action) where E : Exception
{
try
{
action();
return null;
}
catch (E ex)
{
return ex;
}
}
privateメソッドはどうする?
[この辺いろいろ追記・修正 20151018] 以下の方法がある
- 可視性を
internal
にする PrivateObject, PrivateType
クラスを使う(MSTest)
- リフレクション
可視性を internal
にして private
メンバにアクセス
テスト用プロジェクトからだと private
メソッドにアクセスできないので…
- テスト対象メソッドの
private
をinternal
に変更する AssemblyInfo.cs
に[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("テスト用プロジェクトで生成するアセンブリの名前")]
属性をつける。記述するのはテスト対象となるプロジェクト内であり、テスト用のプロジェクトにはこの記述は必要ない。
これで テスト用のプロジェクトのメソッドに、テスト用のプロジェクトからアクセスできる。 ただし、この方法だと同じプロジェクトからはアクセスできてしまうという問題があるので、 同じプロジェクトからもアクセスされたくなければ別の方法を使うこと。
※以前は プライベートアクセサ を使用していたらしいけど推奨されなくなった?
PrivateObject, PrivateType クラスを使う(MSTest)
使い方は簡単なので割愛。でもこれらのクラスは MSTest
のものなので NUnit
の場合に困ると思われる。
リフレクション
NUnit
でも問題のない方法ならリフレクションを使う。リフレクションの方法はググる。
でも実行がすごくメンドイので Private
メソッド呼び出す自作クラスInvokeUtility
Chaining Assertion
http://chainingassertion.codeplex.com/
ググろう。便利。
protectedメソッドはどうする?
internal protected
にすれば継承しなくてもテストクラスから呼び出せる。
テスト準備用のメソッドを作成するための属性
以下は、Visual Basic 2010
で自動生成されたコードのほぼコピペ
//
//テストを作成するときに、次の追加属性を使用することができます:
//
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
// クラスの最初のテストを実行する前にコードを
// 実行するには、ClassInitialize を使用
}
[ClassCleanup()]
public static void MyClassCleanup()
{
// クラスのすべてのテストを実行した後に
// コードを実行するには、ClassCleanup を使用
}
[TestInitialize()]
public void MyTestInitialize()
{
// 各テストを実行する前にコードを
// 実行するには、TestInitialize を使用
}
[TestCleanup()]
public void MyTestCleanup()
{
// 各テストを実行した後にコードを
// 実行するには、TestCleanup を使用
}
AssemblyInitializeAttribute, AssemblyCleanupAttribute
という属性もある。
TestCategory
テストカテゴリの分類
[TestMethod()]
[TestCategory("カテゴリーF")]
public void てすと()
{
// do something...
}
テスト時にリソースファイルを DeploymentItem
で指定
[追記 20-151018] なんかおかしい
テスト時にファイルを参照したい時のメモなんだけど…こんなことしなくてもいい。 テスト用にファイルを用意するのならテストプロジェクトにファイルを追加して、テストコードから相対パスでアクセスできる。
だったら DeploymentItemAttribute
とはいったい何なのか。
MSDNによると「テスト実行前のアセンブリとともに配置する必要があるディレクトリまたはファイルを指定します。 」とのこと。
参考: .NET - MsTestによるユニットテストの解説 - Qiita
また、外部ファイルを利用する場合は DataSourceAttribute
でCSVやXMLを利用できる。
参考: VS2008の単体テストにてテストデータを外部ファイルから設定する (Visual Studio, 単体テスト, CSV, XML) - いろいろ備忘録日記
[追記おわり]
1. プロジェクトのテスト設定で配置を有効にする
これをしないと DeploymentItem
で配置するリソースを指定しても配置してくれない。
Visual Studio 2010
の
[テスト] -> [テスト設定の編集] -> [ローカル(Local.testsettings)]
でテストの設定を開いて [配置] -> [配置を有効にする] のチェックボックスをON
※テスト設定がない場合はプロジェクト…ではなく ソリューションにテスト設定のファイルを追加すること。
2. DeploymentItem
でリソースを指定する
以下のようにコーディングする。
※Text.txtはプロパティで 「出力先ディレクトリにコピー : 常にコピーする」を指定する。
[TestMethod]
[DeploymentItem("Test.txt")]
public void Test()
{
string text = System.IO.File.ReadAllText("Text.txt");
Assert.AreEqual("http://fernweh.jp", text);
}
※設定が正しいのにうまくいかなかったら Visual Studio を再起動するとうまくいくかも。