通过


使用 MSTest 编写测试

在本文中,你将了解 MSTest 用来帮助你编写和塑造测试的 API 和约定。

注意

以“Attribute”结尾的属性名称可以使用短格式。 TestClass 并且 TestClassAttribute 是等效的。 具有无参数构造函数的属性可以省略括号。

测试结构

每个 MSTest 测试类都必须具有 TestClass 该属性,并且每个测试方法都必须具有该 TestMethod 属性:

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class CalculatorTests
{
    [TestMethod]
    public void Add_TwoNumbers_ReturnsSum()
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        var result = calculator.Add(2, 3);

        // Assert
        Assert.AreEqual(5, result);
    }
}

TestClassAttribute

标记 TestClassAttribute 包含测试和(可选)初始化或清理方法的类。 可以扩展此属性以自定义测试类行为。

TestMethodAttribute

TestMethodAttribute 方法标记为要运行的测试。 测试方法必须是:

  • 实例方法(非静态)
  • 公众
  • 返回voidTaskValueTask (MSTest v3.3+)
  • 无参数,除非使用 数据驱动属性
[TestClass]
public class TestMethodExamples
{
    [TestMethod]
    public void SynchronousTest()
    {
        Assert.IsTrue(true);
    }

    [TestMethod]
    public async Task AsynchronousTest()
    {
        await Task.Delay(100);
        Assert.IsTrue(true);
    }
}

警告

请勿在测试方法中使用async void。 请改用 async Taskasync ValueTask

DiscoverInternalsAttribute

程序集 DiscoverInternalsAttribute 属性使 MSTest 能够发现 internal 测试类和方法。 默认情况下,仅发现 public 测试。 如果参数化测试使用内部类型作为参数,则此属性特别有用:

[assembly: DiscoverInternals]

internal record TestInput(int Value, string Description);

[TestClass]
public class CalculatorTests
{
    internal static IEnumerable<TestInput> TestData
    {
        get
        {
            yield return new TestInput(1, "one");
            yield return new TestInput(2, "two");
        }
    }

    [TestMethod]
    [DynamicData(nameof(TestData))]
    internal void Add_WithTestInput_ReturnsExpected(TestInput input)
    {
        var calculator = new Calculator();
        var result = calculator.Add(input.Value, 1);
        Assert.AreEqual(input.Value + 1, result);
    }
}

如果没有 DiscoverInternals,测试方法及其内部 TestInput 参数类型将不会由测试运行程序发现。

核心概念

MSTest 文档按主题进行组织:

主题 Description
断言 使用 Assert 类验证预期结果
数据驱动的测试 使用多个输入运行测试(DataRowDynamicData
测试生命周期 程序集、类和测试级别的设置与清理
执行控件 线程处理、并行化、超时、重试和条件执行
测试组织 类别、优先级、所有者和元数据
TestContext 访问测试运行时信息

属性快速参考

类别 特性 请参阅
测试标识 TestClassTestMethodDiscoverInternals 此页面
数据驱动 DataRowDynamicDataTestDataRow 数据驱动的测试
Lifecycle AssemblyInitializeClassInitializeTestInitialize和清理对应项 测试生命周期
线程 STATestClassSTATestMethodUITestMethod 执行控件
并行化 ParallelizeDoNotParallelize 执行控件
超时/重试 TimeoutRetry 执行控件
有條件的 IgnoreOSConditionCICondition 执行控件
Metadata TestCategoryTestPropertyOwnerPriority 测试组织
跟踪工作 WorkItemGitHubWorkItem 测试组织

断言

使用 Microsoft.VisualStudio.TestTools.UnitTesting 命名空间的 Assert 类来验证特定功能。 测试方法在应用程序中执行代码,只有当包含 Assert 语句时才报告正确性。

MSTest 断言分为:

  • Assert:通用断言(AreEqualIsTrueThrowsException
  • StringAssert:特定于字符串的断言(Contains、、MatchesStartsWith
  • CollectionAssert:集合断言(ContainsAllItemsAreUniqueAreEquivalent

测试私有成员

可以使用反射包装类测试专用成员:

小窍门

考虑专用方法是否需要直接测试。 通常,通过公共接口进行测试可提供更好的覆盖范围和更易于维护的测试。

另请参阅