GitHub CI/CD运行.NET单元测试时找不到项目引用的测试文件
问题根因
你遇到的文件找不到问题来自两个核心原因:
- 硬编码了Windows系统专属的路径分隔符
\,你的GitHub CI运行环境是ubuntu-latest(Linux系统),Linux下路径分隔符为/,硬编码反斜杠会被识别为文件名的一部分,无法正确匹配路径。 - 单元测试执行时的工作目录并不固定,使用
dotnet test --no-build参数时,不同系统、不同测试框架下的执行上下文目录可能和你本地Windows环境的工作目录不一致,直接写相对路径很容易出现定位偏差。
修复方案
1. 优先修改测试代码,通过程序集位置定位文件(跨平台最稳妥)
不要依赖当前工作目录的相对路径,通过反射获取测试程序集自身的输出目录,再用.NET自带的路径拼接方法自动适配不同系统的分隔符,修改后的测试代码如下:
using System.Reflection; using System.IO; [Test] public void MyTest() { // 获取当前测试程序集所在的输出目录 string assemblyPath = Assembly.GetExecutingAssembly().Location; string assemblyDir = Path.GetDirectoryName(assemblyPath); // 自动适配系统路径分隔符拼接文件路径,不要手动写斜杠 string targetFile = Path.Combine(assemblyDir, "testfiles", "mytest.json"); var json = File.ReadAllText(targetFile); Assert.IsNotNull(json); }
同时确认项目文件(.csproj)中已经正确配置了文件复制规则,确保mytest.json会被复制到输出目录,对应配置参考:
<ItemGroup> <!-- 单个文件配置 --> <None Update="testfiles\mytest.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> <!-- 如果需要复制整个testfiles目录下的所有文件,用下面的配置替换上面的单文件配置 --> <!-- <None Include="testfiles\**\*"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> --> </ItemGroup>
2. 调整CI执行命令,排除构建缓存问题
你当前的测试命令带了--no-build参数,如果构建步骤和测试步骤之间存在输出目录路径映射异常,也可能导致文件丢失,可以先去掉该参数,让测试步骤自动完成构建,确保输出目录文件完整,修改GitHub Actions中Test步骤的命令:
- name: Test run: dotnet test --verbosity normal
3. 可选:使用测试框架自带的部署特性
如果你不想手动拼接路径,也可以用对应测试框架的文件部署特性,注意跨平台路径统一用正斜杠书写,以MSTest为例:
[Test] [DeploymentItem("testfiles/mytest.json")] public void MyTest() { var json = File.ReadAllText("mytest.json"); Assert.IsNotNull(json); }
注意:DeploymentItem特性在部分.NET版本+Linux环境下存在兼容性问题,稳定性不如第一种通过程序集定位的方案。
排查技巧
如果修改后仍然报错,可以在测试代码中加入目录和文件列表输出,通过CI日志定位问题:
// 不同测试框架的上下文输出方式略有差异,MSTest直接用TestContext即可 TestContext.WriteLine($"当前工作目录:{Directory.GetCurrentDirectory()}"); TestContext.WriteLine($"程序集输出目录:{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}"); TestContext.WriteLine("程序集目录下所有文件:"); foreach (string file in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*", SearchOption.AllDirectories)) { TestContext.WriteLine(file); }
从CI的测试输出日志中,你可以直接看到目标文件是否被正确复制到输出目录,以及路径拼接是否正确。
内容的提问来源于stack exchange,提问作者Omar.Ebrahim
相关产品推荐
相关产品推荐

