Before starting, you need to make sure you have your own GitLab instance or have registered GitLab.com.

Check in your .NET project.

Make sure there is the .sln file in the root of the repository:

file

Add the following packages to all your unit test projects:

  • coverlet.collector
  • JunitXml.TestLogger
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="coverlet.collector" Version="3.2.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="JunitXml.TestLogger" Version="3.0.124" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
    <PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
    <PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
  </ItemGroup>

  
</Project>

Now you can write some unit tests with your C# code.

And create the .gitlab-ci.yml with content:

(I'm using a Linux agent\runner, with .NET 6 installed.)

stages:
  - build
  - test
  - publish

before_script:
  - 'export DOTNET_CLI_TELEMETRY_OPTOUT=1'
  - 'export PATH=$PATH:$HOME/.dotnet/tools'
  - 'dotnet tool install dotnet-reportgenerator-globaltool --global || echo "DRG already installed."'

build:
  stage: build
  script:
    - dotnet build --no-self-contained

test:
  stage: test
  needs: 
    - build
  coverage: '/TOTAL_COVERAGE=(\d+.\d+)/'
  script:
    - dotnet test *.sln --collect:"XPlat Code Coverage" --logger "junit;MethodFormat=Class;FailureBodyFormat=Verbose"
    - reportgenerator -reports:"**/coverage.cobertura.xml" -targetdir:"." -reporttypes:"cobertura"
    - COVERAGE_VALUE=$(grep -oPm 1 'line-rate="\K([0-9.]+)' "./Cobertura.xml")
    - COVERAGE=$(echo "scale=2; $COVERAGE_VALUE * 100" | bc)
    - 'echo "TOTAL_COVERAGE=$COVERAGE%"'
  artifacts:
    when: always
    expire_in: 1 day
    paths:
      - ./**/TestResults.xml
      - ./Cobertura.xml
    reports:
      junit:
        - ./**/TestResults.xml
      coverage_report:
        coverage_format: cobertura
        path: ./Cobertura.xml

publish:
  stage: publish
  needs: 
    - test
  script:
    - dotnet publish --configuration Release --runtime linux-x64 --no-self-contained *.sln

pack:
  stage: publish
  needs: 
    - test
  script:
    - dotnet build --configuration Release --no-self-contained *.sln
    - dotnet pack --configuration Release *.sln
  artifacts:
    expire_in: 1 week
    paths:
      - '**/*.nupkg'

Now you can try to run your pipeline.

file

And unit test results will be shown here:

file

And code coverage results will also be shown:

file

When you create a pull request, you can also see the coverage info:

file

Don't forget, you can show a coverage badge in your Readme.md file!

Test Coverage

Add the following code to your file.

![Test Coverage](https://{your-gitlab-instance}/{org}/{repo}/badges/{default-branch}/coverage.svg)