Derniers tips / Mémos
Modélise nativement « exactement l'un de ces types », avec un switch exhaustif vérifié par le compilateur.
Fin des state machines générées par le compilateur : moins d'allocations et des stack traces enfin lisibles.
Recherche sémantique directement dans SQL Server 2025, sans base vectorielle séparée, en LINQ typé.
Framework UI cross-platform pour .NET : Windows, macOS, Linux, iOS, Android et WebAssembly.
Découvrez les nouvelles APIs asynchrones pour la compression ZIP et les améliorations de performance dans .NET 10
xUnit : framework de tests unitaires pour .NET
xUnit est le framework de tests de référence pour .NET, simple à utiliser et extensible.
Structure d'un test
Un test xUnit suit souvent le pattern Arrange‑Act‑Assert. Utilisez [Fact] pour un cas fixe et [Theory] avec InlineData pour des cas paramétrés.
using Xunit;
public class CalculatorTests
{
[Fact]
public void Add_TwoIntegers_ReturnsSum()
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert
Assert.Equal(5, result);
}
}Theory et données
Les Theories permettent d'exécuter le même test avec différentes données d'entrée via [InlineData] ou des providers.
[Theory]
[InlineData(2, 3, 5)]
[InlineData(10, 20, 30)]
[InlineData(-1, 1, 0)]
public void Add_DifferentValues_ReturnsExpectedSum(int a, int b, int expected)
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(a, b);
// Assert
Assert.Equal(expected, result);
}Tests asynchrones
xUnit supporte nativement async/await. Évitez .Result/.Wait() pour prévenir les deadlocks.
[Fact]
public async Task ProcessDataAsync_ValidInput_ReturnsProcessedData()
{
// Arrange
var service = new DataService();
var inputData = "test";
// Act
var result = await service.ProcessDataAsync(inputData);
// Assert
Assert.NotNull(result);
Assert.Contains("processed", result);
}Fixtures et partage de données
IClassFixture et CollectionFixture permettent de partager un contexte entre tests sans ordre d'exécution imposé.
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
// Setup database connection
Database = new TestDatabase();
Database.Initialize();
}
public TestDatabase Database { get; private set; }
public void Dispose()
{
Database.Dispose();
}
}
public class DatabaseTests : IClassFixture<DatabaseFixture>
{
private readonly DatabaseFixture _fixture;
public DatabaseTests(DatabaseFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void CanConnectToDatabase()
{
Assert.True(_fixture.Database.IsConnected);
}
}Mocking et isolation
Utilisez des frameworks comme NSubstitute ou Moq pour isoler les dépendances et vérifier les interactions.
public class UserServiceTests
{
[Fact]
public void GetUser_ExistingId_ReturnsUser()
{
// Arrange
var mockRepository = new Mock<IUserRepository>();
var expectedUser = new User { Id = 1, Name = "John" };
mockRepository.Setup(x => x.GetById(1)).Returns(expectedUser);
var service = new UserService(mockRepository.Object);
// Act
var result = service.GetUser(1);
// Assert
Assert.Equal(expectedUser, result);
mockRepository.Verify(x => x.GetById(1), Times.Once);
}
}Collections de tests
Les collections regroupent des classes de tests qui partagent un même fixture, utile pour éviter des initialisations coûteuses répétées.
[Collection("Database collection")]
public class IntegrationTest1
{
// Tests qui partagent la même instance de base de données
}
[Collection("Database collection")]
public class IntegrationTest2
{
// Tests qui partagent la même instance de base de données
}Sortie de test (ITestOutputHelper)
Injectez ITestOutputHelper pour tracer des informations de debug lorsqu'un test est exécuté.
public class DebuggingTests
{
private readonly ITestOutputHelper _output;
public DebuggingTests(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void ComplexTest_WithDebugging()
{
_output.WriteLine("Starting complex test");
var data = GenerateTestData();
_output.WriteLine($"Generated {data.Count} items");
var result = ProcessData(data);
_output.WriteLine($"Processing completed with result: {result}");
Assert.True(result);
}
}Ignorer / mettre en attente un test
Utilisez l'attribut Skip sur [Fact] ou [Theory] pour désactiver temporairement un test. Renseignez toujours une raison explicite pour faciliter le suivi.
using Xunit;
public class SkippingExamples
{
[Fact(Skip = "Feature temporarily disabled")]
public void This_test_is_skipped()
{
// Not executed
}
[Theory(Skip = "Unstable on CI for now")]
[InlineData(1)]
[InlineData(2)]
public void Skipped_theory(int value)
{
// Not executed
}
}Préférez corriger ou isoler un test instable. N'utilisez Skip que temporairement (ex: fonctionnalité désactivée, données externes indisponibles).
Bonnes pratiques
Nommez vos tests de manière descriptive
Séparez clairement Arrange, Act et Assert
Une seule assertion logique par test
Rendez les tests indépendants
Gardez des tests rapides
Conclusion
xUnit fournit une base solide pour des tests fiables et maintenables, avec un modèle extensible et moderne.