J'ai écrit une classe qui gère les destinataires sur une liste MailChimp, appelée MailChimpRecipient. Il utilise la classe MCAPI, qui est un wrapper d'API tiers.
http://apidocs.mailchimp.com/api/1.3/ http://apidocs.mailchimp.com/api/downloads/
Je passe l'objet MCAPI dans le constructeur de l'objet MailChimpRecipient, j'ai donc écrit des tests unitaires en utilisant PHPUnit qui testent toute la logique de ma propre classe (je ne teste pas la classe MCAPI). J'ai une couverture de code à 100% et tous les tests réussissent. Cela se fait en se moquant et en stubant l'objet MCAPI.
Ma prochaine étape était d'écrire un test d'intégration, également en utilisant PHPUnit, où je construirais le luminaire MailChimpRecipient en utilisant un véritable objet MCAPI, configuré pour utiliser une vraie liste MailChimp.
J'ai écrit ce que je pense être un test d'intégration, qui exécute essentiellement des tests contre l'interface publique de l'objet, comme:
public function testAddedRecipientCanBeFound()
{
$emailAddress = '[email protected]';
$forename = 'Fred';
$surname = 'Smith';
// First, delete the email address if it is already on the list
$oldRecipient = $this->createRecipient();
if($oldRecipient->find($emailAddress))
{
$oldRecipient->delete();
}
unset($oldRecipient);
// Add the recipient using the test data
$newRecipient = $this->createRecipient();
$newRecipient->setForename($forename);
$newRecipient->setSurname($surname);
$newRecipient->setEmailAddress($emailAddress);
$newRecipient->add();
unset($newRecipient);
// Assert that the recipient can be found using the same email address
$this->assertTrue($this->_recipient->find($emailAddress));
}
Le test «d'intégration» ne teste aucun des éléments internes de la classe - il s'assure simplement que, étant donné un véritable objet MCAPI, il se comporte comme annoncé.
Est-ce correct? Est-ce la meilleure façon d'exécuter un test d'intergation? Après tout, les internes ont été testés avec un test unitaire. Ai-je raison de penser que le test d'intégration est là pour vérifier qu'il fonctionne vraiment, selon la façon dont son comportement est annoncé?
Pour aller plus loin, la classe MailChimpRecipient implémente une interface, qui sera également implémentée par d'autres classes. L'idée est d'utiliser une fabrique pour transmettre différents types d'objets destinataires de liste de diffusion à mon code, qui font tous la même chose, mais en utilisant différents fournisseurs de liste de diffusion. Étant donné que mes tests d'intégration testent cette interface, que diriez-vous de l'utiliser pour toutes les classes qui implémentent l'interface? Ensuite, à l'avenir, si je conçois une nouvelle classe à utiliser de manière interchangeable, je peux exécuter le même test d'intégration avant de l'insérer dans un projet.
Cela vous semble-t-il raisonnable? Les tests unitaires testent les composants internes d'un objet, les tests d'intégration s'assurent qu'il se comporte comme annoncé?
la source
setUp
fonction pour établir les motifs pour exécuter vos tests. Si l'entrée n'est pas définie, vous ne pouvez pas vraiment tester. L'entrée doit être précise, stricte et toujours la même. Si une condition préalable d'un test n'est pas remplie, ignorez le test à la place. Ensuite, analysez pourquoi il saute et si vous devez ajouter des tests supplémentaires et / ou si celasetUp
n'est pas fait correctement.DataProvider
(c'est une fonction offrant une entrée en tant que paramètres à un test).Réponses:
Lors du test de votre code, vous devez faire attention à trois domaines:
Normalement, la quantité de test que vous avez dans chaque catégorie aurait la forme d'une pyramide, ce qui signifie beaucoup de tests unitaires en bas, quelques tests fonctionnels au milieu et seulement quelques tests de scénario.
Avec un test unitaire, vous simulez tout ce que la classe testée utilise et vous le testez dans l'isolement pur (c'est pourquoi il est important de s'assurer qu'à l'intérieur de votre classe vous récupérez toutes les dépendances par injection afin qu'elles puissent être remplacées sous test).
Avec les tests unitaires, vous testez toutes les possibilités, donc non seulement le «chemin heureux» mais aussi toutes les conditions d'erreur.
Si vous êtes absolument certain que toutes vos unités fonctionnent isolément, vous écrivez quelques tests (tests fonctionnels) pour vous assurer que les unités fonctionnent également lorsqu'elles sont combinées. Ensuite, vous écrivez un test de scénario, qui teste le câblage entre tous les modules fonctionnels.
Par exemple, supposons que vous testiez une voiture.
Vous pouvez assembler toute la voiture et en tant que conducteur vérifier toutes les conditions possibles, mais ce serait vraiment difficile à faire.
Au lieu de cela, vous testeriez une petite partie du moteur avec toutes les possibilités (test unitaire)
Ensuite, vous testez l'ensemble du moteur (séparé de la voiture) qui serait un test fonctionnel.
Comme dernier test, vous introduisez votre clé, démarrez la voiture et la conduisez jusqu'au parking. Si cela fonctionne, vous savez que toutes les pièces (batterie, carburant, moteur, ..) sont connectées et puisque vous les avez testées isolément, vous pouvez être sûr que toute la voiture fonctionne correctement.
Donc, dans votre cas, vous avez testé toutes les conditions d'erreur et le cheminement heureux dans votre test unitaire et savez que vous n'avez qu'à effectuer un test de bout en bout avec les `` vrais composants '' pour vérifier si le câblage est correct.
Quelques autres points,
la source