Il est.
Même si vous ne faites que des tests unitaires, il n’est pas inhabituel d’avoir plus de code dans les tests que le code réellement testé. Il n'y a rien de mal à cela.
Considérons un code simple:
public void SayHello(string personName)
{
if (personName == null) throw new NullArgumentException("personName");
Console.WriteLine("Hello, {0}!", personName);
}
Quels seraient les tests? Il y a au moins quatre cas simples à tester ici:
Le nom de la personne est null
. Une exception est-elle réellement levée? Cela fait au moins trois lignes de code de test à écrire.
Le nom de la personne est "Jeff"
. Sommes-nous "Hello, Jeff!"
en réponse? C'est quatre lignes de code de test.
Le nom de la personne est une chaîne vide. À quelle sortie attendons-nous? Quelle est la sortie réelle? Question secondaire: cela correspond-il aux exigences fonctionnelles? Cela signifie quatre autres lignes de code pour le test unitaire.
Le nom de la personne est suffisamment court pour une chaîne, mais trop long pour être combiné avec "Hello, "
le point d'exclamation. Qu'est-ce qui se passe? ¹
Cela nécessite beaucoup de code de test. De plus, les éléments de code les plus élémentaires nécessitent souvent un code de configuration qui initialise les objets nécessaires au code testé, ce qui conduit souvent à l'écriture de stubs et de mocks, etc.
Si le rapport est très grand, dans ce cas, vous pouvez vérifier quelques points:
Existe-t-il une duplication de code dans les tests? Le fait qu'il s'agisse d'un code de test ne signifie pas que le code doit être dupliqué (copier-coller) entre des tests similaires: une telle duplication rendra difficile la maintenance de ces tests.
Y a-t-il des tests redondants? En règle générale, si vous supprimez un test unitaire, la couverture des branches devrait diminuer. Si ce n'est pas le cas, cela peut indiquer que le test n'est pas nécessaire, car les chemins sont déjà couverts par d'autres tests.
Testez-vous uniquement le code que vous devriez tester? Vous n'êtes pas censé tester la structure sous-jacente des bibliothèques tierces, mais uniquement le code du projet lui-même.
Avec les tests de fumée, les tests de système et d'intégration, les tests de fonctionnement et d'acceptation, ainsi que les tests de contrainte et de charge, vous ajoutez encore plus de code de test. Il ne faut donc pas s'inquiéter d'avoir quatre ou cinq LOCs de tests pour chaque LOC de code réel.
Une note sur le TDD
Si vous êtes préoccupé par le temps nécessaire pour tester votre code, il se peut que vous le fassiez mal, c'est-à-dire le code d'abord, puis les tests plus tard. Dans ce cas, TDD peut vous aider en vous encourageant à travailler dans des itérations de 15 à 45 secondes, en alternant code et tests. Selon les partisans de TDD, cela accélère le processus de développement en réduisant à la fois le nombre de tests que vous devez faire et, plus important encore, le nombre de codes d’entreprise à écrire et surtout la réécriture des tests.
¹ Soit n soit la longueur maximale d'une chaîne . Nous pouvons appeler SayHello
et transmettre par référence une chaîne de longueur n - 1 qui devrait fonctionner correctement. Maintenant, à l’ Console.WriteLine
étape, le formatage doit se terminer par une chaîne de longueur n + 8, ce qui entraînera une exception. Peut-être, en raison des limites de mémoire, même une chaîne contenant n / 2 caractères entraînera une exception. La question à se poser est de savoir si ce quatrième test est un test unitaire (il en a l'air, mais peut avoir un impact beaucoup plus important en termes de ressources que les tests unitaires moyens) et s'il teste le code réel ou le framework sous-jacent.