Bien que ce ne soit pas entièrement lié à la question et que ce soit peut-être un peu trivial, j'aimerais apporter mon grain de sel à ce sujet général (c'était la question la plus pertinente que j'ai pu trouver pour y poster).
Dans le cadre du projet sur lequel je travaille actuellement, j'ai ressenti le besoin de réaliser des tests unitaires simples basés sur des données (par exemple, avec une vingtaine de lignes pour un test donné). Ma liste de souhaits pour un "framework" orienté données était la suivante :
- Intégration facile et agréable dans l'explorateur de tests de Visual Studio.
- Possibilité de continuer à utiliser les raccourcis clavier existants pour exécuter/déboguer la méthode de test dans laquelle se trouve le curseur.
- Pas de fichiers ou de bases de données externes à gérer (c'est-à-dire pas de "DataSources").
- Support "natif" dans C# et Visual Studio, c'est-à-dire qu'aucun paquetage supplémentaire n'est nécessaire.
Malgré le souhait n°4, je me suis penché sur les bibliothèques externes comme xUnit et NUnit. Elles semblaient résoudre le souhait n°3, mais ne faisaient pas un bon travail pour les souhaits n°1 et n°2.
Frustré par l'absence d'une solution simple, j'ai décidé de mettre en œuvre moi-même une aide très basique basée sur les données :
public static void DataDrivenTest(Action<List<object>> testAction, List<List<object>> dataRows)
{
foreach (var dataRow in dataRows)
testAction(dataRow);
}
Je l'utilise comme ça :
[TestMethod]
public void Unit_Can_Add_Two_Numbers()
{
UnitTestUtilities.DataDrivenTest(
dataRow =>
{
// Tests a+b=c
var a = (int)dataRow[0];
var b = (int)dataRow[1];
var c = (int)dataRow[2];
Assert.AreEqual(a + b, c);
},
new List<List<object>>
{
// Rows of arguments a,b,c respectively
new List<object>{1,2,3},
new List<object>{4,5,9}
});
}
Bien qu'il réponde à tous mes souhaits ci-dessus, il présente des inconvénients :
- Le moulage est nécessaire dans la définition de l'action de test (cela pourrait probablement être corrigé avec une magie d'argument générique).
- La mise à jour de l'ordre des arguments dans les lignes de données signifie que les accesseurs de la méthode d'action doivent également être mis à jour.
- Il est clair que cette aide n'est pas appropriée pour les grands tests basés sur des données (par exemple, cette aide serait désordonnée pour plus de, disons, 20 lignes de test).
- Il manque clairement de "sophistication", c'est-à-dire que je suis sûr que des bibliothèques comme xUnit ont des fonctionnalités bizarres qu'il ne possède pas.
- Il exécute toutes les lignes comme un seul test unitaire (c'est-à-dire qu'il n'y a pas de test unitaire et de rapport séparés pour chaque ligne de données).
Quoi qu'il en soit, il a résolu mon problème de base de manière simple. J'espère que cela aidera quelqu'un qui cherche une solution simple comme moi. Après tout, si vous trouvez que vous avez besoin d'une tonne de lignes de test pour tester une méthode, cela peut valoir la peine d'envisager une refactorisation pour décomposer la fonction testée en composants plus petits (et ensuite l'utiliser en conjonction avec les mocks/fakes, l'injection de dépendance, etc).