C# VS团队测试:测试类中有多个测试初始化方法
我在TeamTest中有一个名为“MyClassTest”的单元测试项目。这个项目有三种测试方法。每个方法都需要自己的测试初始化步骤。但是当我将TestInitializeAttribute应用于三种初始化方法时,它表示该属性不应被多次使用。那么,在VisualStudioTeamTest中,用于初始化每个测试方法的属性应该是什么 参考:C# VS团队测试:测试类中有多个测试初始化方法,c#,.net,visual-studio-2010,unit-testing,C#,.net,Visual Studio 2010,Unit Testing,我在TeamTest中有一个名为“MyClassTest”的单元测试项目。这个项目有三种测试方法。每个方法都需要自己的测试初始化步骤。但是当我将TestInitializeAttribute应用于三种初始化方法时,它表示该属性不应被多次使用。那么,在VisualStudioTeamTest中,用于初始化每个测试方法的属性应该是什么 参考: 如果他们需要三个独立的初始化;然后,他们可能会在三个单独的装置中,每个装置都有自己的init 根据TestInitializeAttribute:
如果他们需要三个独立的初始化;然后,他们可能会在三个单独的装置中,每个装置都有自己的init 根据
TestInitializeAttribute
:
- 不能多次使用(AllowMultiple=false),并且
- 无法继承以创建自己的
TestInitializeAttribute
TestInitialize
属性的测试初始化方法。然后在唯一的TestInitialize
方法检查中,检查当前执行的TestMethod
并调用相应的初始化方法:
[TestClass]
public class UnitTest
{
public TestContext TestContext { get; set; }
[TestInitialize]
public void Initialize()
{
switch (TestContext.TestName)
{
case "TestMethod1":
this.IntializeTestMethod1();
break;
case "TestMethod2":
this.IntializeTestMethod2();
break;
default:
break;
}
}
[TestMethod]
public void TestMethod1()
{
}
[TestMethod]
public void TestMethod2()
{
}
public void IntializeTestMethod1()
{
//Initialize Test Method 1
}
public void IntializeTestMethod2()
{
//Initialize Test Method 2
}
}
如果您有三个测试方法,并且每个方法都有自己的初始化步骤,那么为什么要将初始化移到每个测试之前运行的方法?我看到的唯一好处是漂亮的开关块,它在源文件中添加了一些行。但它给了您一个缺点——查看这些测试方法中的任何一种,您都无法真正判断将在哪个上下文方法中执行。所以,我使用初始化方法只设置基本上下文,该上下文实际上由fixture中的所有测试使用 只需将上下文创建移动到每个方法的
arrange
部分
如果您有几个使用公共上下文的方法,那么只需提取方法,它将为它们设置上下文,并在arrange
部分调用它。您还可以将每个上下文设置拆分为几个步骤并重用这些步骤(就像在给定的When-Then工具中所做的那样)
当然,创建不同的固定装置也是一个选择。这是一篇有点老的文章,但我提出了以下几点,似乎还可以: 首先,定义一个属性类:
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class InitialiseWithAttribute : Attribute
{
public string Id { get; private set; }
public InitialiseWithAttribute(string id)
{
Id = id;
}
}
然后在一些方便的实用程序类中定义一个扩展方法:
public static bool IsInitialisedWith(this string testName, string value)
{
bool result = false;
Type testClassType = new StackFrame(1).GetMethod().DeclaringType;
MethodInfo methodInfo = testClassType.GetMethod(testName);
if (methodInfo != null)
{
InitialiseWithAttribute initialiseWithAttribute =
methodInfo.GetCustomAttribute<InitialiseWithAttribute>(true);
if (initialiseWithAttribute != null)
{
result = initialiseWithAttribute.Id == value;
}
}
return result;
}
在我的工作中,我们传入一个参数来TestInitialize方法,以确定我们希望初始化如何工作
public partial class CommonActions
{
public void TestInitialize(bool adminTest)
{
try
{
if (adminTest)
{
//do stuff
}
然后,我们在类定义中有一个标准初始化,默认为false
[TestClass]
public class ProjectTestBase : FrameworkTestBase
{
public CommonActions common { get; set; } = new CommonActions();
[TestInitialize]
public void TestInitialize() => common.TestInitialize(false);
然后,在测试用例本身中,您可以覆盖您想要的任何测试的TestInitialize
[TestClass]
public class SetReportsInAdmin : ProjectTestBase
{
[TestInitialize]
public new void TestInitialize() => common.TestInitialize(true);
我们使用一个布尔值来判断是否进行管理测试,这需要额外的设置开销。采用这种方法,并应用您想要的任何变量,通过使用一种方法,该方法将为您提供多个初始化 谢谢。这似乎是可行的。这是人们遵循的标准实践吗?这是我的团队遵循的实践。我不知道还有没有更好的方法:)
AllowMultiple=false
只在同一个元素中强制使用单一用法。。。这意味着单个方法不能标记为多个TestInitializeAttribute
。不能在不同的方法上使用它的规则与AllowMultiple=false
无关。虽然这是可行的,但它的缺点是,如果测试名称被重构,并且魔法字符串没有更新,测试就会中断。为什么初始化不能成为测试“安排”部分的一部分(即,如果多个测试需要相同的初始化,则在测试体或私有方法中)?然后可以从测试中的try..finally块启动清理。我个人这样做,到目前为止效果很好。那应该很好。你看到什么缺点了吗?没有。。不是真的。只要这三个测试在逻辑上是相关的。我个人。。我会把它分成三场比赛,但这是我个人的偏好。上面的看起来不错。之后是否也需要执行测试清理?可以使用相同的方法吗?在通过集成测试进行负载测试的范围内,例如在WCF服务层的负载测试中,您希望测试方法尽可能干净,因为测试方法的执行时间是要跟踪的。在这种情况下,将所有初始化逻辑移动到testinitialize是唯一的方法@戴维德罗德里格斯不仅如此。您可以为正在测试的每个功能创建单独的TestFixture类。这将是非常简单的,它的设置方法将不会有任何开关块。我也会使用SpecFlow之类的东西进行验收测试。有一些很好的方法,它们组织得很好,可以重用。SpecFlow将所有步骤的执行时间写入输出窗口
[TestClass]
public class SetReportsInAdmin : ProjectTestBase
{
[TestInitialize]
public new void TestInitialize() => common.TestInitialize(true);