Skip to content

Commit

Permalink
Adding MSTest Sdk sample (#117)
Browse files Browse the repository at this point in the history
* Adding mstest sdk project,
  • Loading branch information
fhnaseer authored Apr 17, 2024
1 parent 05f80f1 commit 967a10d
Show file tree
Hide file tree
Showing 11 changed files with 321 additions and 2 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/Algorithms_Scenario07.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: "Algorithms Scenario 07"

on:
push:
branches: [ "main" ]
paths: [ 'samples/Algorithms/tests/**', 'samples/Algorithms/src/**', '.github/workflows/Algorithms_Scenario07.yml' ]

jobs:
build:

runs-on: ubuntu-latest
defaults:
run:
working-directory: ./samples/Algorithms/tests/Algorithms.Core.MSTest.Sdk.Tests
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet run --no-build --coverage --coverage-output $GITHUB_WORKSPACE/report.cobertura.xml --coverage-output-format cobertura
- name: ReportGenerator
uses: danielpalme/ReportGenerator-GitHub-Action@5.2.0
with:
reports: '${{ github.workspace }}/report.cobertura.xml'
targetdir: '${{ github.workspace }}/coveragereport'
reporttypes: 'MarkdownSummaryGithub'
- name: Upload coverage into summary
run: cat $GITHUB_WORKSPACE/coveragereport/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: code-coverage-report
path: ${{ github.workspace }}/report.cobertura.xml
2 changes: 2 additions & 0 deletions samples/Algorithms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Solution contains two projects:
1. `Algorithms.Core` - contains core logic for solution
2. `Algorithms.Console` - contains Native AOT console app
3. `Algorithms.Core.Tests` - contains unit tests for `Algorithms.Core`. It is [MSTest runner project](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-mstest-runner-intro?tabs=dotnetcli)
4. `Algorithms.Core.MSTest.Sdk.Tests` - contains unit tests for `Algorithms.Core`. It is [MSTest runner project using MSTest SDK](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-mstest-sdk)

# Scenarios

Expand All @@ -13,3 +14,4 @@ Solution contains two projects:
4. [***Scenario 04*** Code coverage for MSTest Runner project using `dotnet-coverage` tool](scenarios/scenario04/README.md)
5. [***Scenario 05*** Code coverage for Native AOT console app](scenarios/scenario05/README.md)
6. [***Scenario 06*** Code coverage for Native AOT MSTest Runner project](scenarios/scenario06/README.md)
7. [***Scenario 07*** Code coverage for MSTest SDK project using dynamic instrumentation](scenarios/scenario07/README.md)
96 changes: 96 additions & 0 deletions samples/Algorithms/scenarios/scenario07/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Scenario Description

Collect code coverage using dynamic instrumentation for MSTest SDK project.

> **_NOTE:_** MSTest SDK project coverage extension by default is not collecting native code coverage. If you want to enable please set to `True` `EnableStaticNativeInstrumentation` or `EnableDynamicNativeInstrumentation` in configuration.
## Collect code coverage using command line

```shell
git clone https://github.com/microsoft/codecoverage.git
cd codecoverage/samples/Algorithms/tests/Algorithms.Core.MSTest.Sdk.Tests/
dotnet run --coverage --coverage-output report.cobertura.xml --coverage-output-format cobertura
```

You can also use [run.ps1](run.ps1) to collect code coverage.

## Collect code coverage inside github workflow

`reportgenerator` can be used to generate final github summary markdown.

```yml
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet run --no-build --coverage --coverage-output $GITHUB_WORKSPACE/report.cobertura.xml --coverage-output-format cobertura
- name: ReportGenerator
uses: danielpalme/ReportGenerator-GitHub-Action@5.2.0
with:
reports: '${{ github.workspace }}/report.cobertura.xml'
targetdir: '${{ github.workspace }}/coveragereport'
reporttypes: 'MarkdownSummaryGithub'
- name: Upload coverage into summary
run: cat $GITHUB_WORKSPACE/coveragereport/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: code-coverage-report
path: ${{ github.workspace }}/report.cobertura.xml
```
[Full source example](../../../../.github/workflows/Algorithms_Scenario07.yml)
[Run example](../../../../../../actions/workflows/Algorithms_Scenario07.yml)
## Collect code coverage inside Azure DevOps Pipelines
```yml
steps:
- task: DotNetCoreCLI@2
inputs:
command: 'restore'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'restore'

- task: DotNetCoreCLI@2
inputs:
command: 'build'
arguments: '--no-restore --configuration $(buildConfiguration)'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'build'

- task: DotNetCoreCLI@2
inputs:
command: 'run'
arguments: '--no-build --configuration $(buildConfiguration) --results-directory $(Agent.TempDirectory) --coverage --coverage-output $(Agent.TempDirectory)/report.cobertura.xml --coverage-output-format cobertura --report-trx'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'test'

- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '$(Agent.TempDirectory)/**/*.trx'
publishRunAttachments: false

- task: PublishCodeCoverageResults@2
inputs:
summaryFileLocation: $(Agent.TempDirectory)/**/*.cobertura.xml
```
[Full source example](azure-pipelines.yml)
![alt text](azure-pipelines.jpg "Code Coverage tab in Azure DevOps pipelines")
## Report example
![alt text](example.report.jpg "Example report")
[Link](example.report.cobertura.xml)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions samples/Algorithms/scenarios/scenario07/azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: "Algorithms Scenario 07"

pool:
vmImage: 'ubuntu-latest'

variables:
buildConfiguration: 'Debug'
projectPath: './samples/Algorithms/tests/Algorithms.Core.MSTest.Sdk.Tests/Algorithms.Core.MSTest.Sdk.Tests.csproj' # this is specific to example - in most cases not needed

steps:
- task: DotNetCoreCLI@2
inputs:
command: 'restore'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'restore'

- task: DotNetCoreCLI@2
inputs:
command: 'build'
arguments: '--no-restore --configuration $(buildConfiguration)'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'build'

- task: DotNetCoreCLI@2
inputs:
command: 'run'
arguments: '--no-build --configuration $(buildConfiguration) --results-directory $(Agent.TempDirectory) --coverage --coverage-output $(Agent.TempDirectory)/report.cobertura.xml --coverage-output-format cobertura --report-trx'
projects: '$(projectPath)' # this is specific to example - in most cases not needed
displayName: 'test'

- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '$(Agent.TempDirectory)/**/*.trx'
publishRunAttachments: false

- task: PublishCodeCoverageResults@2
inputs:
summaryFileLocation: $(Agent.TempDirectory)/**/*.cobertura.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<coverage line-rate="1" branch-rate="1" complexity="10" version="1.9" timestamp="1705670662" lines-covered="17" lines-valid="17" branches-covered="10" branches-valid="10">
<packages>
<package line-rate="1" branch-rate="1" complexity="10" name="Algorithms.Core">
<classes>
<class line-rate="1" branch-rate="1" complexity="10" name="Algorithms.Core.Merger" filename="/home/runner/work/codecoverage/codecoverage/samples/Algorithms/src/Algorithms.Core/Merger.cs">
<methods>
<method line-rate="1" branch-rate="1" complexity="10" name="Merge" signature="(int[], int[])">
<lines>
<line number="6" hits="1" branch="False" />
<line number="7" hits="1" branch="False" />
<line number="8" hits="1" branch="False" />
<line number="9" hits="1" branch="False" />
<line number="11" hits="1" branch="False" />
<line number="13" hits="1" branch="True" condition-coverage="100% (4/4)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
<condition number="1" type="jump" coverage="100%" />
</conditions>
</line>
<line number="14" hits="1" branch="False" />
<line number="15" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="16" hits="1" branch="False" />
<line number="18" hits="1" branch="False" />
<line number="19" hits="1" branch="False" />
<line number="21" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="22" hits="1" branch="False" />
<line number="24" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="25" hits="1" branch="False" />
<line number="27" hits="1" branch="False" />
<line number="28" hits="1" branch="False" />
</lines>
</method>
</methods>
<lines>
<line number="6" hits="1" branch="False" />
<line number="7" hits="1" branch="False" />
<line number="8" hits="1" branch="False" />
<line number="9" hits="1" branch="False" />
<line number="11" hits="1" branch="False" />
<line number="13" hits="1" branch="True" condition-coverage="100% (4/4)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
<condition number="1" type="jump" coverage="100%" />
</conditions>
</line>
<line number="14" hits="1" branch="False" />
<line number="15" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="16" hits="1" branch="False" />
<line number="18" hits="1" branch="False" />
<line number="19" hits="1" branch="False" />
<line number="21" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="22" hits="1" branch="False" />
<line number="24" hits="1" branch="True" condition-coverage="100% (2/2)">
<conditions>
<condition number="0" type="jump" coverage="100%" />
</conditions>
</line>
<line number="25" hits="1" branch="False" />
<line number="27" hits="1" branch="False" />
<line number="28" hits="1" branch="False" />
</lines>
</class>
</classes>
</package>
</packages>
</coverage>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions samples/Algorithms/scenarios/scenario07/run.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd $PSScriptRoot/../../tests/Algorithms.Core.MSTest.Sdk.Tests
dotnet run --coverage --coverage-output report.cobertura.xml --coverage-output-format cobertura
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="MSTest.Sdk/3.3.1">

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

<ItemGroup>
<ProjectReference Include="../../src/Algorithms.Core/Algorithms.Core.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Algorithms.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]

namespace Algorithms.Core.MSTest.Sdk.Tests;

[TestClass]
public class MergerTests
{
[TestMethod]
public void Test1()
{
var result = Merger.Merge([1, 3, 5], [2, 4, 5, 6]);
AssertArrays([1, 2, 3, 4, 5, 5, 6], result);
}

[TestMethod]
public void Test2()
{
var result = Merger.Merge([], [2, 4, 5, 6]);
AssertArrays([2, 4, 5, 6], result);
}

[TestMethod]
public void Test3()
{
var result = Merger.Merge([2, 4, 5, 6], []);
AssertArrays([2, 4, 5, 6], result);
}

private void AssertArrays(int[] expected, int[] actual)
{
Assert.AreEqual(expected.Length, actual.Length, $"Sizes of arrays are different. expected.Length={expected.Length} actual.Length={actual.Length}");
for (int index = 0; index < expected.Length; index++)
Assert.AreEqual(expected[index], actual[index], $"Arrays different on index={index}. expected[{index}]={expected[index]} actual[{index}]={actual[index]}");
}
}
4 changes: 2 additions & 2 deletions samples/Algorithms/tests/Algorithms.Core.Tests/MergerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Algorithms.Core;
using Algorithms.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]
Expand Down Expand Up @@ -35,4 +35,4 @@ private void AssertArrays(int[] expected, int[] actual)
for (int index = 0; index < expected.Length; index++)
Assert.AreEqual(expected[index], actual[index], $"Arrays different on index={index}. expected[{index}]={expected[index]} actual[{index}]={actual[index]}");
}
}
}

0 comments on commit 967a10d

Please sign in to comment.