“no test is available”错误主因是配置或语法问题:未引用microsoft.net.test.sdk、测试类/方法非public、误用[test]而非[fact]。

直接用 dotnet test 就能跑起来,前提是项目结构和修饰符写对了——不是环境没装好,而是测试类或方法缺 public、没引用 Microsoft.NET.Test.Sdk、或者误用了 [Test] 而不是 [Fact]。
为什么 dotnet test 报 “No test is available”
这是最常卡住新手的第一步。根本原因几乎全是项目配置或语法细节错位,和 SDK 版本、IDE、插件无关。
-
Microsoft.NET.Test.Sdk没被显式引用:xUnit 模板会自动加,但手动创建或迁移项目时容易漏;执行dotnet add package Microsoft.NET.Test.Sdk补上 - 测试类不是
public:xUnit 只扫描public类里的测试方法,internal或默认访问级别的类会被跳过 - 测试方法不是
public void(或public async Task):写成private、internal、async void都不识别 - 用了错误的特性:NUnit 的
[Test]或 MSTest 的[TestMethod]在 xUnit 里完全无效,必须用[Fact]或[Theory]
Assert.Equal 和 Assert.True 怎么选才不掩盖问题
断言不是越“看起来严格”越好,而是要让失败信息直接暴露差异点。用错会导致调试时反复打日志、查变量。
- 值类型(
int、string、DateTime、Guid)或已实现IEquatable<t></t>的类 → 优先用Assert.Equal(expected, actual),失败时明确提示Expected: ..., Actual: ... - 自定义引用类型(如
Person)没重写Equals→Assert.Equal(p1, p2)实际比的是内存地址,两个字段相同的新对象也会判为不等;此时应改用Assert.True(p1.Equals(p2)),并确保已重写Equals和GetHashCode - 需要表达式逻辑(如“小于 500ms”、“包含某子串”、“不为 null”)→ 必须用
Assert.True(...),但记得加message参数,否则只报Assert.True failed,毫无上下文
集合比较别直接 Assert.Equal(list1, list2)
Assert.Equal 对 IEnumerable 默认调用 SequenceEqual,但它要求元素顺序、数量、内容全一致——这在多数业务场景中过于严格,且错误提示不直观。
- 要验证“内容相同、顺序无关” → 用
Assert.Collection(actual, ...)手动逐项断言,或先排序再比:actual.OrderBy(x => x.Id).SequenceEqual(expected.OrderBy(x => x.Id)) - 要验证“结构一致(比如 JSON 序列化后字符串相等)” → 仅限无循环引用、无动态属性的简单 DTO,可用
JsonConvert.SerializeObject(actual).Equals(JsonConvert.SerializeObject(expected)) - 避免
Assert.Equal直接传两个List<t></t>:它不会深比较元素,也不会提示哪个索引出错,失败时只显示“序列不匹配”
[Theory] + [InlineData] 是防止签名变更漏测的关键
当被测方法加参数、改类型、删重载时,十个分散的 [Fact] 方法可能只有九个被手动更新,剩下一个静默失效——而 [Theory] 能靠编译器强制校验参数数量和类型。
-
[InlineData]是编译期检查:如果方法签名从int Add(int a, int b)改成int Add(int a, int b, bool round),所有[InlineData(1, 2)]会立刻报错,无法编译通过 - 数据与逻辑分离:输入、预期结果集中管理,修改边界值(如
0、-1、int.MaxValue)只需改数据行,不用翻找多个方法体 - 不要在
[Theory]方法里写重复的 Arrange 逻辑:把初始化、构造对象等共用代码提到私有方法或new表达式里,保持每个[InlineData]行只体现差异点
最容易被忽略的是测试项目的输出路径和运行时工作目录——比如读取 data.json 时,File.ReadAllText("data.json") 会去 bin/Debug/net6.0/ 下找,不是项目根目录。硬编码路径或依赖当前目录的测试,在 CI 环境里大概率失败。










