Search code examples
c#.net-coregithub-actions

.NET application tests failing on GitHub Actions due to missing dependencies


I have a set of .NET 6.0 projects within a .NET solution, one of which is a test data provider. I am using LiteDB to store test data records. The solution builds fine locally and completes all tests successfully. I have set up a standard CI build pipeline on GitHub using GitHub Actions; the build completes without issues and tests that do not depend on the test database run fine.

But tests that rely on the LiteDb database cannot run because there seems to be an issue on the build server finding the LiteDb assembly:

Testhost process for source(s) '/home/runner/work/MyProject.Core/MyProject.Core/test/MyProject.Testing.Data/bin/Release/net6.0/MyProject.Testing.Data.dll' exited with error: Error: An assembly specified in the application dependencies manifest (MyProject.Testing.Data.deps.json) was not found: package: 'LiteDB', version: '5.0.16' path: 'lib/netstandard2.0/LiteDB.dll'

Most of the articles with similar error messages relate to ASP.NET Core, e.g., An assembly specified in the application dependencies manifest (...) was not found but clutching at straws, I tried adding the following to the test data project:

<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>

This made no difference. Another SO answer (How do I get .NET Core projects to copy NuGet references to the build output?) suggested adding the following to the .csproj:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

This dealt with the missing dependency but introduced a new one:

Testhost process for source(s) '/home/runner/work/MyProject/MyProject/test/MyProject.Testing.Data/bin/Release/net6.0/MyProject.Testing.Data.dll' exited with error: Error: An assembly specified in the application dependencies manifest (testhost.deps.json) was not found: package: 'Microsoft.TestPlatform.CommunicationUtilities', version: '15.0.0.0' path: 'Microsoft.TestPlatform.CommunicationUtilities.dll'

(Naturally I tried adding Microsoft.TestPlatform as a dependency, but that didn't make any difference.)

For completeness, I confirmed that LiteDb is supported on Linux, as the GitHub Actions service is running on Ubuntu - it doesn't seem like there is any issue there. The application and all assemblies (and tests) target .NET 6.0 and all projects are set to build AnyCPU. Here is my ci.yml file, if that is helpful:

name: CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:

    env:
      BUILD_CONFIG: 'Release'
      SOLUTION: 'MyProject.Core.sln'
      
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: 6.0.x
        
    - name: Restore dependencies
      run: dotnet restore
      
    - name: Build
      run: dotnet build $SOLUTION --configuration $BUILD_CONFIG --no-restore
      
    - name: Test
      run: dotnet test /p:Configuration=$BUILD_CONFIG --no-build --verbosity normal

Here are the top 10 lines of my .csproj (the 5.0.* was another attempt to fix the issue; it could just as easily be 5.0.16):

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net6.0</TargetFrameworks>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
    
  <ItemGroup>
    <PackageReference Include="LiteDB" Version="5.0.*" />
    <PackageReference Include="xunit" Version="2.4.2" />
  </ItemGroup>

Can anyone see where I might be going wrong here?


Solution

  • Most likely, the issue you are facing is due to the way that dotnet test works. When you run it within a solution without specifying a target project, it searches for all the projects that might be test projects. For whatever reason, it has determined that your test data support library contains tests, but it is unable to run it because it can't find the dependencies.

    Assuming this to be the case, what you need to do is be more specific in your dotnet test invocations. Sadly the dotnet test command line doesn't accept wildcards, so even if your test projects all have the file name format:

    MyProject.SomeFunction.Tests

    then there is no way to run them selectively.

    My suggestion would be to add a Bash script to your project (say in the .github folder) thus:

    #!/bin/bash
    
    FAILURES=0
    TEST_PROJECTS=$(find test -name "MyProject.*.Tests")
    
    for PROJECT in $TEST_PROJECTS
    do 
        (dotnet test ./$PROJECT --no-build --verbosity normal)
        if test "$?" != "0" 
        then ((FAILURES+=1)) 
        fi    
    done
    
    exit $FAILURES
    

    called say runtests.sh. You can then replace the test step in your .yaml file with the following:

    - name: Test
      run: bash .github/runtests.sh
    

    Note that your build will be slower as there is no parallelism here when running tests, but at least the damn thing should work!