Question

J'ai lu quelque chose sur TDD et j'aimerais l'utiliser pour mon prochain projet, mais je ne suis pas sûr de savoir comment structurer mes cours avec ce nouveau paradigme. Le langage que je voudrais utiliser est Java, bien que le problème ne soit pas spécifique à un langage.

Le projet

J'ai quelques éléments matériels qui sont fournis avec une interface ASCII sur RS232. Je peux émettre des commandes simples, obtenir des réponses simples et les contrôler comme si elles se trouvaient sur leur panneau avant. Chacune a une syntaxe légèrement différente et des ensembles de commandes très différents. Mon objectif est de créer une abstraction / interface afin de pouvoir les contrôler via une interface graphique et / ou des appels de procédures distantes.

Le problème

Je pense que la première étape consiste à créer une classe abstraite (les noms me manquent, que diriez-vous de "Communicator"?) pour implémenter tous les éléments tels que Serial I / O, puis créer une sous-classe pour chaque périphérique. Je suis sûr que ce sera un peu plus compliqué que cela, mais c'est le cœur de l'application dans mon esprit.

Maintenant, pour les tests unitaires, je ne pense pas avoir vraiment besoin du matériel réel ni d’une connexion série. Ce que j'aimerais faire, c'est de donner à mes communicateurs un InputStream et un OutputStream (ou un Lecteur et un Graveur) pouvant provenir d'un port série, d'un fichier, d'une stdin / stdout, d'une fonction de test, etc. Alors, le constructeur de Communicator prendrait-il ces entrées comme entrées? Si tel est le cas, il serait facile de mettre la responsabilité de tout mettre en place sur le cadre de test, mais dans les faits, qui établit la connexion? Un constructeur séparé? La fonction appelant le constructeur encore? Une classe distincte dont le travail consiste à "connecter" le Communicator aux flux d’entrée / sortie appropriés?

Modifier

J'étais sur le point de réécrire la section sur le problème afin d'obtenir des réponses à la question que je pensais poser, mais je pense l'avoir résolue. J'avais (correctement?) Identifié deux domaines fonctionnels différents.

1) Traitement du port série

2) Communication avec le périphérique (compréhension de ses sorties et commandes de génération)

Il y a quelques mois, j'aurais tout combiné en un seul cours. Ma première idée pour rompre avec cette idée était de ne transmettre que les flux d'E / S à la classe qui comprend le périphérique, et je ne pouvais pas déterminer qui serait alors responsable de la création des flux.

Après avoir effectué davantage de recherches sur l'inversion de contrôle, je pense avoir une réponse. Avoir une interface et une classe séparées qui résolvent le problème n ° 1 et le transmettre au constructeur de la ou des classes qui résolvent le problème n ° 2. De cette façon, il est facile de tester les deux séparément. N ° 1 en se connectant au matériel réel et en permettant au framework de test de faire différentes choses. Le n ° 2 peut être testé en utilisant un modèle de n ° 1.

Cela vous semble-t-il raisonnable? Dois-je partager plus d'informations?

Était-ce utile?

La solution

Avec TDD, vous devez faire émerger votre conception , commencer petit, par petits pas et élargir petit à petit les tests de votre classe.

CLARIFIED: Commencez avec une classe concrète, pour envoyer une commande, puis testez-la avec une maquette ou un moignon. Quand cela fonctionnera assez (peut-être pas avec toutes les options), testez-le une fois avec votre vrai appareil pour valider votre maquette / stub / simulateur.

Une fois que la classe de la première commande est opérationnelle, commencez à implémenter une deuxième commande, de la même manière: revenez tout d'abord à votre maquette / stub, puis une fois contre le périphérique pour validation. Maintenant, si vous voyez des similitudes entre vos deux classes, vous pouvez refactoriser votre conception basée sur des classes abstraites - ou quelque chose de différent.

Autres conseils

Désolé d'être un peu centré sur Linux ..

Ma manière préférée de simuler des gadgets est de écrire des pilotes de périphérique de caractères qui simuler leur comportement. Cela vous donne également des capacités amusantes, comme celle de fournir une interface ioctl () qui rend le périphérique simulé anormal.

À ce stade ... des tests au monde réel, seul le (s) périphérique (s) que vous ouvrez, lisez et écrivez réellement.

Il ne devrait pas être trop difficile d’imiter le comportement de vos gadgets. Ils semblent prendre des instructions très basiques et renvoyer des réponses très basiques. Encore une fois, un simple ioctl () pourrait indiquer au périphérique simulé qu'il est temps qu'il se comporte mal, afin que vous puissiez vous assurer que votre code gère correctement ces événements. Par exemple, échouez intentionnellement à chaque énième instruction, où n est sélectionné de manière aléatoire lors de l’appel de ioctl ().

Après avoir vu vos modifications, je pense que vous vous dirigez exactement dans la bonne direction. TDD a tendance à vous conduire vers une conception composée de petites classes avec une responsabilité bien définie. Je voudrais également faire écho aux conseils de tinkertim: un simulateur de dispositif que vous pouvez contrôler et "provoquer". se comporter de différentes manières est inestimable pour les tests.

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