必须安装 Microsoft.NET.Test.Sdk、测试框架(如 xunit)及对应运行器(如 xunit.runner.visualstudio);缺一不可,否则 dotnet test 报错“Could not find a test host executable”。

用 dotnet test 运行测试前必须装什么
不装测试运行器,dotnet test 会报错 Could not find a test host executable。核心是三样东西缺一不可:
-
Microsoft.NET.Test.Sdk:提供测试宿主和基础框架 - 一个测试框架包,比如
xunit、nunit或mstest - 对应框架的运行器,例如
xunit.runner.visualstudio(用于 VS 和dotnet test)
推荐直接用 xunit,它和 .NET SDK 集成最稳。添加方式:
dotnet add package xunit注意:.NET 6+ 项目中,
dotnet add package xunit.runner.visualstudio
dotnet add package Microsoft.NET.Test.Sdk
Microsoft.NET.Test.Sdk 是必需的,否则 dotnet test 根本识别不出测试项目。
[Fact] 和 [Theory] 怎么选
[Fact] 用于无参数、固定逻辑的单次验证;[Theory] 必须配合 [InlineData]、[MemberData] 等数据源,适合验证同一逻辑在多组输入下的行为。
常见误用是把本该用 [Theory] 的边界测试硬写成多个 [Fact],既冗余又难维护。比如验证字符串长度限制:
public class StringValidatorTests
{
[Theory]
[InlineData("a", true)]
[InlineData("ab", true)]
[InlineData("abc", false)] // 超长
public void ValidateLength_WithVariousInputs_ReturnsExpected(string input, bool expected)
{
var result = StringValidator.ValidateLength(input, maxLength: 2);
Assert.Equal(expected, result);
}
}
如果只测一种情况,用 [Fact] 更直白;但凡涉及输入组合、边界值、空/零/负数等,优先上 [Theory]。
如何让测试访问 internal 成员
被测类或方法设为 internal 是常见做法,但默认情况下测试项目无法访问。解决方法是在被测项目的 .csproj 中加一行:
其中
MyApp.Tests 是测试项目的程序集名(不是文件夹名,也不是命名空间)。如果测试项目启用了强名称签名,还得补上公钥:漏掉这步,编译不报错,但运行时
Assert 会失败——因为根本调不到目标方法,null 或默认值导致断言崩了,容易误判为逻辑错误。
异步方法测试必须用 async Task 当返回类型
写 async void 或忽略 await 是最常踩的坑。以下写法会导致测试“假通过”:
[Fact]正确写法必须是:
public void WhenCallingApi_ThenReturnsData() // ❌ 返回 void
{
var result = await MyService.GetDataAsync(); // 编译不过,但假设你绕过了
Assert.NotNull(result);
}
[Fact]原因:xUnit 需要控制异步生命周期,只有返回
public async Task WhenCallingApi_ThenReturnsData() // ✅
{
var result = await MyService.GetDataAsync();
Assert.NotNull(result);
}
Task 才能真正等待完成。否则测试框架在异步操作结束前就标记为通过,掩盖真实问题。
测试里最容易被忽略的是异步等待的完整性,以及 internal 成员的可见性配置——这两处不显式处理,问题往往延迟暴露,查起来反而更费时间。










