Automatisation des tests unitaires pour les projets hérités .NET Framework 4.6.1 avec GitLab Runner sous Windows

L'intégration continue pour les applications héritées peut s'avérer complexe. Ce guide détaille la configuration de GitLab Runner sur un environnement Windows afin d'exécuter automatiquement des tests unitiares sur une base de code .NET Framework 4.6.1 en s'appuyant sur l'exécutable vstest.console.exe.

Migration vers le format SDK du fichier projet

La première étape consiste à moderniser le fichier .csproj pour utiliser le format SDK, tout en conservant la cible net461. Voici un exemple de configuration optimisée :

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <ProjectGuid>{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}</ProjectGuid>
        <OutputType>Library</OutputType>
        <RootNamespace>Enterprise.Legacy.Tests</RootNamespace>
        <AssemblyName>Enterprise.Legacy.Tests</AssemblyName>
        <TargetFramework>net461</TargetFramework>
        <FileAlignment>512</FileAlignment>
    </PropertyGroup>

    <ItemGroup>
        <Reference Include="System" />
    </ItemGroup>

    <ItemGroup>
        <ProjectReference Include="..\Enterprise.Legacy.Core\Enterprise.Legacy.Core.csproj">
            <Project>{11223344-5566-7788-99AA-BBCCDDEEFF00}</Project>
            <Name>Enterprise.Legacy.Core</Name>
        </ProjectReference>
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="NUnit" Version="3.12.0" />
        <PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
    </ItemGroup>
</Project>

Configuration du framework de test NUnit

Le remplacement de MSTest par NUnit nécessite une attention particulière concernant les versions des adaptateurs. Nous utilisons la version 3.12.0 pour NUnit.

Il est crucial d'aligner la version de NUnit3TestAdapter sur celle de NUnit (3.12.0).

  • Sans l'adaptateur de test, le moteur d'exécution ne pourra pas découvrir les cas de test.
  • Si une version plus récente de l'adaptateur est utilisée, Visual Studio 2022 pourrait détecter les tests localement, mais vstest.console.exe échouera silencieusement lors de l'exécution via le Runner GitLab.

Définition des variables d'environnement GitLab

Plusieurs variables doivent être configurées au niveau du serveur ou du groupe GitLab pour pointer vers les outils nécessaires : MSBUILD_EXECUTABLE, LEGACY_BUILD_VERSION et LEGACY_PKG_DIR.

Configuration du pipeline CI/CD

Le fichier .gitlab-ci.yml doit être placé à la racine de la solution. Il orchestre la compilation et l'exécution des tests via des scripts PowerShell externes.

stages:
  - compilation
  - validation

variables:
  LEGACY_BUILD_VERSION: "2024.5.$CI_PIPELINE_IID"
  LEGACY_PKG_DIR: "$NUPKG_OUTPUT_ROOT\\Enterprise.Legacy.Core\\$LEGACY_BUILD_VERSION"

execute_unit_tests:
  stage: validation
  before_script:
    - .$COMPILE_SCRIPT_PATH
    - .$TEST_SCRIPT_PATH
  script:
    - echo "Démarrage de la compilation..."
    - Invoke-LegacyBuild $MSBUILD_EXECUTABLE $CI_PROJECT_DIR "Enterprise.Legacy.Tests\\Enterprise.Legacy.Tests.csproj" $LEGACY_BUILD_VERSION
    - echo "Exécution des tests unitaires NUnit..."
    - Invoke-LegacyVSTest $VSTEST_EXECUTABLE_DIR $CI_PROJECT_DIR "Enterprise.Legacy.Tests\\bin\\debug\\net461\\Enterprise.Legacy.Tests.dll" "x:\\builds\\test-reports"

Script d'exécution PowerShell

Le script PowerShell suivant encapsule l'appel à vstest.console.exe. Il gère la résolution des chemins d'accès et l'invocation de l'exécutable de test.

function Invoke-LegacyVSTest {
    param (
        [Parameter(Mandatory=$true)]
        [string]$TestRunnerPath,

        [Parameter(Mandatory=$true)]
        [string]$WorkspaceRoot,

        [Parameter(Mandatory=$true)]
        [string]$RelativeAssemblyPath,

        [Parameter(Mandatory=$true)]
        [string]$ReportDestination
    )

    $absoluteAssemblyPath = Join-Path -Path $WorkspaceRoot -ChildPath $RelativeAssemblyPath

    if ($RelativeAssemblyPath.StartsWith("/") -or $RelativeAssemblyPath.StartsWith("\")) {
        $absoluteAssemblyPath = $RelativeAssemblyPath
    }

    Write-Host "Assembly cible pour les tests : $absoluteAssemblyPath"
    Write-Host "Répertoire de l'exécutable vstest : $TestRunnerPath"
    Write-Host "Destination des rapports : $ReportDestination"

    Set-Location -Path $TestRunnerPath
    & ".\vstest.console.exe" $absoluteAssemblyPath
}

Défis techniques restants

Lors de la mise en place de cette pipeline, deux problématiques principales subsistent :

  • Comment propager correctement le code de sortie (exit code) de PowerShell pour que GitLab Runner marque le job comme échoué en cas d'erruer de test ?
  • Quelle est la meilleure méthode pour générer des rapports de tests lisibles (ex: TRX, JUnit) et les intégrer directement dans l'interface utilisateur de GitLab ?

Étiquettes: gitlab-ci DotNet-Framework NUnit vstest PowerShell

Publié le 11 juillet à 04h06