Question

Ayant récemment découvert cette méthode de développement, je la trouve plutôt jolie. Donc, pour mon premier projet, j’ai une petite DLL de code (en C # .NET, ça vaut le coup), et je veux faire une série de tests pour ce code, mais je suis un peu perdue sur comment et par où commencer.

J'utilise NUnit et VS 2008, des conseils sur le type de classes à utiliser, les objets pour lesquels écrire des tests et des conseils sur la marche à suivre pour déplacer du code vers un développement basé sur le test seraient grandement appréciés. .

Était-ce utile?

La solution

Voir le livre Travailler efficacement avec du code hérité de Michael Feathers.

En résumé, la refactorisation du code existant en code testable et testé demande beaucoup de travail. Parfois, c'est trop de travail pour être pratique. Cela dépend de la taille de la base de code et du degré de dépendance des différentes classes et fonctions.

Le refactoring sans test introduira des changements de comportement (bugs). Et les puristes diront que ce n'est pas vraiment une refactorisation à cause du manque de tests pour vérifier que le comportement ne change pas.

Plutôt que d'ajouter simultanément des tests à l'ensemble de votre application, ajoutez des tests lorsque vous travaillez dans une zone de code. Il est très probable que vous deviez revenir à ces "points chauds". encore.

Ajoutez des tests de bas en haut: testez l'exactitude des petites classes et fonctions indépendantes.

Ajoutez des tests de haut en bas: testez des sous-systèmes entiers sous forme de boîtes noires pour voir si leur comportement change avec les modifications de code. Et vous pouvez donc les parcourir pour savoir ce qui se passe. Cette approche vous apportera probablement le plus d'avantages.

Ne soyez pas trop préoccupé au début par ce que le "correct" " comportement est pendant que vous ajoutez des tests, cherchez à détecter et à éviter les changements de comportement. Les grands systèmes non testés ont souvent des comportements internes qui peuvent sembler incorrects, mais dont dépendent d'autres parties du système.

Pensez à isoler les dépendances telles que la base de données, le système de fichiers, le réseau, de manière à pouvoir les échanger contre des fournisseurs de données fictifs lors des tests.

Si le programme ne possède pas d'interfaces internes ni de lignes définissant la limite entre un sous-système / une couche et une autre, vous devrez peut-être essayer de les introduire et de les tester.

De plus, des frameworks moqueurs automatiques tels que Rhinomocks ou Moq pourrait vous aider à simuler des classes existantes ici. Je n'ai pas vraiment trouvé la nécessité de les utiliser dans un code conçu pour la testabilité.

Autres conseils

Travailler efficacement avec du code hérité est ma bible pour la migration de code sans tests dans un environnement testé par unités, il fournit également de nombreuses informations sur ce qui rend le code facile à tester et comment le tester.

J'ai également trouvé le développement piloté par les tests et Les tests unitaires pragmatiques: en C # avec NUnit constituent une bonne introduction aux tests unitaires dans cet environnement.

Une approche simple pour démarrer TDD consiste à commencer à écrire des tests à partir de ce jour et à vous assurer que chaque fois que vous devez toucher votre code existant (non testé par une unité), vous écrivez des tests réussis qui vérifient le comportement existant du système. avant de le changer afin que vous puissiez relancer ces tests après pour augmenter votre confiance en ce que vous n’avez rien cassé.

Je l'appelle "ingénierie inverse pilotée par les tests".

Commencez par "en bas" - chaque classe peut être examinée séparément et un test écrit pour elle. En cas de doute, devinez.

Lorsque vous effectuez un TDD ordinaire dans le sens aller, vous considérez le test comme sacré et supposez que le code est probablement cassé. Parfois, le test est faux, mais votre position de départ est que c'est le code.

Lorsque vous utilisez TDRE, le code est sacré - jusqu'à ce que vous puissiez prouver que le code contient un bogue existant de longue date. Dans le cas contraire, vous écrivez des tests autour du code, peaufinant les tests jusqu'à ce qu'ils fonctionnent et déclarez que le code fonctionne.

Ensuite, vous pouvez creuser dans le mauvais code. Certains mauvais cade auront des cas de test sensibles - cela doit juste être nettoyé. Certains mauvais codes, cependant, auront également un test élémentaire insensé. Cela peut être un bug ou une conception maladroite que vous pourrez peut-être rectifier.

Pour déterminer si le code est réellement incorrect, vous devez également commencer par le haut des cas de test globaux. Les données en direct qui fonctionnent réellement sont un début. En outre, les données en direct qui produisent l’un des bugs connus sont également un bon point de départ.

J'ai écrit de petits générateurs de code pour transformer les données en temps réel en cas extrêmement difficiles. De cette façon, j'ai une base cohérente pour les tests et la refactorisation.

Le code testable est facile à repérer - grâce aux tests qui l’accompagnent. S'il y en a, ça doit être testable. S'il n'y en a pas, supposez le contraire. ;)

Cela dit: le développement piloté par les tests (TDD) n’est pas tant une stratégie de test que une stratégie de conception. Les tests que vous écrivez d’abord vous aideront à concevoir l’interface de vos classes et à définir correctement le contenu de vos classes (ou de vos sous-systèmes).

Avoir les tests que vous avez créés pendant le TDD et les exécuter plus tard est un bon test, mais n’est qu’un effet secondaire (très apprécié) de cette philosophie de conception.

Ceci dit, attendez-vous à une certaine résistance de votre code contre les tests. Écoutez votre code et changez l'interface afin d'être facilement testable. Vous devrez probablement le redéfinir lorsque vous commencerez à écrire des tests.

Votre DLL fournit une sorte de service. Pour chaque service, que devez-vous faire avant d’obtenir ce service, quels paramètres devez-vous définir pour obtenir ce service? Comment sauriez-vous que le service demandé a été exécuté correctement?

Une fois que vous avez les réponses à ces questions, vous pouvez écrire un premier test. De tels tests s'appelleraient plutôt Tests de caractérisation plutôt que des tests unitaires, mais seraient probablement plus facile à écrire que les tests unitaires si la DLL n’a pas été développée avec TDD.

Les tests de caractérisation sont également décrits dans la rubrique "Utilisation efficace avec le code hérité" de M. Feathers, recommandée dans d'autres réponses.

Assurez-vous également d’écrire un test qui a échoué avant d’ajouter une nouvelle ligne de code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top