テストにタグ付けできるいくつかのカスタム属性に基づいて、メソッドを拡張NUnitTestMethod
およびオーバーライドして、テストに関する詳細情報を提供するアドインを作成しています。RecordException()
[Test]
これまでのところ、拡張機能を使用して属性でマークされた個々のテストを拡張するアドインを作成することに成功しましたITestDecorator
。[TestCase()]
パラメータ化された属性でマークされたテストケースに対して同じことをしようとすると、問題が発生します。この場合、NUnit はいわゆる を作成しParametrizedMethodSuite
、NUnitTestMethod から継承するクラスをそのようなスイートに注入する方法を見つけることができないようです。
しばらく前に NUnit メーリング リストに質問を投稿しましたが、何の回答も得られませんでした。たぶん、同じ問題に遭遇したNUnitの達人が私を助けてくれるでしょうか?
私のプロジェクトのコード例については、NUnit メーリング リストの投稿を参照してください:
https://groups.google.com/d/topic/nunit-discuss/dZW0Nc8N2LM/discussion
編集:
NUnit ソース コードを詳しく調べた後、別の方法ではありますが、目的を達成する方法を最終的に見つけました。
私が見る限り、派生クラスのプライベート引数構造にアクセスできないため、それらを設定できないため、ParameterizedMethodSuite
継承する独自のテストメソッドを設定することは不可能です。
メソッドを拡張してオーバーライドすることになり
、一貫性のためにクラスから返されたその後の変更により、拡張するとメソッドもオーバーライドされるようになりました。NUnitTestMethod
ParameterizedMethodSuite
Run()
TestResult
base.Run()
NUnitTestMethod
Run()
その過程で、興味深い例外も発見しました。TestResult.StackTrace
それは、setter があるのにTestResult.Message
ないということです。実際にメッセージを変更する必要があったため、SetResult()
メソッドを調べてすべてを更新する必要がありました。
[NUnitAddin(Name = "Custom Tag Attribute Decorator", Description = "Outputs additional information for tests tagged with custom attributes.")]
public class TagDecorator : ITestDecorator, IAddin
{
public Test Decorate(Test test, MemberInfo member)
{
List<Attribute> tags = Reflect.GetAttributes(member, false).OfType<ITestTag>().Cast<Attribute>().ToList();
if (tags.Count == 0)
{
return test;
}
if (test is NUnitTestMethod)
{
return new TestMethodExtension((test as NUnitTestMethod).Method, tags);
}
if (test is ParameterizedMethodSuite)
{
ParameterizedMethodSuite suite = test as ParameterizedMethodSuite;
ParameterizedMethodSuiteExtension outputSuite = new ParameterizedMethodSuiteExtension(member as MethodInfo, tags);
NUnitFramework.ApplyCommonAttributes(member, outputSuite);
outputSuite.RunState = suite.RunState;
outputSuite.IgnoreReason = suite.IgnoreReason;
foreach (NUnitTestMethod testMethod in suite.Tests)
{
outputSuite.Add(testMethod);
}
return outputSuite;
}
return test;
}
public bool Install(IExtensionHost host)
{
IExtensionPoint testDecorators = host.GetExtensionPoint("TestDecorators");
if (testDecorators == null)
return false;
testDecorators.Install(this);
return true;
}
}
public static class TagExtensionHandler
{
public static void ModifyTestResult(TestResult testResult, List<Attribute> tags)
{
StringBuilder message = new StringBuilder();
message.AppendLine("Related to:");
foreach (ITestTag taggedAttrib in tags.OfType<ITestTag>().Select(attrib => attrib))
{
message.Append(" ");
message.AppendLine(taggedAttrib.GetInfo());
message.AppendLine();
}
message.AppendLine();
message.Append(testResult.Message);
testResult.SetResult(testResult.ResultState, message.ToString(), testResult.StackTrace, testResult.FailureSite);
}
}
public class ParameterizedMethodSuiteExtension : ParameterizedMethodSuite
{
private readonly List<Attribute> _tags;
public ParameterizedMethodSuiteExtension(MethodInfo method, List<Attribute> tags)
: base(method)
{
_tags = tags;
}
public override TestResult Run(EventListener listener, ITestFilter filter)
{
TestResult result = base.Run(listener, filter);
foreach (TestResult subResult in result.Results)
{
TagExtensionHandler.ModifyTestResult(subResult, _tags);
}
return result;
}
}
public class TestMethodExtension : NUnitTestMethod
{
private readonly List<Attribute> _tags;
public TestMethodExtension(MethodInfo methodInfo, List<Attribute> tags)
: base(methodInfo)
{
_tags = tags;
}
public override TestResult Run(EventListener listener, ITestFilter filter)
{
TestResult result = base.Run(listener, filter);
TagExtensionHandler.ModifyTestResult(result, _tags);
return result;
}
}