NUnit2.6の新機能:Action属性クラス
(サンプルコード:「新機能_Action属性クラス」クラス)
Action
属性というのは、Attribute
クラスを継承し、NUnitのITestAction
インターフェースを実装して自分で作る属性クラスです。
テストクラス・テストメソッドごとに自由に設定できる共通の前処理・後処理を書くことができます。SetUp
/TearDown
属性では、すべてのメソッドで同じ前処理・後処理が実行されてしまいますが、Action
属性では、属性を付けたメソッドだけでその前処理・後処理が実行されます。
Action
属性クラスは次のように書きます。
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)] public class MyDefaultActionAttribute : Attribute, ITestAction { private string _message; public MyDefaultActionAttribute(string message) { _message = message; } // 属性を付けたテストが実行される直前に呼び出される public void BeforeTest(TestDetails details) { if (details.IsSuite) WriteToConsole("◇MyDefaultAction - TestFixtureSetUp", details); else WriteToConsole("◇MyDefaultAction - SetUp", details); } // 属性を付けたテストが実行された直後に呼び出される public void AfterTest(TestDetails details) { if (details.IsSuite) WriteToConsole("◇MyDefaultAction - TestFixtureTearDown", details); else WriteToConsole("◇MyDefaultAction - TearDown", details); } public ActionTargets Targets { get { return ActionTargets.Default; } } private void WriteToConsole(string eventMessage, TestDetails details) { Console.WriteLine("{0} {1}: {2}, from {3}.{4}.", eventMessage, details.IsSuite ? "Suite" : "Case", _message, details.Fixture != null ? details.Fixture.GetType().Name : "{no fixture}", details.Method != null ? details.Method.Name : "{no method}" ); } }
こうして作ったAction
属性は、次のように使えます。
[TestFixture] [MyDefaultAction("テストクラスに付けた")] public class 新機能_Action属性クラス { [Test] public void Test01_加算() { Console.WriteLine("■ Test01_加算"); Assert.That(整数.加算する(1, 2), Is.EqualTo(3)); } [MyDefaultAction("Test02_偶奇判定")] [TestCase(1, false)] [TestCase(2, true)] public void Test02_偶奇判定_TestCase属性で複数回実行(int n, bool expected) { Console.WriteLine("■ Test02_偶奇判定"); Assert.That(整数.Is偶数(n), Is.EqualTo(expected)); } [TestFixtureSetUp] public void TestFixtureSetUp() { Console.WriteLine("通常の TestFixtureSetUp"); } [TestFixtureTearDown] public void TestFixtureTearDown() { Console.WriteLine("通常の TestFixtureTearDown"); } [SetUp] public void SetUp() { Console.WriteLine("通常の SetUp"); } [TearDown] public void TearDown() { Console.WriteLine("通常の TearDown"); } }
この実行結果は、次のようになります(読みやすいように空行を入れた)。
通常の TestFixtureSetUp ◇MyDefaultAction - TestFixtureSetUp Suite: テストクラスに付けた, from 新機能_Action属性クラス.{no method}. ***** CsTdd03Tests.新機能_Action属性クラス.Test01_加算 通常の SetUp ■ Test01_加算 通常の TearDown ***** CsTdd03Tests.新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行(1,False) 通常の SetUp ◇MyDefaultAction - SetUp Case: Test02_偶奇判定, from 新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行. ■ Test02_偶奇判定 ◇MyDefaultAction - TearDown Case: Test02_偶奇判定, from 新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行. 通常の TearDown ***** CsTdd03Tests.新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行(2,True) 通常の SetUp ◇MyDefaultAction - SetUp Case: Test02_偶奇判定, from 新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行. ■ Test02_偶奇判定 ◇MyDefaultAction - TearDown Case: Test02_偶奇判定, from 新機能_Action属性クラス.Test02_偶奇判定_TestCase属性で複数回実行. 通常の TearDown ◇MyDefaultAction - TestFixtureTearDown Suite: テストクラスに付けた, from 新機能_Action属性クラス.{no method}. 通常の TestFixtureTearDown
まとめ
最新版のNUnitの機能を紹介しましたが、いかがだったでしょうか。あまりにも多機能で、テストを書くときにどの機能を使えばよいか迷うかもしれません。しかし最初に述べたように、どんなテストだってIsTrue()
だけ知っていれば書けますから、あとは少しずつ覚えていけばよいのです。
NUnitの豊富な機能は、メンテナンスしやすいテストコードを簡潔に書くためにあります。ほとんどの機能は知らなくてもどうということはありませんが、知っていれば、より良いテストコードをすばやく書く助けになることでしょう。テストコードをリファクタリングしたくなった時には、本記事を思い出してください。