もくじ
https://tera1707.com/entry/2022/02/06/144447#UnitTest
やりたいこと
WinUI3のexeの中のpublicなものをUnitTestしようと思うと、いつも使っていたMsTest(vstest.console.exe)でテスト実行がどうしてもできなかった。
で、代替を探していたら、NUnitというものを知った。
せっかくNUnitを使ったので、使い方をまとめておく。
前提
- Windows10 Home 21H1 19043.1706
- VisualStudio2022 Community 17.1.4
- Windows App SDK 1.0
- NUnitで単体テスト実施
- 2022年6月の時点の調査
NUnit使い方
プロジェクトの追加で、C#の「NUnit テストプロジェクト」を追加する。
追加したプロジェクトの「UnitTest1.cs」に、テストコードを追加する。(ほかのcsファイルを追加して、そこに書いても当然OK)
NUnitで使うアトリビュート
つけるところ | アトリビュート | 説明 |
---|---|---|
テストクラス | [TestFixture] |
テスト対象のクラスにつける |
[SetUpFixture] |
テスト全体の最初or最後に動くメソッド([OneTimeSetUp] or[OneTimeTearDown] )を含むクラスにつける |
|
テストメソッド | [OneTimeSetUp] |
テストクラスの最初に一回だけ実行するテストメソッドにつける。[SetUpFixture] がついたテストクラスの中にこれを書いた場合は、テスト全体の最初に一回だけ実行される。 |
[OneTimeTearDown] |
テストクラスの最後に一回だけ実行するテストメソッドにつける。[SetUpFixture] がついたテストクラスの中にこれを書いた場合は、テスト全体の最後に一回だけ実行される。 |
|
[SetUp] |
各テストメソッドの前に毎回実行されるメソッドにつける。 | |
[TearDown] |
各テストメソッドの後に毎回実行されるメソッドにつける。 | |
[TestCase(1, "AAA")] |
テストメソッドに引数を渡して、同じテストロジックで複数テストを実行するためのメソッドにつける。 | |
[TestCaseSource(nameof(Test4Args))] |
テストメソッドの引数として、変数を使う場合につける。 |
各アトリビュートの具体例は下を参照。
NUnitひな型(部品どり)
using System.Diagnostics; namespace TestProject { [TestFixture] public class Tests { [OneTimeSetUp] public void OneTimeSetUp() { // テストクラスの最初に一回実施 Debug.WriteLine("OneTimeSetUp"); } [OneTimeTearDown] public void OneTimeTearDown() { // テストクラスの最後に一回実施 Debug.WriteLine("OneTimeTearDown"); } [SetUp] public void Setup() { // [Test]の前に毎回実施 Debug.WriteLine("Setup"); } [TearDown] public void TearDown() { // [Test]の後に毎回実施 Debug.WriteLine("TearDown"); } [Test] public void Test1() { Debug.WriteLine("Test1"); } [Test] public void Test2() { Debug.WriteLine("Test2"); } [TestCase(1, "AAA")]// ここの引数の数とメソッドの引数の数が一致していないとエラーにしてくれる [TestCase(2, "BBB")] public void Test3(int arg1, string arg2) { Debug.WriteLine($"Test3 {arg1}, {arg2}"); } static object[] Test4Args = { new object[] { 10, "aaaaa"}, new object[] { 20, "bbbbb"}, }; [TestCaseSource(nameof(Test4Args))] public void Test4(int arg1, string arg2) { Debug.WriteLine($"Test4 {arg1}, {arg2}"); } } [TestFixture] public class Test2 { [Test] public void Test1inTest2() { Debug.WriteLine("Test1inTest2"); } } [SetUpFixture] public class TestSetupFixture { [OneTimeSetUp] public void RunBeforeAnyTests() { Debug.WriteLine("RunBeforeAnyTests"); } [OneTimeTearDown] public void RunAfterAnyTests() { Debug.WriteLine("RunAfterAnyTests"); } } }
実行結果(どのアトリビュートを付けたらどういうタイミングで実行されるか、の参考に。)
RunBeforeAnyTests Test1inTest2 OneTimeSetUp Setup Test1 TearDown Setup Test2 TearDown Setup Test3 1, AAA TearDown Setup Test3 2, BBB TearDown Setup Test4 10, aaaaa TearDown Setup Test4 20, bbbbb TearDown OneTimeTearDown RunAfterAnyTests
使ってみた感想
何となくだが、MSTestより、公式ページの説明がわかりやすい?気がする。
(自分が、今まで使ってたMSTestでのUTの経験値で呑み込みが早くなってただけかもだが、何となくそう感じた)
あとTestCase
を使ってるときに思ったが、[TestCase(1, "AAA")]
に書いた引数とテストメソッドpublic void Test3(int arg1, string arg2)
に書いた引数の型があってなかったらエラーが出てくれた。
たしか、MSTestだったらエラー出ずに実行時によくわからないエラーで怒られたような気がする。(記憶によるので、違ってるかも)
→何となく、NUnitの方が多少使いやすいかも?と感じた。
開発環境の制約でNUnit使えない、とかが無ければ、NUnit使ってみようかなという気になった。
参考
NUnit公式。classやメソッドの頭につけるアトリビュート等はここに書いてある
https://docs.nunit.org/articles/nunit/writing-tests/attributes/apartment.html
MSDocsのNUnitページ
https://docs.microsoft.com/ja-jp/dotnet/core/testing/unit-testing-with-nunit