在 Microsoft.Testing.Platform 的上下文中, 功能 是指 执行特定作或提供特定信息的可能性。 这是测试框架和扩展以声明其以某种方式运行或向请求者提供特定信息的能力的一种方式。
请求者 可以是测试会话中涉及的任何组件,例如平台、扩展或测试框架本身。
功能系统的主要目标是促进测试会话中涉及的组件之间的有效通信,使他们能够准确交换信息并满足各自的需求。
引导式示例
让我们考虑一个假设示例来演示功能系统的必要性。
注意
此示例仅用于说明目的,目前未在 Microsoft.Testing.Platform 或任何测试框架中实现。
假设你有一个扩展,该扩展要求测试框架一次执行不超过一个测试。 此外,每次测试后,扩展都需要知道该特定测试的 CPU 使用率。
若要适应上述方案,需要从测试框架查询以下情况:
- 它一次只能执行一个测试。
- 它可以提供有关每个测试使用的 CPU 量的信息。
扩展如何确定测试框架是否能够在此模式下运行,并为测试会话提供 CPU 使用情况信息? 在 Microsoft.Testing.Platform 中,此功能由接口的 Microsoft.Testing.Platform.Capabilities.ICapability
实现表示:
// Base capabilities contracts
public interface ICapability
{
}
public interface ICapabilities<TCapability>
where TCapability : ICapability
{
IReadOnlyCollection<TCapability> Capabilities { get; }
}
// Specific testing framework capabilities
public interface ITestFrameworkCapabilities : ICapabilities<ITestFrameworkCapability>
{
}
public interface ITestFrameworkCapability : ICapability
{
}
如你所看到的那样,ICapability
接口是一个标记接口,因为它可以表示任何功能,其实际实现取决于上下文。 你还将观察 ITestFrameworkCapability
,它从 ICapability
继承以对功能进行分类。 功能系统的泛型性质允许按上下文方便地分组。
ITestFrameworkCapability
会对由测试框架实现的所有功能进行分组。
ICapabilities<TCapability>
接口显示扩展实现的所有功能的集合。 同样,对于基础版本,有一个特定于语境的测试框架名为 ITestFrameworkCapabilities
。 在ITestFrameworkCapabilities
过程中, 会提供给平台。
若要创建解决上述方案的功能,请按如下方式定义它:
public interface IDisableParallelismCapability : ITestFrameworkCapability
{
bool CanDisableParallelism { get; }
bool CanProvidePerTestCpuConsumption { get; }
void Enable();
}
如果测试框架在运行时实现此接口,可以查询以下内容:
- 验证测试框架是否能够关闭并行
CanDisableParallelism = true
。 - 确定测试框架能否提供
CanProvidePerTestCPUConsumption = true
CPU 使用情况数据。 - 在测试会话开始之前调用
Enable()
方法,请求测试适配器激活此模式。
扩展内的假设代码片段可能类似于:
IServiceProvider provider = null; // TODO: Get IServiceProvider.
var capabilities = serviceProvider.GetRequiredService<ITestFrameworkCapabilities>();
// Utilize the `GetCapability` API to search for the specific capability to query.
var capability = capabilities.GetCapability<IDisableParallelismCapability>();
if (capability is null)
{
// Capability not supported...
}
else
{
capability.Enable();
if (capability.CanDisableParallelism)
{
// Do something...
}
if (capability.CanProvidePerTestCpuConsumption)
{
// Do something...
}
}
前面的示例演示了功能基础结构如何启用强大的机制,以便在测试会话中涉及的组件之间进行通信能力。 虽然该示例演示了专为测试框架设计的一项功能,但任何组件都可以公开和实现继承自 ICapability
的扩展。
很明显,并非所有细节都可以通过接口进行通信。 考虑到前面的示例,如果支持 CanProvidePerTestCpuConsumption
,扩展应该有什么期望? 测试框架预计通过 IMessageBus 传输哪种类型的自定义信息? 解决方案是功能的文档。 功能所有者有责任尽可能清晰地设计、运送和记录它,以使用需要特定功能的扩展来协助想要有效地进行协作的实施者。
例如,TRX 报表扩展使测试框架能够实施必要的功能来准确生成 TRX 报表。 要注册的扩展包含在 https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport 包中,但实现功能在仅限合同https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport.Abstractions的 NuGet 包中。
最后,让我们总结一下功能系统的主要方面:
- 它对于促进组件之间清晰稳定的通信至关重要。
- 所有功能都应继承自
ICapability
或从中继承的接口,并通过具有ICapabilities
接口的集合公开。 - 它有助于特征的演变,而不会造成重大更改。 如果某些功能不受支持,可以采取适当的措施。
- 设计、运输和记录功能使用情况的责任在于 功能所有者。 Microsoft.Testing.Platform 也可以像任何其他扩展一样拥有一项功能。
框架功能
平台公开了一个名为 ITestFrameworkCapability
的专用接口,该接口是所有针对测试框架公开功能的基础。
将测试框架注册到平台时,将提供这些功能。
IBannerMessageOwnerCapability
可选的 测试框架功能,允许测试框架向平台提供横幅消息。 如果消息 null
或功能不存在,则平台将使用其默认横幅消息。
使用此功能实现,可以抽象化测试框架在决定是否显示横幅消息时可能需要考虑的各种条件。
平台公开 IPlatformInformation
服务,提供有关生成自定义横幅消息时可能有用的平台的一些信息。