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