借助 .NET Core 中的 dotnet test 命令,可以使用筛选表达式来运行选定的测试。 本文演示如何筛选测试。 本示例使用 dotnet test。 如果使用的是 vstest.console.exe,请将 --filter 替换成 --testcasefilter:。
Note
--filter以下部分中介绍的语法适用于 MSTest、NUnit 和 xUnit。 TUnit 使用不同的语法;有关详细信息,请选择本文顶部的 TUnit 。
语法
dotnet test --filter <Expression>
表达式的格式为 。
表达式可与布尔运算符结合使用:
|表示 or 布尔运算符, 表示 and 布尔运算符 。表达式可以用括号括起来。 例如:
(Name~MyClass) | (Name~MyClass2)。没有任何运算符的表达式被解释为 属性上的 contains 。 例如,
dotnet test --filter xyz和dotnet test --filter FullyQualifiedName~xyz相同。属性是 的一个特性。 例如,常用单元测试框架支持以下属性。
测试框架 支持的属性 MSTest FullyQualifiedNameNameClassNamePriorityTestCategoryIdNUnit FullyQualifiedNameNamePriorityTestCategoryCategoryPropertyxUnit FullyQualifiedNameDisplayNameTraits运算符
-
=完全匹配 -
!=非完全匹配 -
~包含 -
!~不包含
-
值是一个字符串。 所有查找都不区分大小写。
字符转义
使用转义序列表示筛选器值中的筛选器运算符字符。 这些转义序列与 shell 所需的任何转义序列分开。
| 转义序列 | 表示 |
|---|---|
\\ |
\ |
\( |
( |
\) |
) |
\& |
& |
\| |
| |
\= |
= |
\! |
! |
\~ |
~ |
若要以编程方式转义筛选器值,请使用 Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.FilterHelper.Escape NuGet 包中的 Microsoft.VisualStudio.TestPlatform.ObjectModel API。
若要在筛选表达式中使用感叹号 (!),必须在 Linux 或 macOS shell 中对其进行转义,具体做法是在前面加一个反斜杠 (\!)。 例如,以下筛选器跳过包含 IntegrationTests 的命名空间中的所有测试:
dotnet test --filter FullyQualifiedName\!~IntegrationTests
对于包含泛型类型参数的逗号的 FullyQualifiedName 值,请使用 %2C 来转义逗号。 例如:
dotnet test --filter "FullyQualifiedName=MyNamespace.MyTestsClass<ParameterType1%2CParameterType2>.MyTestMethod"
由于 shell 还会分析筛选器表达式,因此每当 shell 包含特殊字符(例如--filter,<或>)时,引用整个,值。 PowerShell 中需要引用,其中逗号是数组运算符。
对于 Name 或 DisplayName,请使用特殊字符的 URL 编码。 例如,若要运行名称为 MyTestMethod 的测试,以及 "text"字符串值,请使用以下筛选器:
dotnet test --filter "Name=MyTestMethod \(%22text%22\)"
MSTest 示例
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MSTestNamespace
{
[TestClass]
public class UnitTest1
{
[TestMethod, Priority(1), TestCategory("CategoryA")]
public void TestMethod1()
{
}
[TestMethod, Priority(2)]
public void TestMethod2()
{
}
}
}
| 表达式 | 结果 |
|---|---|
dotnet test --filter Method |
运行 FullyQualifiedName 包含 Method 的测试。 |
dotnet test --filter Name~TestMethod1 |
运行名称包含 TestMethod1 的测试。 |
dotnet test --filter ClassName=MSTestNamespace.UnitTest1 |
运行属于类 MSTestNamespace.UnitTest1 的测试。注意: 由于 ClassName 值应有命名空间,因此 ClassName=UnitTest1 无效。 |
dotnet test --filter FullyQualifiedName!=MSTestNamespace.UnitTest1.TestMethod1 |
运行除 MSTestNamespace.UnitTest1.TestMethod1 之外的其他所有测试。 |
dotnet test --filter TestCategory=CategoryA |
运行含 [TestCategory("CategoryA")] 批注的测试。 |
dotnet test --filter Priority=2 |
运行含 [Priority(2)] 批注的测试。 |
dotnet test --filter "Id=<guid>" |
运行发现 TestCase.Id 的值与 GUID 完全匹配的测试用例。 |
Id 筛选需要 MSTest.TestAdapter 3.6 或更高版本。 从 VSTest 发现返回 TestCase.Id的测试用例中获取 GUID。 此筛选器可以选择一个展开的数据驱动迭代,而无需匹配或转义其显示名称。 每个行都必须作为单个测试用例发现;折叠的数据驱动测试仅公开一个父标识。
使用条件运算符 | 和 & 的示例:
运行
UnitTest1中包含 FullyQualifiedName 或TestCategoryAttribute 为"CategoryA"的测试。dotnet test --filter "FullyQualifiedName~UnitTest1|TestCategory=CategoryA"运行
UnitTest1中包含 FullyQualifiedName 且TestCategoryAttribute 为"CategoryA"的测试。dotnet test --filter "FullyQualifiedName~UnitTest1&TestCategory=CategoryA"运行 FullyQualifiedName 中包含
UnitTest1且TestCategoryAttribute 为"CategoryA"或PriorityAttribute 的优先级为1的测试。dotnet test --filter "(FullyQualifiedName~UnitTest1&TestCategory=CategoryA)|Priority=1"
xUnit 示例
using Xunit;
namespace XUnitNamespace
{
public class TestClass1
{
[Fact, Trait("Priority", "1"), Trait("Category", "CategoryA")]
public void Test1()
{
}
[Fact, Trait("Priority", "2")]
public void Test2()
{
}
}
}
| 表达式 | 结果 |
|---|---|
dotnet test --filter DisplayName=XUnitNamespace.TestClass1.Test1 |
仅运行一个测试,即 XUnitNamespace.TestClass1.Test1。 |
dotnet test --filter FullyQualifiedName!=XUnitNamespace.TestClass1.Test1 |
运行除 XUnitNamespace.TestClass1.Test1 之外的其他所有测试。 |
dotnet test --filter DisplayName~TestClass1 |
运行显示名称包含 TestClass1 的测试。 |
在代码示例中,包含键 "Category" 和 "Priority" 的已定义特征可用于筛选。
| 表达式 | 结果 |
|---|---|
dotnet test --filter XUnit |
运行 FullyQualifiedName 包含 XUnit 的测试。 |
dotnet test --filter Category=CategoryA |
运行包含 [Trait("Category", "CategoryA")] 的测试。 |
使用条件运算符 | 和 & 的示例:
运行
TestClass1中包含 FullyQualifiedName 或Trait的键为"Category"且值为"CategoryA"的测试。dotnet test --filter "FullyQualifiedName~TestClass1|Category=CategoryA"运行
TestClass1中包含 FullyQualifiedName 且Trait的键为"Category"且值为"CategoryA"的测试。dotnet test --filter "FullyQualifiedName~TestClass1&Category=CategoryA"运行 FullyQualifiedName 中包含
TestClass1且Trait的键为"Category"且值为"CategoryA"或Trait的键为"Priority"且值为1的测试。dotnet test --filter "(FullyQualifiedName~TestClass1&Category=CategoryA)|Priority=1"
NUnit 示例
对于 NUnit, TestCategory 并且 Category 是可互换的筛选器属性名称。 两者均筛选使用属性分配的 Category 类别,因此使用 --filter Category=MyCategory 的现有 NUnit 命令无需更改。
using NUnit.Framework;
namespace NUnitNamespace
{
public class UnitTest1
{
[Test, Property("Priority", 1), Category("CategoryA")]
public void TestMethod1()
{
}
[Test, Property("Priority", 2)]
public void TestMethod2()
{
}
}
}
| 表达式 | 结果 |
|---|---|
dotnet test --filter Method |
运行 FullyQualifiedName 包含 Method 的测试。 |
dotnet test --filter Name~TestMethod1 |
运行名称包含 TestMethod1 的测试。 |
dotnet test --filter FullyQualifiedName~NUnitNamespace.UnitTest1 |
运行属于类 NUnitNamespace.UnitTest1 的测试。 |
dotnet test --filter FullyQualifiedName!=NUnitNamespace.UnitTest1.TestMethod1 |
运行除 NUnitNamespace.UnitTest1.TestMethod1 之外的其他所有测试。 |
dotnet test --filter TestCategory=CategoryA |
运行含 [Category("CategoryA")] 批注的测试。 |
dotnet test --filter Category=CategoryA |
运行与 . 相同的测试 TestCategory=CategoryA。 |
dotnet test --filter Priority=2 |
运行含 [Priority(2)] 批注的测试。 |
使用条件运算符 | 和 & 的示例:
运行 UnitTest1 中包含 FullyQualifiedName 或Category 为 "CategoryA" 的测试。
dotnet test --filter "FullyQualifiedName~UnitTest1|TestCategory=CategoryA"
运行 UnitTest1 中包含 FullyQualifiedName 且Category 为 "CategoryA" 的测试。
dotnet test --filter "FullyQualifiedName~UnitTest1&TestCategory=CategoryA"
运行 FullyQualifiedName 中包含 UnitTest1 且Category 为 "CategoryA" 或Property 的 "Priority" 为 1 的测试。
dotnet test --filter "(FullyQualifiedName~UnitTest1&TestCategory=CategoryA)|Priority=1"
有关详细信息,请参阅 TestCase 筛选器
TUnit 示例
TUnit 不支持 --filter 本文前面所述的选项。 而是使用 MTP --treenode-filter 选项。 树节点筛选器是窗体 /<Assembly>/<Namespace>/<Class>/<Method>中的路径,其中:
-
*匹配单个路径段中的任何值,并且可以与其他文本(例如*Method*)组合在一起。 -
**匹配任意数量的路径段。 -
[<Property>=<Value>]路径段与具有该属性的测试匹配之后。[Category("CategoryA")]作为属性Category[Property("Priority", "2")]和属性Priority公开。 -
|(或) 和 (和&) 在单个路径段或属性筛选器中组合替代项。 将每个替代项括在括号中,例如/*/*/(UnitTest1)|(UnitTest2)/*或[(Category=CategoryA)|(Priority=2)]。
该 --treenode-filter 选项是一个 MTP 选项,因此 dotnet test 必须在其 MTP 模式下运行。 使用 .NET 10 SDK 或更高版本,将以下配置添加到解决方案根目录中 global.json 文件:
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
如果没有它, dotnet test 在 VSTest 模式下运行,并在任何测试运行之前失败 MSB1001: Unknown switch 。 有关详细信息,包括如何使用早期 SDK 运行 MTP 项目,请参阅 dotnet 测试的 MTP 模式。
这些示例使用以下测试类:
namespace TUnitNamespace;
public class UnitTest1
{
[Test, Property("Priority", "1"), Category("CategoryA")]
public void TestMethod1()
{
}
[Test, Property("Priority", "2")]
public void TestMethod2()
{
}
}
| 表达式 | 结果 |
|---|---|
dotnet test --treenode-filter "/*/*/*/*Method*" |
运行方法名称包含 Method的测试。 |
dotnet test --treenode-filter "/*/*/*/TestMethod1" |
运行名称为 TestMethod1.. |
dotnet test --treenode-filter "/*/TUnitNamespace/UnitTest1/*" |
在类 TUnitNamespace.UnitTest1中运行所有测试。 |
dotnet test --treenode-filter "/**[Category=CategoryA]" |
运行含 [Category("CategoryA")] 批注的测试。 |
dotnet test --treenode-filter "/**[Priority=2]" |
运行含 [Property("Priority", "2")] 批注的测试。 |
使用条件运算符 | 和 & 的示例:
若要运行类UnitTest1中的测试,并具有以下项Category"CategoryA":
dotnet test --treenode-filter "/*/*/UnitTest1/*[Category=CategoryA]"
若要运行具有以下项Category"CategoryA"或其一"2"项Priority的测试,请执行:
dotnet test --treenode-filter "/**[(Category=CategoryA)|(Priority=2)]"
若要运行类UnitTest1中的测试,并具有以下项之一Category"CategoryA"或一"2"个Priority:
dotnet test --treenode-filter "/*/*/UnitTest1/*[(Category=CategoryA)|(Priority=2)]"
若要运行具有
dotnet test --treenode-filter "/**[(Category=CategoryA)&(Priority=1)]"