I am running a collection of unit tests in an Azure DevOps Pipeline. The unit testing framework in use is MSTest.
Some unit tests load files that are inside the repo. Therefore the Property Copy to Output Directory
is set to Copy Always
.
Down below you can see the property being set inside the csproj
file.
<Project Sdk="Microsoft.NET.Sdk">
<!-- shortened csproj file -->
<ItemGroup>
<None Update="TestFiles\sample.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Inside the test, the file gets loaded as seen in the next code block.
var path = Path.Join("TestFiles", "sample.xml");
var fileStream = File.OpenRead(path);
I set the
verbosity
todetailed
in order to see if the file gets copied or not.
Running dotnet test .\Project\Project.csproj --logger trx --verbosity detailed
locally, everything works as expected with the test results.
Same applies for running the tests in Visual Studio.
I execute the tests inside an Azure DevOps Pipeline with the DotNetCoreCLI
task.
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- task: DotNetCoreCLI@2
displayName: Run Unit Tests
inputs:
command: test
projects: Project/Project.csproj
arguments: --verbosity detailed
I extracted the generated command from the pipeline logs: /usr/bin/dotnet test /home/vsts/work/1/s/Project/Project.csproj --logger trx --results-directory /home/vsts/work/_temp --verbosity detailed
. I don't see any significant differences between my local command compared to the one being generated by the pipeline.
Indeed inspecting the local and Azure DevOps Pipeline logs, the file gets copied as expected.
Copying file from "/home/vsts/work/1/s/Project/TestFiles/sample.xml" to "/home/vsts/work/1/s/Project/bin/Debug/net6.0/TestFiles/sample.xml".
The path matches the one from the MSBuild log /home/vsts/work/1/s/Project/bin/Debug/net6.0/TestFiles/sample.xml
. Then again, I get a FileNotFoundException
:
System.IO.FileNotFoundException: Could not find file '/home/vsts/work/1/s/Project/bin/Debug/net6.0/TestFiles/sample.xml'.
I tried to list all files inside the output directory adding the continueOnError
key to the test task.
# ...
tasks:
# ...
- script: ls -la /home/vsts/work/1/s/Project/bin/Debug/net6.0
- script: ls -la /home/vsts/work/1/s/Project/bin/Debug/net6.0/TestFiles
The first script action already fails with the following error message:
ls: cannot access '/home/vsts/work/1/s/Project/bin/Debug/net6.0': No such file or directory
At this point I'm just lost and don't know what to do about this seemingly simple problem... Any suggestions how I get the files containing test data to the unit test? Where is my mistake?
I tried to switch to xUnit. But it gave me the same FileNotFoundException
as before. I don't think it's a problem with the test itself but with the Azure DevOps Pipeline environment.
After some further debugging of the pipeline, I found a mistake I caused myself.
When debugging the pipeline I used the - script: ls -la /home/vsts/work/1/s/Project/...
task. The path I specified was the one from this post (which I abstracted from the real thing cuz its from work yk) NOT the actual one of my test project.
Listing a non existing directory does not work for obvious reasons...
Comparing the paths from the MSBuild log message and the actual test run showed that they were almost identical. The actual file had a lowercase extension and the file name inside the test project was uppercase.
Running the pipeline in the ubuntu-latest
environment means that we are working with a case sensitive file system (unlike on my local machine which is a Windows 11 machine).
tl;dr - Everything was correct, I just got to match the actual file name and file path inside the consuming test 100% correctly or run it in a windows environment.