Utiliser xUnit avec MTP2 est possible, sous condition ...

Aujourd'hui, il est enfin possible d'utiliser Microsoft Testing Platform 2 (MTP) avec xUnit. Ceci passe par l'usage d'une version spécifique de xUnit. Cette version porte le doux nom de xunit.v3.mtp-v2 3.2.0.

La décision de créer un nouveau package a été motivée par le fait que l'usage de MTP2 avec le SDK, rendait impossible l'emploi de VSTest. Ceci est expliqué sur GitHub :

We have no timeline for if/when v2 becomes the default. For the foreseeable future, v1 will be the default, for backward compatibility (and because v2 + .NET 10 SDK purposefully breaks compatibility with people who need to use VSTest from dotnet test, which I felt was far too big a breaking change to allow v2 to become the default). In fact it's fair to say this compatibility issue was the primary driver for why I released this feature this way.

Source : XUnit.V3 compatible version for MTP 2.0.0 · Issue #3416 · xunit/xunit

Personnellement, le passage à .net core, et sa CLI m'avaient convaincu d'abandonner les appel directs à  VSTest. Mes builds .net étaient déjà compatibles avant l'arrivée de .net 10 (via DotNetCoreCLI sur Azure DevOps). Les early adopters se sentiront très peu concernés. Mais il faut reconnaitre que nombre d'entreprises ont encore du mal à faire évoluer leurs builds, et outils de builds au même rythme que .net.

Ironiquement, nous vivons une époque ou tout le monde veut parler DevOps, mais ne traite pas le sacro-saint CI / CD aussi bien que le reste.

Jérémy Jeanson

Comment changer facilement des paramètres lors de tests avec WebApplicationFactory ?

Pour des tests d'intégrations, il peut être compliqué de produire un fichier de configuration pour tester l'impacte de chaque paramètre.

Heureusement, avec WebApplicationFactory, il est possible de définir un paramètre dans son test via la méthode UseSetting.


public sealed class ProgramTests(WebApplicationFactory<Program> webApplicationFactory)
 : IClassFixture<WebApplicationFactory<Program>>
    {
        [Theory]
        [InlineData("/")]
        [InlineData("/error")]
        public async Task Test1(String url)
        {
            using HttpClient client = webApplicationFactory
                .WithWebHostBuilder(b =>
                {
                    b.UseEnvironment("xUnit");
                    b.UseSetting("Authentication:Type", "Internal");
                })
                .CreateClient();
 
	// ...
        }

Cerise sur le gâteau, contrairement à d'autres approches le paramètre est disponible avant l'ajout des services. Si votre application s'appuie sur des paramètres pour déduire les services à enregistrer, votre code devient testable.

Jérémy Jeanson

Comment contourner les petits problèmes de xUnit quand il est utilisé avec MTP ?

Depuis 3 semaines, si vous utilisez xUnit avec Microsot Testing Platform (MTP), vous rencontrez certainement quelques difficultés. Ces problèmes sont liés à l'arrivée de MTP 2. Actuellement, xUnit ne prend pas en charge cette version. Bien évidemment une issue a été créée sur GitHub. Elle peut être suivie ici : XUnit.V3 compatible version for MTP 2.0.0 · Issue #3416 · xunit/xunit

En attendant la résolution de celle-ci, il y a moyen de faire fonctionner xUnit avec MTP 1.

Le seul véritable problème consiste à comprendre comment MTP s'est retrouvé dans vos projets. En l'état, un projet de test ne référence pas directement MTP. Se sont les frameworks, et extensions qui références celui-ci. Comme toujours avec nuget, il suffit de consulter le détail d'un package pour en avoir le cœur net.

Par exemple, Microsoft.Testing.Extensions.CodeCoverage 18.1, dépends de MTP 2.0.0 à minima.

Interface nuget affichant le détail de Microsoft.Testing.Extensions.CodeCoverage 18.1

Si l'on regarde les versions précédentes de Microsoft.Testing.Extensions.CodeCoverage, on constate que la version 17.14.2 est la dernière version dépendant de MTP 1.

Interface nuget affichant le détail de Microsoft.Testing.Extensions.CodeCoverage 17.14.2

Si vous utilisez Microsoft.Testing.Extensions.CodeCoverage, il suffit donc d'installer la version 17.14.2, pour avoir une version compatible avec xUnit. Si vous utilisez d'autres extensions de MTP, il vous faudra vérifier chacune d'entre elles afin d'identifier les versions dépendants de MTP 1.

Petite astuce : avec Visual Studio, il est possible de visualiser rapidement les dépendances indirectes à des packages nuget en déroulant le nœud packages. Désolé, il n'y a pas d'équivaillent dans Rider.

Affichage des dépendances d'un projet de tests

Jérémy Jeanson

Les développeurs peuvent-ils encore rédiger des articles utiles, à l’aire de l’IA ?

Depuis le retour en force de l’IA, nombre de sujets sont « remis en perspective ». La tenue d’un blog, et la rédaction d’articles technique n’échappent pas à cela.

Attendez un instant je vais trop vite. Pourquoi parler d’un « retour en force » ?

L’IA, c’est tout beau, c’est tout nouveau, et c’est partout depuis 3 ans !

… et bien non.

Nous sommes nombreux à avoir joué avec l’IA avant les LLM, et la publication de Chat GPT (novembre 2022), et avant même la création d’Open AI (décembre 2015). Peut-être que les 7 ans d’écart entre 2015, et 2022, vous font un peu réfléchir. Si oui, c’est une bonne chose.

L’IA, ça n’est pas nouveau. Personnellement, j’ai réalisé mes premiers projets .net utilisant des service d’IA en 2015. Les vrais spécialistes de l’IA ont commencé bien avant l’an 2000.

Mais revenons à nos moutons. À force d’entendre parler de l’IA qui allait tout faire, et tous nous remplacer, je me suis véritablement interrogé sur l’utilité de ce blog. Quel intérêt avais-je à poursuivre cette aventure, si tout le monde demande à l’IA dès qu’il rencontre un problème technique. J’ai donc choisi de mettre ce projet en pause durant 2 mois :

  • Passé le premier mois, je me suis demandé si le fait d’être autant impliqué dans ce blog, et les communautés de Dev ne me conduisait pas une forme de burn-out.
  • Passer le second mois, rien, nada.
  • Arrivé au troisième mois … oh ! Mais on s’était fixé dit 2 mois ?

Oui, je ne pensais pas prendre autant de temps pour moi. Mais je me suis rendu compte que je me faisais happer par le tourbillon de l’IA. J’expérimentais, je testais, j’utilisais, j’apprenais, je réapprenais. Je finissais par me demander si je gagnais du temps, ou si j’en perdais. En tant que développeur, c’était bien la première fois que le temps consacré à l’expérimentation ne se concluait pas par « un gain » (nouvelle compétence, nouvelle pratique, nouvel outil, etc.). Le temps consacré à l’IA telle qu’on en parle en 2025, c’était conclu pour moi en un retour à la case départ.

Oui, finalement il m’a fallu presque trois mois pour me dire que ce blog faisait partie du puzzle. Les IA ont besoin de contenu, et de personnes qui adoptent rapidement les technologies, car elles sont véritablement à la ramasse quand on parle de nouveautés. Aujourd’hui, peut-être même plus qu’hier, la communauté a besoin de développeurs qui partagent leur avis, et des retours expérience concrets sans langue de bois. Faire tout le reste sans tenir ce blog n’a plus trop de sens.

Je relance donc ce blog. Les contenus sont partis pour être très variés. Avec un peu d’IA, mais pas trop.


PS : Je pense que chacun doit avoir une posture vis-à-vis des IA. Moi, je ne suis pas un spécialiste de l’IA. Je suis un développeur qui sait l’implémenter dans ces réalisations.

Jérémy Jeanson

Comment faire un bon usage des attributs CLSCompliant ?

La bonne pratique voudrait que tout code .net soit CLS Compliant. Aujourd'hui, on peut se demander pourquoi faire la remarque. Mais, je me suis rendu compte que nombre de développeurs ne savent pas ce que cela signifiait.

En une phrase : Un code CLS Compliant peut être appelé par un projet C#, F#, ou VB sans problèmes.

Quand le compilateur dit qu'un code n'est pas CLS Compliant, c'est donc qu'il y a un risque que votre librairie ne soit pas exploitable dans un autre projet. Attention : un autre projet peut utiliser votre code et compiler sans problèmes. Mais à l'exécution il peut y avoir des effets de bord.

Ex: une classe écrite en C# avec deux méthodes ayant le même nom, les mêmes arguments. Mais sur l'une d'elle, l'un des arguments est préfixé d'un "ref". VB ne sera pas en mesure de faire la différence entre ces deux méthodes.

Comme l'explique très bien la documentation, il y a beaucoup d'autres cas. Je présente celui-ci, car comme beaucoup de problèmes de codes non CLS Compliant, il y a là un problème de qualité de code. Cette manière de coder complexifie la lecture du code, et vos collègues, ou utilisateurs de votre librairie ne comprendront peut-être pas bien vos intentions.

Si vous n'utilisez un seul langage, un warning de type "not CLS Compliant" est à prendre comme un problème de qualité à traiter.

Il y aura malheureusement des cas où l'on doit utiliser des librairies, et des classes non CLS Compliant. Je pense par exemple à l'usage de très anciens interops Office.

Dans ces cas, là il y a une approche très simple à suivre :

  • Ne pas utiliser ces types comme arguments de vos méthodes publiques.
  • Créer des classes "passe-plat" qui seront CLS Compliant, et qui porteront les propriétés dont vous avez besoin pour créer en interne l'objet non CLS Compliant.

Si cela n'est pas possible, il faut marquer la classe avec l'attribut suivant (ceci est le dernier recours, on est d'accord?):


[CLSCompliant(false)]

Mais surtout, il ne faut pas utiliser cet attribut au niveau de l'assembly. Si vous l'avez dans votre projet, passez-le temporairement à true pour observer les dégâts, et planifier leur remédiation.


[assembly: CLSCompliant(true)]

Cet attribut mis à false, est là pour cacher la misère. Il finira toujours par propager les problèmes.

Jérémy Jeanson