MSTest 属性
MSTest 使用自定义属性来标识和自定义测试。
为了帮助提供更清晰的测试框架概述,本部分将 Microsoft.VisualStudio.TestTools.UnitTesting 命名空间的成员组织为相关功能组。
注意
名称以“Attribute”结尾的属性在使用时可以添加或不添加该“Attribute”后缀。 包含无参数构造函数的属性在写入时可以添加或不添加括号。 以下代码示例的工作方式相同:
[TestClass()]
[TestClassAttribute()]
[TestClass]
[TestClassAttribute]
用于标识测试类和方法的属性
每个测试类都必须具有 TestClass
属性,每个测试方法都必须具有 TestMethod
属性。
TestClassAttribute
TestClass 属性用于标记类,该类包含测试和可选的初始化或清理方法。
可以扩展此属性来改变或扩展默认行为。
示例:
[TestClass]
public class MyTestClass
{
}
TestMethodAttribute
TestMethod 属性在 TestClass
内用于定义要运行的实际测试方法。
该方法应该是定义为 public
、void
或 Task
的实例 ValueTask
方法(从 MSTest v3.3 开始)。 它可以是 async
,但不能是 async void
。
该方法应该不带参数,除非它与 [DataRow]
、[DynamicData]
或向测试方法提供测试用例数据的类似属性一起使用。
考虑以下示例测试类:
[TestClass]
public class MyTestClass
{
[TestMethod]
public void TestMethod()
{
}
}
用于数据驱动的测试的属性
使用以下元素设置数据驱动的测试。 有关详细信息,请参阅创建数据驱动的单元测试和使用配置文件定义数据源。
DataRowAttribute
DataRowAttribute
允许使用多个不同的输入运行同一测试方法。 它可以在测试方法上出现一次或多次。 它应与 TestMethodAttribute
结合使用。
参数的数量和类型必须与测试方法签名完全匹配。 请考虑以下有效测试类的示例,该示例演示了 DataRow
属性的用法,以及与测试方法参数一致的内联参数:
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, "message", true, 2.0)]
public void TestMethod1(int i, string s, bool b, float f)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" })]
public void TestMethod2(string[] lines)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(null)]
public void TestMethod3(object o)
{
// Omitted for brevity.
}
[TestMethod]
[DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
public void TestMethod4(string[] input, string[] expectedOutput)
{
// Omitted for brevity.
}
}
注意
还可以使用 params
功能捕获 DataRow
的多个输入。
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2, 3, 4)]
public void TestMethod(params int[] values) {}
}
无效组合的示例:
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2)] // Not valid, we are passing 2 inline data but signature expects 1
public void TestMethod1(int i) {}
[TestMethod]
[DataRow(1)] // Not valid, we are passing 1 inline data but signature expects 2
public void TestMethod2(int i, int j) {}
[TestMethod]
[DataRow(1)] // Not valid, count matches but types do not match
public void TestMethod3(string s) {}
}
注意
从 MSTest v3 开始,当想要传递恰好 2 个数组时,不再需要将第二个数组包装在对象数组中。
此前:[DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })]
从 v3 开始:[DataRow(new string[] { "a" }, new string[] { "b" })]
可以通过设置 DataRowAttribute
属性来修改 Visual Studio 中使用的显示名称以及每个 DisplayName
实例的记录器。
[TestClass]
public class TestClass
{
[TestMethod]
[DataRow(1, 2, DisplayName = "Functional Case FC100.1")]
public void TestMethod(int i, int j) {}
}
还可以通过继承 DataRowAttribute
来创建自己的专用数据行属性。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomDataRowAttribute : DataRowAttribute
{
}
[TestClass]
public class TestClass
{
[TestMethod]
[MyCustomDataRow(1)]
public void TestMethod(int i) {}
}
用于提供初始化和清理的属性
可将多个测试共有的设置和清理提取到单独的方法中,并使用下面列出的属性之一进行标记,以便在适当的时间运行该方法,例如在每次测试之前。 有关详细信息,请参阅单元测试的剖析。
程序集级别
AssemblyInitialize 在加载程序集之后进行调用,AssemblyCleanup 在卸载程序集之前进行调用。
用这些属性标记的方法应在 static void
中定义为 static Task
、static ValueTask
或 TestClass
(从 MSTest v3.3 开始),并且只能出现一次。 初始化部分需要一个类型为 TestContext 的参数,而清理部分则可以不需要参数,或者在使用 MSTest 3.8 及更高版本时,可以包含一个类型为 TestContext的参数。
[TestClass]
public class MyTestClass
{
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext testContext)
{
}
[AssemblyCleanup]
public static void AssemblyCleanup() // Starting with MSTest 3.8, it can be AssemblyCleanup(TestContext testContext)
{
}
}
[TestClass]
public class MyOtherTestClass
{
[AssemblyInitialize]
public static async Task AssemblyInitialize(TestContext testContext)
{
}
[AssemblyCleanup]
public static async Task AssemblyCleanup() // Starting with MSTest 3.8, it can be AssemblyCleanup(TestContext testContext)
{
}
}
类级别
ClassInitialize 在加载类之前(但在静态构造函数之后)进行调用,而 ClassCleanup 在卸载类之后进行调用。
可以控制继承行为:仅适用于使用 InheritanceBehavior.None
的当前类或使用 InheritanceBehavior.BeforeEachDerivedClass
的所有派生类。
还可以配置是在类结束时还是在程序集结束时运行类清理。
用这些属性标记的方法应在 static void
中定义为 static Task
、static ValueTask
或 TestClass
(从 MSTest v3.3 开始),并且只能出现一次。 初始化部分需要一个类型为 TestContext 的参数,而清理部分则可以不需要参数,或者在使用 MSTest 3.8 及更高版本时,可以包含一个类型为 TestContext的参数。
[TestClass]
public class MyTestClass
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
}
[ClassCleanup]
public static void ClassCleanup() // Starting with MSTest 3.8, it can be ClassCleanup(TestContext testContext)
{
}
}
[TestClass]
public class MyOtherTestClass
{
[ClassInitialize]
public static async Task ClassInitialize(TestContext testContext)
{
}
[ClassCleanup]
public static async Task ClassCleanup() // Starting with MSTest 3.8, it can be ClassCleanup(TestContext testContext)
{
}
}
测试级别
TestInitialize 在测试开始之前进行调用,而 TestCleanup 在测试完成之后进行调用。
TestInitialize
类似于类构造函数,但通常更适合长初始化或异步初始化。 TestInitialize
始终在构造函数之后进行调用,并针对每个测试(包括数据驱动测试的每个数据行)调用一次。
TestCleanup
类似于 Dispose
(或 DisposeAsync
)类,但通常更适合长时间或异步清理。 TestCleanup
始终在 DisposeAsync
/Dispose
之前进行调用,并针对每个测试(包括数据驱动测试的每个数据行)调用一次。
用这些属性标记的方法应在 void
中定义为 Task
、ValueTask
或 TestClass
(从 MSTest v3.3 开始),不带参数,并且可以出现一次或多次。
[TestClass]
public class MyTestClass
{
[TestInitialize]
public void TestInitialize()
{
}
[TestCleanup]
public void TestCleanup()
{
}
}
[TestClass]
public class MyOtherTestClass
{
[TestInitialize]
public async Task TestInitialize()
{
}
[TestCleanup]
public async Task TestCleanup()
{
}
}
用于控制测试执行的属性
以下属性可用于修改测试的执行方式。
TimeoutAttribute
Timeout 属性可用于指定测试方法允许运行的最长时间(以毫秒为单位)。 如果测试方法的运行时间超过指定时间,则测试将中止并标记为失败。
此属性可应用于任何测试方法或任何固定例程方法(初始化和清理方法)。 还可以使用 runsettings 文件的 timeout 属性为所有测试方法或所有测试固定例程方法全局指定超时。
注意
无法保证超时是精确的。 在指定的时间过后,测试将会中止,但也可能会多持续几毫秒时间。
使用超时功能时,将创建一个单独的线程/任务来运行测试方法。 主线程/任务负责监视超时,如果达到超时,则取消观察方法线程/任务。
从 MSTest 3.6 开始,可以在属性上指定 CooperativeCancellation
属性(或通过 runsettings 文件全局指定)以启用协作取消。 在此模式下,该方法将负责检查取消令牌,并在收到信号时中止测试,就像在典型的 async
方法中所做的那样。 此模式的性能更佳,并让你可以对取消过程进行更精确的控制。 此模式可应用于异步方法和同步方法。
STATestClassAttribute
应用于测试类时,[STATestClass]
属性表示类中的所有测试方法(以及 [ClassInitialize]
和 [ClassCleanup]
方法)都应在单线程单元 (STA) 中运行。 当测试方法与需要 STA 的 COM 对象交互时,此属性非常有用。
注意
这仅在 Windows 以及版本 3.6 及更高版本中受支持。
STATestMethodAttribute
应用于测试方法时,[STATestMethod]
属性表示测试方法应在单线程单元 (STA) 中运行。 当测试方法与需要 STA 的 COM 对象交互时,此属性非常有用。
注意
这仅在 Windows 以及版本 3.6 及更高版本中受支持。
ParallelizeAttribute
默认情况下,MSTest 按顺序运行测试。 Parallelize 属性可用于并行运行测试。 这是一个程序集级别的属性。 可以指定并行度应处于类级别(多个类可以并行运行,但给定类中的测试将按顺序运行)还是方法级别。
还可以指定用于并行执行的最大线程数。 值 0
(默认值)表示线程数等于计算机上的逻辑处理器数。
还可以通过 runsettings 文件的 parallelization 属性指定并行度。
DoNotParallelizeAttribute
DoNotParallelize 属性可用于防止在给定的程序集中并行执行测试。 此属性可以在程序集级别、类级别或方法级别应用。
注意
默认情况下,MSTest 按顺序运行测试,因此,仅当你在程序集级别应用了 [Parallelize]
属性时,才需要使用此属性。
实用工具属性
DeploymentItemAttribute
MSTest 框架引入了 DeploymentItemAttribute,用于将指定为部署项的文件或文件夹复制到部署目录(无需添加所复制文件在项目文件夹内的 TestResults 文件夹中的自定义输出路径)。 部署目录是所有部署项以及测试项目 DLL 所在的位置。
它既可以用于测试类(标有 TestClass
属性的类),也可以用于测试方法(标有 TestMethod
属性的方法)。
用户可以使用多个属性实例来指定多个项。
可在此处查看其构造函数。
示例
[TestClass]
[DeploymentItem(@"C:\classLevelDepItem.xml")] // Copy file using some absolute path
public class UnitTest1
{
[TestMethod]
[DeploymentItem(@"..\..\methodLevelDepItem1.xml")] // Copy file using a relative path from the dll output location
[DeploymentItem(@"C:\DataFiles\methodLevelDepItem2.xml", "SampleDataFiles")] // File will be added under a SampleDataFiles in the deployment directory
public void TestMethod1()
{
string textFromFile = File.ReadAllText("classLevelDepItem.xml");
}
}
警告
不建议使用此属性将文件复制到部署目录。
ExpectedExceptionAttribute
MSTest 框架引入了 ExpectedExceptionAttribute,用于标记测试方法以指示预期会发生特定类型的异常。 如果引发了预期的异常并且异常消息与预期消息匹配,则测试将会通过。
警告
保留此属性是为了后向兼容,不建议用于新测试。 请改用 Assert.ThrowsException
方法(如果使用 MSTest 3.8 及更高版本,请改用 Assert.ThrowsExactly
)。
元数据特性
以下属性和分配给它们的值会出现在特定测试方法的 Visual Studio
“属性”窗口中。 不应通过测试代码访问这些属性。 相反,它们会影响使用或运行测试的方式(由你通过 Visual Studio IDE 使用或运行,或由 Visual Studio 测试引擎使用或运行)。 例如,其中一些属性在测试管理器 窗口和测试结果窗口中显示为列,这意味着可以使用它们对测试和测试结果进行分组和排序。 TestPropertyAttribute 就是这样的一个属性,它用于将任意元数据添加到测试。
例如,可以通过使用 [TestProperty("Feature", "Accessibility")]
标记测试,来使用该属性存储此测试所涵盖的“测试轮次”的名称。 还可以使用它存储其所属的测试类型的指示器:[TestProperty("ProductMilestone", "42")]
。 使用此特性创建的属性以及分配的属性值都会显示在 Visual Studio属性窗口中的标题测试特定的下。
- DescriptionAttribute
- IgnoreAttribute
- OwnerAttribute
- PriorityAttribute
- TestCategoryAttribute
- TestPropertyAttribute
- WorkItemAttribute
以下属性将它们修饰的测试方法与 Team Foundation Server
团队项目的项目层次结构中的实体相关联: