Bonnes pratiques XUnit
Votre objectif est de vous aider à écrire des tests unitaires efficaces avec XUnit, couvrant les approches de test standard et piloté par les données.
Configuration du projet
- Utilisez un projet de test distinct avec la convention de nommage
[ProjectName].Tests - Référencez les packages Microsoft.NET.Test.Sdk, xunit et xunit.runner.visualstudio
- Créez des classes de test correspondant aux classes testées (par exemple,
CalculatorTestspourCalculator) - Utilisez les commandes de test du SDK .NET :
dotnet testpour exécuter les tests
Structure des tests
- Aucun attribut de classe de test requis (contrairement à MSTest/NUnit)
- Utilisez les tests basés sur des faits avec l'attribut
[Fact]pour les tests simples - Suivez le modèle Arrange-Act-Assert (AAA)
- Nommez les tests selon le modèle
MethodName_Scenario_ExpectedBehavior - Utilisez le constructeur pour la configuration et
IDisposable.Dispose()pour le nettoyage - Utilisez
IClassFixture<T>pour le contexte partagé entre les tests d'une classe - Utilisez
ICollectionFixture<T>pour le contexte partagé entre plusieurs classes de test
Tests standard
- Maintenez les tests focalisés sur un seul comportement
- Évitez de tester plusieurs comportements dans une même méthode de test
- Utilisez des assertions claires qui expriment l'intention
- N'incluez que les assertions nécessaires pour vérifier le cas de test
- Rendez les tests indépendants et idempotents (peuvent s'exécuter dans n'importe quel ordre)
- Évitez les dépendances entre tests
Tests pilotés par les données
- Utilisez
[Theory]combiné avec les attributs de source de données - Utilisez
[InlineData]pour les données de test en ligne - Utilisez
[MemberData]pour les données basées sur une méthode - Utilisez
[ClassData]pour les données basées sur une classe - Créez des attributs de données personnalisés en implémentant
DataAttribute - Utilisez des noms de paramètres significatifs dans les tests pilotés par les données
Assertions
- Utilisez
Assert.Equalpour l'égalité des valeurs - Utilisez
Assert.Samepour l'égalité des références - Utilisez
Assert.True/Assert.Falsepour les conditions booléennes - Utilisez
Assert.Contains/Assert.DoesNotContainpour les collections - Utilisez
Assert.Matches/Assert.DoesNotMatchpour les correspondances d'expressions régulières - Utilisez
Assert.Throws<T>ouawait Assert.ThrowsAsync<T>pour tester les exceptions - Utilisez la bibliothèque d'assertions fluides pour des assertions plus lisibles
Mocking et isolation
- Envisagez d'utiliser Moq ou NSubstitute avec XUnit
- Simulez les dépendances pour isoler les unités testées
- Utilisez les interfaces pour faciliter la simulation
- Envisagez d'utiliser un conteneur DI pour les configurations de test complexes
Organisation des tests
- Regroupez les tests par fonctionnalité ou composant
- Utilisez
[Trait("Category", "CategoryName")]pour la catégorisation - Utilisez les fixtures de collection pour regrouper les tests avec des dépendances partagées
- Envisagez d'utiliser les assistants de sortie (
ITestOutputHelper) pour les diagnostics de test - Ignorez conditionnellement les tests avec
Skip = "reason"dans les attributs fact/theory