我有一个方法
using Microsoft.VisualStudio.TestTools.UnitTesting; // using visual studio's test framework
[TestMethod]
public void ATestMethod()
{
// stuff
}
来自public class ATestClass
。该测试类运行两种类型的测试:
- 测试要求在运行测试的计算机上安装某个软件
- 可以免费运行的测试
为了处理此问题,我添加了一个public class BaseTestClass
,从中我制作了ATestClass
,在ATestClass
中,我添加了A:
public bool isTheSoftwareInstalledOnTheMachine()
{
// stuff
}
和我"装饰"了ATestClass
的所有内部测试范围,如下:
[TestMethod]
public void ATestMethod()
{
if (isTheSoftwareInstalledOnTheMachine())
{
// stuff
}
}
我觉得这太可怕了。我宁愿能够写出类似的东西:
[TestMethod]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// stuff
}
,但我不知道是否允许有人定义"自定义" [characterizer]
'S。(我什至不知道适合他们的词。)如果是,那是最好的设计吗?(我听说了装饰器的模式,但是我不知道我是否可以在上下文中使其足够通用,因为我可能需要在许多其他测试课程中使用该条件。)无论如何,我如何继续使用characterizer
's?
我知道您正在使用VS测试框架,但是如果您可以更改为Nunit,则可以完成您想要的。
测试用例:
using NUnit.Framework;
[TestFixture]
public class MyAppTests
{
[Test]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// Executes if custom attribute is true, otherwise test case is ignored
}
}
自定义属性:
using NUnit.Framework;
using NUnit.Framework.Interfaces;
public class TestHelper
{
public static bool IsTheSoftwareInstalledOnTheMachine()
{
// Return state of software
return true;
}
}
public class RunIfTheSoftwareInstalledOnTheMachineAttribute : Attribute, ITestAction
{
public ActionTargets Targets { get; private set; }
public void AfterTest(ITest test) {}
public void BeforeTest(ITest test)
{
if (!TestHelper.IsTheSoftwareInstalledOnTheMachine())
{
Assert.Ignore("Omitting {0}. Software is not installed on machine.", test.Name);
}
}
}
如果您定义自己的属性,则必须自行使用检查。您无法期望您的框架猜测该属性的用途。
但我想您甚至不需要一个属性来执行此操作。您可以通过将逻辑在内部放置进行
来忽略测试。[Test]
public void MyTest()
{
if(!RunIfTheSoftwareInstalledOnTheMachine)
Assert.Ignore("Test not run because no software was installed");
// your actual test-code
}
另一种方法是使用Nunit提供的CategoryAttribute
,您只能运行那些属于您提供的类别的测试:
[Test]
[Category("SoftwareInstalled")]
public void MyTest() { /* ... */ }
编辑:您也可以使用TestCaseAttribute
使用特定方法,该方法在满足条件时返回TestCase
:
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData();
}
如果未达到编码,根本没有生成测试柜。
如果要在计算机上安装的软件是测试的任何的要求,并且任何一个测试失败意味着整个套件失败,那么为什么要打扰检查在多个测试中是否已安装软件?只需写一个单测试即可失败,如果软件未安装并抛出有用的例外。类似:
[Test]
public void EnsureImportantSoftwareIsInstalled()
{
if(!importantSoftwareIsInstalled)
{
Assert.Fail($"Software X must be installed for the tests in {nameof(MyTestClass)} to run, please install it");
}
}
对于nunit 2.6,himbrombeere答案的略有变化对我来说很好。测试案例显示为忽略。
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData().Ignore();
}