J'ai écrit quelques algorithmes de tri pour une affectation de classe et j'ai également écrit quelques tests pour m'assurer que les algorithmes ont été correctement implémentés. Mes tests ne font que 10 lignes et il y en a 3 mais seulement 1 ligne change entre les 3 donc il y a beaucoup de code répété. Est-il préférable de refactoriser ce code dans une autre méthode qui est ensuite appelée à partir de chaque test? Ne devrais-je pas alors écrire un autre test pour tester le refactoring? Certaines variables peuvent même être déplacées au niveau de la classe. Les classes et méthodes de test doivent-elles suivre les mêmes règles que les classes / méthodes normales?
Voici un exemple:
[TestMethod]
public void MergeSortAssertArrayIsSorted()
{
int[] a = new int[1000];
Random rand = new Random(DateTime.Now.Millisecond);
for(int i = 0; i < a.Length; i++)
{
a[i] = rand.Next(Int16.MaxValue);
}
int[] b = new int[1000];
a.CopyTo(b, 0);
List<int> temp = b.ToList();
temp.Sort();
b = temp.ToArray();
MergeSort merge = new MergeSort();
merge.mergeSort(a, 0, a.Length - 1);
CollectionAssert.AreEqual(a, b);
}
[TestMethod]
public void InsertionSortAssertArrayIsSorted()
{
int[] a = new int[1000];
Random rand = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < a.Length; i++)
{
a[i] = rand.Next(Int16.MaxValue);
}
int[] b = new int[1000];
a.CopyTo(b, 0);
List<int> temp = b.ToList();
temp.Sort();
b = temp.ToArray();
InsertionSort merge = new InsertionSort();
merge.insertionSort(a);
CollectionAssert.AreEqual(a, b);
}
givenThereAreProductsSet(amount)
et même aussi simples queactWith(param)
. J'ai réussi à le faire avec une bonne maîtrise de l'api (par exemplegivenThereAre(2).products()
) une fois, mais j'ai rapidement arrêté parce que c'était comme une surpuissance.Comme Oded l'a déjà dit, le code de test doit encore être maintenu. J'ajouterais que la répétition dans le code de test rend plus difficile pour les mainteneurs de comprendre la structure des tests et d'ajouter de nouveaux tests.
Dans les deux fonctions que vous avez publiées, les lignes suivantes sont absolument identiques, à l'exception d'une différence d'espace au début de la
for
boucle:Ce serait un candidat parfait pour passer à une sorte de fonction d'aide, dont le nom indique qu'il initialise des données.
la source
Non, ce n'est pas OK. Vous devez utiliser un TestDataBuilder à la place. Vous devez également faire attention à la lisibilité de vos tests: a? 1000? b? Si demain il faut travailler sur l'implémentation que vous testez, les tests sont un excellent moyen d'entrer dans la logique: écrivez vos tests pour vous autres programmeurs, pas pour le compilateur :)
Voici votre implémentation de tests, "revampée":
la source
Encore plus que le code de production, le code de test doit être optimisé pour la lisibilité et la maintenabilité, car il doit être maintenu tout au long du code testé et également lu dans le cadre de la documentation. Considérez comment le code copié peut rendre la maintenance du code de test plus difficile et comment cela peut devenir une incitation à ne pas écrire de tests pour tout. N'oubliez pas non plus que lorsque vous écrivez une fonction pour sécher vos tests, elle doit également être soumise à des tests.
la source
La duplication de code pour les tests est un piège facile à tomber. Bien sûr, c'est pratique, mais que se passe-t-il si vous commencez à refactoriser votre code d'implémentation et que vos tests commencent tous à changer? Vous courez les mêmes risques que vous si vous avez dupliqué votre code d'implémentation, dans la mesure où vous devrez probablement changer votre code de test à de nombreux endroits également. Tout cela représente une perte de temps considérable et un nombre croissant de points de défaillance à traiter, ce qui signifie que le coût de maintenance de votre logiciel devient inutilement élevé et réduit donc la valeur commerciale globale du logiciel que vous travailler sur.
Considérez également que ce qui est facile à faire dans les tests deviendra facile à faire dans la mise en œuvre. Lorsque vous êtes pressé par le temps et que vous subissez beaucoup de stress, les gens ont tendance à s'appuyer sur des modèles de comportement appris et essaient généralement de faire ce qui semble le plus facile à l'époque. Donc, si vous trouvez que vous copiez et collez une grande partie de votre code de test, il est probable que vous fassiez de même dans votre code d'implémentation, et c'est une habitude que vous voulez éviter au début de votre carrière, pour vous faire économiser beaucoup de difficulté plus tard lorsque vous vous retrouvez devant conserver un code plus ancien que vous avez écrit et que votre entreprise ne peut pas nécessairement se permettre de réécrire.
Comme d'autres l'ont dit, vous appliquez le principal DRY et vous recherchez des opportunités de refactoriser toutes les duplications probables des méthodes et classes d'assistance, et oui, vous devriez même le faire dans vos tests afin de maximiser la réutilisation du code et d'enregistrer vous rencontrez des difficultés d'entretien plus tard. Vous pouvez même vous retrouver à développer lentement une API de test que vous pouvez utiliser encore et encore, peut-être même dans plusieurs projets - c'est certainement ainsi que les choses se sont passées pour moi au cours des dernières années.
la source