2008-09-16 4 views
8

Je suis convaincue par this presentation et par d'autres commentaires sur le site que j'ai besoin d'apprendre en test unitaire. Je me rends également compte qu'il y a eu beaucoup de questions sur ce qu'est le test unitaire ici. Chaque fois que je vais voir comment cela devrait se faire dans l'application sur laquelle je travaille actuellement, je repars confus. C'est une application d'application xulrunner, et une grande partie de la logique est basée sur les événements - lorsqu'un utilisateur clique ici, cette action a lieu.Comment une unité peut-elle tester des sections de code procédurales ou événementielles?

Souvent, les exemples que je vois pour tester sont des classes de test - ils instancient un objet, lui donnent des données fantaisie, puis vérifient les propriétés de l'objet par la suite. Cela a du sens pour moi - mais qu'en est-il des pièces non orientées objet?

This guy mentioned que le test unitaire basé sur l'interface graphique est difficile dans la plupart des cadres de test, c'est peut-être le problème. La présentation ci-dessus mentionne que chaque test ne devrait toucher qu'une classe, une méthode à la fois. Cela semble exclure ce que j'essaie de faire. Ainsi, la question - comment une unité teste-t-elle un code procédural ou événementiel? Fournissez un lien vers une bonne documentation, ou expliquez-le vous-même. D'un autre côté, j'ai aussi du mal à ne pas avoir trouvé de framework de test pour tester les applications xulrunner - il semble que les outils ne soient pas encore développés. J'imagine que c'est plus périphérique que de comprendre les concepts, d'écrire du code testable, d'appliquer des tests unitaires.

Répondre

5

L'idée des tests unitaires est de tester de petites sections de code avec chaque test. Dans un système basé sur un événement, une forme de test unitaire que vous pourriez faire serait de tester comment vos gestionnaires d'événements répondent aux divers événements. Ainsi, votre test unitaire peut définir un aspect de votre programme dans un état spécifique, puis appeler directement la méthode de l'écouteur d'événement et enfin tester l'état ultérieur de votre programme.Si vous envisagez de tester un système basé sur des événements, vous simplifierez la vie si vous utilisez le schéma d'injection de dépendance et que, dans l'idéal, vous utiliseriez l'inversion de contrôle (voir http://martinfowler.com/articles/injection.html et http://msdn.microsoft.com/en-us/library/aa973811.aspx pour plus de détails de ces modèles)

(grâce à pc1oad1etter pour souligner que j'avais foiré les liens)

+0

Vous avez en fait lié deux fois le même article - vouliez-vous dire? – pc1oad1etter

+0

Je pense que ces deux concepts (DI et IoC) me dépassent. Je ne pense pas avoir jamais appris sur les modèles de design à l'école, ni dans aucun de mes emplois. – pc1oad1etter

+3

Je n'ai pas entendu parler de ceux qui sont à l'école non plus. J'ai appris à leur sujet sur le terrain. Ne laissez pas votre arrière-plan vous contraindre. Vous n'obtiendrez pas une bonne compréhension de ces concepts sans donner un coup de feu (à la mise en œuvre.) –

1

Le problème est que la "programmation basée sur les événements" lie beaucoup trop de logique aux événements. La façon dont un tel système devrait être conçu est qu'il devrait y avoir un sous-système qui soulève des événements (et vous pouvez écrire des tests pour s'assurer que ces événements sont levés dans le bon ordre). Et il devrait y avoir un autre sous-système qui ne s'occupe que de gérer, disons, l'état d'un formulaire. Et vous pouvez écrire un test unitaire qui vérifiera que, compte tenu des entrées correctes (c'est-à-dire les événements qui sont levés), l'état du formulaire sera positionné sur les valeurs correctes. Au-delà de cela, le gestionnaire d'événements réel qui est levé à partir du composant 1, et appelle le comportement sur le composant 2 est juste un test d'intégration qui peut être fait manuellement par une personne QA.

2

Au début, je voudrais tester des événements comme celui-ci:

private bool fired; 

private void HandlesEvent(object sender, EventArgs e) 
{ 
    fired = true; 
} 

public void Test() 
{ 
    class.FireEvent += HandlesEvent; 
    class.PErformEventFiringAction(null, null); 

    Assert.IsTrue(fired); 
} 

Et puis j'ai découvert RhinoMocks. RhinoMocks est un framework qui crée des objets fantaisie et gère également les tests d'événements. Il peut également s'avérer utile pour vos tests de procédure.

0

Une approche que j'ai trouvé utile pour le code procédural est d'utiliser TextTest. Ce n'est pas tellement sur les tests unitaires, mais cela vous aide à faire des tests de régression automatisés. L'idée est que vous avez votre application écrire un journal, puis utiliser texttest pour comparer le journal avant et après vos modifications.

0

Voir la Working Effectively with Legacy Code souvent liée. Reportez-vous aux sections intitulées «Ma demande est tous les appels d'API» et «Mon projet n'est pas orienté objet.» Comment effectuer des modifications sécurisées? Dans le monde C/C++ (mon expérience), la meilleure solution dans la pratique est d'utiliser le "joint" linker et de le lier contre des doubles de test pour toutes les fonctions appelées par la fonction testée. De cette façon, vous ne modifiez aucun code existant, mais vous pouvez toujours le tester de manière isolée.

+0

J'ai commandé le livre - j'espère que c'est aussi bon que tout le monde le dit. – pc1oad1etter

2

Répondre à ma propre question ici, mais je suis tombé sur un article qui prend explique le problème, et fait un tour d'un exemple simple - Agile User Interface Development. Le code et les images sont grandes, et voici un extrait qui montre l'idée:

gourous Agile tels que Kent Beck et David Astels suggèrent la construction de l'interface graphique en gardant les objets de vue très mince, et tester la couches "ci-dessous la surface ." Ce modèle «objet intelligent/mince » est analogue aux modèles client-document et , mais applique au développement d'éléments individuels GUI . Séparation du contenu et la présentation améliore la conception du code, rendant plus modulaire et testable. Chaque composant de l'interface utilisateur est implémenté en tant qu'objet intelligent , contenant le comportement de l'application qui doit être testé , mais pas de code de présentation graphique. Chaque objet intelligent a une classe de vue fine correspondante contenant uniquement le comportement de l'interface graphique générique . Avec ce modèle de conception, le bâtiment de GUI devient accessible à TDD.

1

Votre question n'indique pas votre langage de programmation de choix, mais le mien est C# donc je vais illustrer l'utilisation de cela. Ceci est juste un raffinement sur la réponse de Gilligans en utilisant des délégués anonymes pour intégrer votre code de test. Je suis tout à fait en faveur de rendre les tests aussi lisibles que possible, et pour moi cela signifie tout le code de test dans la méthode de test;

// Arrange 
var car = new Car(); 
string changedPropertyName = ""; 
car.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) 
         { 
          if (sender == car) 
            changedPropertyName = e.PropertyName; 
         }; 

// Act 
car.Model = "Volvo"; 

// Assert 
Assert.AreEqual("Model", changedPropertyName, 
    "The notification of a property change was not fired correctly."); 

La classe que je teste ici implémente l'interface INotifyPropertyChanged et donc un événement NotifyPropertyChanged devrait être soulevée à chaque fois que la valeur d'une propriété a changé.

Questions connexes