Search code examples
c#.netazure-pipelinesdevopsmstest

Consuming files in UnitTests running in Azure DevOps Pipeline


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>

Test Method

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);

Local Run

I set the verbosity to detailed 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.

Pipeline

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.

MSBuild

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".

Test Error

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'.

Pipeline debugging

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?

Update 1

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.


Solution

  • 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.