1 / 111

Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés

Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés. Jonathan “Peli” de Halleux Microsoft Research. Objectifs de cette session A la fin de cette session, je saurai. Ecrire des tests unitaires Utiliser Moles et Stubs pour isoler les tests

galiena
Download Presentation

Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Moles, Stubs et PexTest UnitairesIsolés et Paramétrisés • Jonathan “Peli” de Halleux • Microsoft Research

  2. Objectifs de cette sessionA la fin de cette session, je saurai • Ecrire des tests unitaires • UtiliserMoles et Stubs pour isoler les tests • Ecrire des test unitairesparamétriséavec Pex • Ecrire des tests baséssur des transitions d’états

  3. Test Unitaire

  4. Test Unitaire • A test unitaireest un programmecontenant des assertions qui testeuneunité de code void PushNonEmpty() { var stack = new Stack(); stack.Push(3); Assert.IsFalse(stack.Empty); }

  5. Quiz • Les thèmes des questions du quiz… • Couverture de code • Assertions • Isolation • La définition de tests unitaires

  6. Le Code à Tester string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); foreach(var line in lines){ intindex = line.IndexOf('='); string name = line.Substring(index); if (name == "Foo") { string value = line.Substring(index); return value; } } return null; }

  7. Quiz: Couverture • Combien de couverture de blocs a-t-on besoin? • 50% • 80% • 100% • La couverture de blocs n’est pas suffisante

  8. Quiz: Couverture • Combien de couverture de blocs a-t-on besoin? • 50% • 80% • 100% • La couverture de blocs n’est pas suffisante

  9. Quiz: Couverture • Combien de tests pour 100% de couverture de blocs? • 1 • 2 • 3 • 10 • 1000

  10. Quiz: Couverture • Combien de tests pour 100% de couverture de blocs? • 1 • 2 • 3 • 10 • 1000

  11. Quiz: Couverture [TestMethod] void ExistingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“Foo=b”}); Reader.ReadFooValue();} • Quelautre test pour 100% cov.?

  12. Quiz: Couverture [TestMethod] void ExistingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“Foo=b”}); Reader.ReadFooValue();} • Quelautre test pour 100% cov.? [TestMethod] void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); Reader.ReadFooValue();}

  13. Quiz: Assertions • Pourquoiécrire des Assertions? • Documentation • S’assurerque le code est correct • Faire plaisir au chef • Prévenir de futursfautes • Validater des entrées utilisateur • Capturer les fautestôtdansl’exécution

  14. Quiz: Assertions • Pourquoiécrire des Assertions? • Documentation • S’assurerque le code est correct • Faire plaisir au chef • Prévenir de futursfautes • Validater des entrées utilisateur • Capturer les fautestôtdansl’exécution

  15. Quiz: Assertions if (name == "Foo") { var value = line.Substring(index); Debug.Assert(???); return value; } • Quelssont de bonsexemplesd’assertions? • Debug.Assert(true); • Debug.Assert(value != null); • Debug.Assert(value.Length == line.Length – (index + 1)); • No assertions

  16. Quiz: Assertions if (name == "Foo") { var value = line.Substring(index); Debug.Assert(???); return value; } • Quelssont de bonsexemplesd’assertions? • Debug.Assert(true); • Debug.Assert(value != null); • Debug.Assert(value.Length == line.Length – (index + 1)); • No assertions

  17. Quiz: Assertions • Quelssont de bonsexemplesd’assertions? • Assert.IsTrue(value == “b”); • Assert.IsTrue(value == null); • Assert.IsTrue(String.IsNullOrEmpty(value)) • Assert.IsTrue(false); • No assertions [TestMethod] void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); string value = Reader.ReadFooValue(); Assert.IsTrue(????);}

  18. Quiz: Assertions • Quelssont de bonsexemplesd’assertions? • Assert.IsTrue(value == “b”); • Assert.IsTrue(value == null); • Assert.IsTrue(String.IsNullOrEmpty(value)) • Assert.IsTrue(false); • No assertions [TestMethod] void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); string value = Reader.ReadFooValue(); Assert.IsTrue(????);}

  19. Quiz: Couverture +Assertions • Comment avoirconfiancedans le code? • Haute couverture, peuxd’assertions • Bassecouverture, beaucoup d’assertions • Haute couverture, peuxd’assertions • Bassecouverture, beaucoup d’assertions • “Je l’aiécrit”

  20. Quiz: Couverture +Assertions • Comment avoirconfiancedans le code? • Haute couverture, peuxd’assertions • Bassecouverture, beaucoup d’assertions • Haute couverture, beaucoup d’assertions • Bassecouverture, peuxd’assertions • “Je l’aiécrit”

  21. Quiz: Couverture +Assertions • Considéronsuneexécution de tests automatisée • Comment iplementerune assertion,e.g. Debug.Assert? • { /* ignore */ } • Log(c); • if(!c) MessageBox.Show(“Assert!”); • if(!c) throw new AssertionException(); • Kill process

  22. Quiz: Couverture +Assertions • Considéronsuneexécution de tests automatisée • Comment iplementerune assertion,e.g. Debug.Assert? • { /* ignore */ } • Log(c); • if(!c) MessageBox.Show(“Assert!”); • if(!c) throw new AssertionException(); • Kill process

  23. Quiz: Couverture +Assertions • Considéronsuneexécution de tests automatisée • Comment iplementerune assertion,e.g. Debug.Assert? • { /* ignore */ } • Log(c); • if(!c) MessageBox.Show(“Assert!”); • if(!c) throw new AssertionException(); • Kill process 1 assertion = 1 branch

  24. The Code à Tester string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); foreach(var line in lines){ intindex = line.IndexOf('='); string name = line.Substring(index); if (name == "Foo") { string value = line.Substring(index); return value; } } return null; }

  25. Quiz: Isolation string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); ... } • Quellessont les dépendancesexternes? • Réseau • Disque local • Températureambiante

  26. Quiz: Isolation string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); ... } • Quellessont les dépendancesexternes? • Réseau • Disquedur • Températureambiante

  27. Quiz: Isolation • Quelest le problème du disquedur? • Le Mappingexiste déjà • Les tests ne peuventêtreexécuté en parralèle • Le disqueestplein • Droitd’accès • Pas de problèmes

  28. Quiz: Isolation • Quelest le problème du disquedur? • Le Mappingexiste déjà • Les tests ne peuventêtreexécuté en parralèle • Le disqueestplein • Droitd’accès • Pas de problèmes

  29. Quiz: Isolation • Comment gérer le problème? • Toujoursexécuterdans le même environment • Refactoring: utiliser des Streams • Refactoring: introduireIFileSystem • Refactoring: passer lines comme argument • Change l’implémentation de File.ReadAllLines

  30. Quiz: Isolation Abstractiondevraitêtre la première option • Comment gérer le problème? • Toujoursexécuterdans le même environment • Refactoring: utiliser des Streams • Refactoring: introduireIFileSystem • Refactoring: passer lines comme argument • Change l’implémentation de File.ReadAllLines

  31. Quiz: Isolation • Comment gérer le problème? • Toujoursexécuterdans le même environment • Refactoring: utiliser des Streams • Refactoring: introduireIFileSystem • Refactoring: passer lines comme argument • Change l’implémentation de File.ReadAllLines Dernier ressort

  32. Quiz: Isolation • Comment changer File.ReadAllLines? • Surcharger la procédure • Recompiler le CLR • Instrumentation du code • Demander poliment

  33. Quiz: Isolation • Comment changer File.ReadAllLines? • Surcharger la procédure • Recompiler le CLR • Instrumentation du code • Demander poliment

  34. Quiz: Test Unitaire • Propriétés de test unitaires? • Connection au réseau • Exécutelongtemps • En mémoire • Lit le disquedur • Exécuterapidement • Reproducible • Exécute 10 mèthodes • Exécute 100 mèthodes • Exécute 10000 mèthodes • Requiertune base de données SQL

  35. Quiz: Test Unitaire • Propriétés de test unitaires? • Connection au réseau • Exécutelongtemps • En mémoire • Lit le disquedur • Exécuterapidement • Reproducible • Exécute 10 mèthodes • Exécute 100 mèthodes • Exécute 10000 mèthodes • Requiertune base de données SQL

  36. Quiz: La Définition d’un Test Unitaire • Qu’est-cequ’un Test Unitaire? • Un test unitaireest un programme qui exécute (lentement/rapidement) le code à tester, (avec/sans) dépendences à l’environement, (avec/sans) assertions. • Qu’est-cequ’unebatterie de tests unitaires? • Un ensemble de test unitaires qui atteint un (haut/bas) taux de couverture de code

  37. Quiz: La Définition d’un Test Unitaire • Qu’est-cequ’un Test Unitaire? • Un test unitaireest un programme qui exécuterapidement le code à tester, sansdépendences à l’environement, avec assertions. • Qu’est-cequ’unebatterie de tests unitaires? • Un ensemble de test unitaires qui atteint un hauttaux de couverture de code

  38. Isolation avecMoles

  39. Le casse tête du testeur • Le code à tester ne devrait pas dépendre de l’environement: • Comment changerFile.ReadAllLines? • Surchargeruneméthodestatique • Changer le CLR (et le recompiler) • Ecrirel’application en javascript • Instrumentation de code var lines = File.ReadAllLines(@"t:\myapp.ini");

  40. Le casse tête du testeur • Le code à tester ne devrait pas dépendre de l’environement: • Comment changerFile.ReadAllLines? • Surchargeruneméthodestatique • Changer le CLR (et le recompiler) • Ecrirel’application en javascript • Instrumentation de code var lines = File.ReadAllLines(@"t:\myapp.ini");

  41. Faisons un voeux • Et si on savait changer File.ReadAllLinesfacilementdans un contexte de test? var lines = File.ReadAllLines(@"t:\myapp.ini"); File.ReadAllLines = delegate(string fileName) { return new string[]{“a=b”}; }

  42. Molerdes méthodes • Avec Moles, on peux le faire:redirigertoutes les futures exécutions de ReadAllLinesvers un délégué qui renvoie{“a=b”}: var lines = File.ReadAllLines(@"t:\myapp.ini"); MFile.ReadAllLinesString = delegate(string fileName) { return new string[]{“a=b”}; }

  43. Molerdes méthodes • Avec Moles, on peux le faire:redirigertoutes les futures exécutions de ReadAllLinesvers un délégué qui renvoie{“a=b”}: var lines = File.ReadAllLines(@"t:\myapp.ini"); string[] ReadAllLines(string fileName); MFile.ReadAllLinesString = delegate(string fileName) { return new string[]{“a=b”}; } Func<string,string[]> ReadAllLines{ set; }

  44. Quiz: Func<T> • Associez les délégués et méthodes • Func<string> • Action • Action<string> • Func<bool,string> • Func<string, bool> • Action<int> • Action<List<T>, int> • boolFile.Exists(string) • Console.WriteLine(string) • void Flush() • String.Empty {get;} • List<T>.Capacity {set;}

  45. Quiz: Func<T> • Associez les délégués et méthodes • Func<string> • Action • Action<string> • Func<bool,string> • Func<string, bool> • Action<int> • boolFile.Exists(string) • Console.WriteLine(string) • void Flush() • String.Empty {get;} • List<T>.Capacity {set;}

  46. C# 3.0 Lambdas MFile.ReadAllLinesString = delegate(string fileName) { return new string[]{“a=b”}; }

  47. C# 3.0 Lambdas MFile.ReadAllLinesString = (fileName) => { return new string[]{“a=b”}; }

  48. C# 3.0 Lambdas MFile.ReadAllLinesString = (fileName) => new string[]{“a=b”};

  49. C# 3.0 Lambdas MFile.ReadAllLinesString = fileName => new string[]{“a=b”};

  50. Quiz: Lambdas • Associez les lambdas et méthodes • () => “” • () => {} • s => {} • (s) => “” • (s) => false • boolFile.Exists(string) • Console.WriteLine(string) • void Flush(); • String.Empty {get;} • string ToString();

More Related