Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft...

111
Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan “Peli” de Halleux Microsoft Research

Transcript of Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft...

Page 1: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Moles, Stubs et PexTest Unitaires Isolés et Paramétrisés

Jonathan “Peli” de HalleuxMicrosoft Research

Page 2: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Objectifs de cette sessionA la fin de cette session, je saurai

Ecrire des tests unitaires

Utiliser Moles et Stubs pour isoler les tests

Ecrire des test unitaires paramétrisé avec Pex

Ecrire des tests basés sur des transitions d’états

Page 3: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Test Unitaire

Page 4: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

A test unitaire est un programme contenant des assertions qui teste une unité de code

Test Unitaire

void PushNonEmpty() { var stack = new Stack(); stack.Push(3); Assert.IsFalse(stack.Empty);}

Page 5: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz Les thèmes des questions du quiz…

Couverture de code Assertions Isolation La définition de tests unitaires

Page 6: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Le Code à Tester

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

Page 7: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Combien de couverture de blocs a-t-on besoin?1. 50%2. 80%3. 100%4. La couverture de blocs n’est pas

suffisante

Page 8: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Combien de couverture de blocs a-t-on besoin?1. 50%2. 80%3. 100%4. La couverture de blocs n’est pas

suffisante

Page 9: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Combien de tests pour 100% de couverture de blocs?1. 12. 23. 34. 105. 1000

Page 10: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Combien de tests pour 100% de couverture de blocs?1. 12. 2 3. 34. 105. 1000

Page 11: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Quel autre test pour 100% cov.?

[TestMethod]void ExistingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“Foo=b”}); Reader.ReadFooValue();}

Page 12: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture

Quel autre test pour 100% cov.?

[TestMethod]void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); Reader.ReadFooValue();}

[TestMethod]void ExistingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“Foo=b”}); Reader.ReadFooValue();}

Page 13: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Pourquoi écrire des Assertions?1. Documentation2. S’assurer que le code est correct3. Faire plaisir au chef4. Prévenir de futurs fautes5. Validater des entrées utilisateur6. Capturer les fautes tôt dans l’exécution

Page 14: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Pourquoi écrire des Assertions?1. Documentation2. S’assurer que le code est correct3. Faire plaisir au chef4. Prévenir de futurs fautes5. Validater des entrées utilisateur6. Capturer les fautes tôt dans

l’exécution

Page 15: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Quels sont de bons exemples d’assertions?1. Debug.Assert(true);2. Debug.Assert(value != null);3. Debug.Assert(value.Length == line.Length –

(index + 1));4. No assertions

if (name == "Foo") { var value = line.Substring(index); Debug.Assert(???); return value;}

Page 16: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Quels sont de bons exemples d’assertions?1. Debug.Assert(true);2. Debug.Assert(value != null);3. Debug.Assert(value.Length == line.Length

– (index + 1));4. No assertions

if (name == "Foo") { var value = line.Substring(index); Debug.Assert(???); return value;}

Page 17: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Quels sont de bons exemples d’assertions?1. Assert.IsTrue(value == “b”);2. Assert.IsTrue(value == null);3. Assert.IsTrue(String.IsNullOrEmpty(value))4. Assert.IsTrue(false);5. No assertions

[TestMethod]void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); string value = Reader.ReadFooValue(); Assert.IsTrue(????);}

Page 18: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Assertions

Quels sont de bons exemples d’assertions?1. Assert.IsTrue(value == “b”);2. Assert.IsTrue(value == null);3. Assert.IsTrue(String.IsNullOrEmpty(value))4. Assert.IsTrue(false);5. No assertions

[TestMethod]void MissingFoo() { File.WriteAllLines(@"t:\myapp.ini",new string[]{“a=b”}); string value = Reader.ReadFooValue(); Assert.IsTrue(????);}

Page 19: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture + Assertions

Comment avoir confiance dans le code?1. Haute couverture, peux d’assertions2. Basse couverture, beaucoup

d’assertions3. Haute couverture, peux d’assertions4. Basse couverture, beaucoup

d’assertions5. “Je l’ai écrit”

Page 20: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture + Assertions

Comment avoir confiance dans le code?1. Haute couverture, peux d’assertions2. Basse couverture, beaucoup

d’assertions3. Haute couverture, beaucoup

d’assertions4. Basse couverture, peux d’assertions5. “Je l’ai écrit”

Page 21: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture + Assertions

Considérons une exécution de tests automatisée

Comment iplementer une assertion,e.g. Debug.Assert?1. { /* ignore */ }2. Log(c);3. if(!c) MessageBox.Show(“Assert!”);4. if(!c) throw new AssertionException();5. Kill process

Page 22: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture + Assertions

Considérons une exécution de tests automatisée

Comment iplementer une assertion,e.g. Debug.Assert?1. { /* ignore */ }2. Log(c);3. if(!c) MessageBox.Show(“Assert!”);4. if(!c) throw new AssertionException();5. Kill process

Page 23: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Couverture + Assertions

Considérons une exécution de tests automatisée

Comment iplementer une assertion,e.g. Debug.Assert?1. { /* ignore */ }2. Log(c);3. if(!c) MessageBox.Show(“Assert!”);4. if(!c) throw new AssertionException();5. Kill process1 assertion =

1 branch

Page 24: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

The Code à Tester

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

Page 25: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Quelles sont les dépendances externes?1. Réseau2. Disque local3. Température ambiante

string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); ...}

Page 26: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Quelles sont les dépendances externes?1. Réseau2. Disque dur3. Température ambiante

string ReadFooValue() { string[] lines = File.ReadAllLines(@"t:\myapp.ini"); ...}

Page 27: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Quel est le problème du disque dur?1. Le Mapping existe déjà2. Les tests ne peuvent être exécuté en

parralèle3. Le disque est plein4. Droit d’accès5. Pas de problèmes

Page 28: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Quel est le problème du disque dur?1. Le Mapping existe déjà2. Les tests ne peuvent être exécuté

en parralèle3. Le disque est plein4. Droit d’accès5. Pas de problèmes

Page 29: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Comment gérer le problème?1. Toujours exécuter dans le même

environment2. Refactoring: utiliser des Streams3. Refactoring: introduire IFileSystem4. Refactoring: passer lines comme

argument5. Change l’implémentation de

File.ReadAllLines

Page 30: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Comment gérer le problème?1. Toujours exécuter dans le même

environment2. Refactoring: utiliser des Streams3. Refactoring: introduire IFileSystem4. Refactoring: passer lines comme

argument5. Change l’implémentation de

File.ReadAllLines

Abstraction devrait être la

première option

Page 31: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Comment gérer le problème?1. Toujours exécuter dans le même

environment2. Refactoring: utiliser des Streams3. Refactoring: introduire IFileSystem4. Refactoring: passer lines comme

argument5. Change l’implémentation de

File.ReadAllLines

Dernier ressort

Page 32: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Comment changer File.ReadAllLines?1. Surcharger la procédure2. Recompiler le CLR3. Instrumentation du code4. Demander poliment

Page 33: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Isolation

Comment changer File.ReadAllLines?1. Surcharger la procédure2. Recompiler le CLR3. Instrumentation du code4. Demander poliment

Page 34: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Test Unitaire

Propriétés de test unitaires?1. Connection au réseau2. Exécute longtemps3. En mémoire4. Lit le disque dur5. Exécute rapidement6. Reproducible7. Exécute 10 mèthodes8. Exécute 100 mèthodes9. Exécute 10000 mèthodes10.Requiert une base de données SQL

Page 35: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Test Unitaire

Propriétés de test unitaires?1. Connection au réseau2. Exécute longtemps3. En mémoire4. Lit le disque dur5. Exécute rapidement6. Reproducible7. Exécute 10 mèthodes8. Exécute 100 mèthodes9. Exécute 10000 mèthodes10.Requiert une base de données SQL

Page 36: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: La Définition d’un Test Unitaire

Qu’est-ce qu’un Test Unitaire?

Un test unitaire est un programme qui exécute (lentement/rapidement) le code à tester, (avec/sans) dépendences à l’environement, (avec/sans) assertions.

Qu’est-ce qu’une batterie de tests unitaires?

Un ensemble de test unitaires qui atteint un (haut/bas) taux de couverture de code

Page 37: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: La Définition d’un Test Unitaire

Qu’est-ce qu’un Test Unitaire?

Un test unitaire est un programme qui exécute rapidement le code à tester, sans dépendences à l’environement, avec assertions.

Qu’est-ce qu’une batterie de tests unitaires?

Un ensemble de test unitaires qui atteint un haut taux de couverture de code

Page 38: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Isolation avec Moles

Page 39: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Le code à tester ne devrait pas dépendre de l’environement:

Comment changer File.ReadAllLines?1. Surcharger une méthode statique2. Changer le CLR (et le recompiler)3. Ecrire l’application en javascript4. Instrumentation de code

Le casse tête du testeur

var lines = File.ReadAllLines(@"t:\myapp.ini");

Page 40: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Le code à tester ne devrait pas dépendre de l’environement:

Comment changer File.ReadAllLines?1. Surcharger une méthode statique2. Changer le CLR (et le recompiler)3. Ecrire l’application en javascript4. Instrumentation de code

Le casse tête du testeur

var lines = File.ReadAllLines(@"t:\myapp.ini");

Page 41: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Et si on savait changer File.ReadAllLines facilement dans un contexte de test?

Faisons un voeux

File.ReadAllLines = delegate(string fileName) { return new string[]{“a=b”}; }

var lines = File.ReadAllLines(@"t:\myapp.ini");

Page 42: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Avec Moles, on peux le faire:rediriger toutes les futures exécutions de ReadAllLines vers un délégué qui renvoie {“a=b”}:

Moler des méthodes

var lines = File.ReadAllLines(@"t:\myapp.ini");

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

Page 43: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Avec Moles, on peux le faire:rediriger toutes les futures exécutions de ReadAllLines vers un délégué qui renvoie {“a=b”}:

Moler des méthodes

var lines = File.ReadAllLines(@"t:\myapp.ini");

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

string[] ReadAllLines(string fileName);

Func<string,string[]> ReadAllLines { set; }

Page 44: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Func<T>

Associez les délégués et méthodes

1. Func<string>2. Action3. Action<string>4. Func<bool,string>5. Func<string, bool>6. Action<int>7. Action<List<T>, int>

a) bool File.Exists(string)b) Console.WriteLine(string)c) void Flush()d) String.Empty {get;}e) List<T>.Capacity {set;}

Page 45: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Func<T>

Associez les délégués et méthodes

1. Func<string>2. Action3. Action<string>4. Func<bool,string>5. Func<string, bool>6. Action<int>

a) bool File.Exists(string)b) Console.WriteLine(string)c) void Flush()d) String.Empty {get;}e) List<T>.Capacity {set;}

Page 46: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

C# 3.0 Lambdas

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

Page 47: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

C# 3.0 Lambdas

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

Page 48: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

C# 3.0 Lambdas

MFile.ReadAllLinesString = (fileName) => new string[]{“a=b”};

Page 49: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

C# 3.0 Lambdas

MFile.ReadAllLinesString = fileName => new string[]{“a=b”};

Page 50: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Lambdas

Associez les lambdas et méthodes

1. () => “”2. () => {}3. s => {}4. (s) => “”5. (s) => false

a) bool File.Exists(string)b) Console.WriteLine(string)c) void Flush();d) String.Empty {get;}e) string ToString();

Page 51: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Lambdas

Associez les lambdas et méthodes

1. () => “”2. () => {}3. s => {}4. (s) => “”5. (s) => false

a) bool File.Exists(string)b) Console.WriteLine(string)c) void Flush();d) String.Empty {get;}e) string ToString();

Page 52: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Pour chaque classe une classe mole Une propriété par méthode Conventions de noms

Structure d’un Mole

class File { static string[] FileReadAllLines(string f);}class MFile { Func<string, string[]> FileReadAllLinesString { set; }}

Page 53: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Moles

Convention de noms: ‘M’ + nom de classe Nom de méthode + noms des classes des

paramètres Accesseur de propriétés: Get

Quel est le mole de bool File.Exists(string)?

1. SFile.ExistsString2. MFile.Exists3. MFile.ExistsStringBool4. MFile.ExistsString

Page 54: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Moles

Convention de noms: ‘M’ + nom de classe Nom de méthode + noms des classes des

paramètres Accesseur de propriétés: Get

Quel est le mole de bool File.Exists(string)?

1. SFile.ExistsString2. MFile.Exists3. MFile.ExistsStringBool4. MFile.ExistsString

Page 55: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Injection de détours dans le corps des méthodes avec un profiler

DétoursCourt circuit de méthodes

Page 56: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Injection de détours dans le corps des méthodes avec un profiler

DétoursCourt circuit de méthodes

struct DateTime { static DateTime Now {

return InternalNow(); }}

Page 57: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Injection de détours dans le corps des méthodes avec un profiler

DétoursCourt circuit de méthodes

struct DateTime { static DateTime Now {

return InternalNow(); }}

Func<DateTime> f = GetDetour(...); if(f != null) return f();

Page 58: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Demo

Page 59: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

“Remplacer quelconque méthode .NET avec un délégué”

L’instrumentation requiert une configuration spéciale:

[HostType(“Moles”)] avec MSTest

MFile.ReadAllLinesString = (f) => new string[0];

Molesen action

Page 60: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Jusqu’ici on a appris

La définition de tests unitaires

L’isolation de tests unitaires avec Moles

1. Identifier les dépendences externes2. Replacer chaque API externe avec un

délégué

Page 61: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Pause10 Minutes

Page 62: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Isolation avec Stubs

Page 63: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

The Code à Tester

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

Page 64: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Dependency Injection

string ReadFooValue(IFileSystem fs) { string[] lines = fs.ReadAllLines(@"t:\myapp.ini"); ...}

interface IFileSystem { string[] ReadAllLines(string fileName);}

Page 65: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Structure d’un Stub

interface IFileSystem { string[] ReadAllLines(string fileName);}

class SIFileSystem : IFileSystem, IStub { public Func<string,string[]> ReadAllLinesString; string[] IFileSystem.ReadAllLines(string name){ return this.ReadAllLinesString(name); } }

Page 66: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Stub en action

class SIFileSystem : IFileSystem, IStub { public Func<string,string[]> ReadAllLinesString; string[] IFileSystem.ReadAllLines(string name){ return this.ReadAllLinesString(name); } }var lines = { “foo=a”, “b=c”};var fs = new SIFileSystem { ReadAllLinesString = f => lines};

ReadFooValue(fs);

Page 67: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Jusqu’ici on a appris

La définition de tests unitaires

L’isolation de tests unitaires avec Moles

L’isolation de tests unitaires avec Stubs

Page 68: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Stubs vs Moles

Moles pour le code des autres “pas le choix”

Stubs pour votre code Refactoring + interfaces + Stubs

Page 69: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Test UnitaireParamétrisé

Page 70: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

The recette d’un Test Unitaire

var stack = new Stack(); stack.Push(item);

Assert.IsTrue(stack.IsEmpty);}

3 ingrédients étentiels: Données Séquence de méthodes Assertionsvoid PushIsNotEmpty() { int item = 3;

Page 71: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: stack.Push (???)

Quelle donnée utiliser?1. 02. 13. int.MaxValue, int.MinValue4. -15. 10006. Peu importe7. Il faux d’abord lire le code

stack.Push(???);

Page 72: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: stack.Push (???)

Quelle donnée utiliser?1. 02. 13. int.MaxValue, int.MinValue4. -15. 10006. Peu importe7. Il faux d’abord lire le code

stack.Push(???);

Page 73: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Test Unitaire Paramétrisé = Test Unitaire avec Parametres

Separation de concepts Spécification Données pour avoir de la couverture de

code

Test Unitaire Paramétrisévoid PushIsNotEmpty(Stack stack, int item) { stack.Push(item); Assert.IsFalse(stack.IsEmpty);}

Page 74: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Test Unitaire Paramétrisé = Test Unitaire avec Parametres

Separation de concepts Spécification Données pour avoir de la couverture de

code

Test Unitaire Paramétrisévoid PushIsNotEmpty(Stack stack, int item) { stack.Push(item); Assert.IsFalse(stack.IsEmpty);}

pour tout stack,

pour tout item,

… ajouter un element et le stack

n’est pas vide

Page 75: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Génération de donnéesavec l’exécution dynamique symbolique

Page 76: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

76

Goal: Soit un programme paramétrisé, générer automaticement un ensemble de données qui, à l’exécution, vont atteindre un maximum de chemins d’exécution

Quelle technique pourrait-on utiliser?

Le challenge de la génération de données

Page 77: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Constraints to solve

a!=null a!=null &&a.Length>0

a!=null &&a.Length>0 &&a[0]==1234567890

void CoverMe(int[] a){ if (a == null) return; if (a.Length > 0) if (a[0] == 1234567890) throw new Exception("bug");}

Observed constraints

a==nulla!=null &&!(a.Length>0)a!=null &&a.Length>0 &&a[0]!=1234567890

a!=null &&a.Length>0 &&a[0]==1234567890

Data

null

{}

{0}

{123…}a==null

a.Length>0

a[0]==123…T

TF

T

F

F

Exécuter&ObserverRésoudreChoiser le prochain chemin

Done: There is no path left.

Exécution dynamique symboliqueExample

Page 78: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Constraints to solve

Observed constraints

Data

T

TF

T

F

F

Execute&MonitorSolve

Choose next path

Exécution dynamique symboliqueExample

Quels tests Pex générera-t-il?

void CoverMe2( int[] a, int index) { if (a[index] == 1 + a[index + 1]) throw new Exception("bug");}

Page 79: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Quiz: Exécution dynamique symbolique

Quels tests Pex générera-t-il?

1. (null, 0), ({0,1}, 0)2. (null, 0), ({0,1}, 0), ({0,1}, 1)3. ({}, 1), ({0,0,0,0}, 3)4. (null, 0), ({}, 0), ({0}, 0), ({0},

1), ({1}, 0), ({0,0},0), ({0,1}, 0)

void CoverMe2(int[] a, int index) { if (a[index] == 1 + a[index + 1]) throw new Exception("bug");}

Page 80: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Demo

Page 81: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Jusqu’ici on a appris

La définition de tests unitaires

L’isolation de tests unitaires avec Moles

L’isolation de tests unitaires avec Stubs

Test unitaires paramétrisés avec Pex

Page 82: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Behaved TypesTests à base de transition d’état

Page 83: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Behaved file system

interface IFileSystem { string[] ReadAllLines(string fileName);}

class BIFileSystem : SIFileSystem { BehavedDictionary<string, string[]> files; public BIFileSystem() { this.files = new BehavedDictionary<string, string[]>(this,”Files”); this.ReadAllLinesString = fn => { string[] lines; if (!this.files.TryGetValue(fn, out lines)) throw new FileNotFoundException(fn); return (string[])lines.Clone(); }; }}

Page 84: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Behaved file system

interface IFileSystem { string[] ReadAllLines(string fileName);}

On approxime le systême de fichiers par un dictionnaire

Page 85: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Behaved file system

interface IFileSystem { string[] ReadAllLines(string fileName);}

class BIFileSystem : SIFileSystem { BehavedDictionary<string, string[]> files; public BIFileSystem() { this.files = new BehavedDictionary<string, string[]>(this,”Files”); this.ReadAllLinesString = fn => { string[] lines; if (!this.files.TryGetValue(fn, out lines)) throw new FileNotFoundException(fn); return (string[])lines.Clone(); }; }}

Undefined state

Page 86: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Démo

Page 87: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

What you learned so far

The Definition of Test Unitaire

Unit Test Isolation through Moles

Unit Tests Isolation through Stubs

Stated-based Unit Tests with Behaved Types

Page 88: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Break2 Minutes

Page 89: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Jusqu’ici on a appris

La définition de tests unitaires

L’isolation de tests unitaires avec Moles

L’isolation de tests unitaires avec Stubs

Test unitaires paramétrisés avec Pex

Test à base de transition d’état avec Behaved Types

Page 90: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Patterns

Page 91: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternNormalized Roundtrip

For an API f(x), f-1(f(f-1(x)) = f-1(x) for all x

void ParseToString(string x) { var normalized = int.Parse(x); var intermediate = normalized.ToString(); var roundtripped = int.Parse(intermediate);

// assert quiz1. Assert(x == intermediate);2. Assert(intermediate == roundtripped);3. Assert(normalized == roundtripped);4. Assert(x == roundtripped); }

Page 92: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternState Relation

Observe a state change

void ContainedAfterAdd(string value) { var list = new List<string>(); list.Add(value);

// assert quiz1. Assert(value != null);2. Assert(list.Contains(value));3. Assert(list.IndexOf(value) < 0);4. Assert(list[0] == value);}

Page 93: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternSame Observable Behavior

Given two methods f(x) and g(x), and a method b(y) that observes the result or the exception behavior of a method, assert that f(x) and g(x) have same observable behavior under b, i.e. b(f(x)) = b(g(x)) for all x.

public void ConcatsBehaveTheSame( string left, string right) { PexAssert.AreBehaviorsEqual( () => StringFormatter.ConcatV1(left, right), () => StringFormatter.ConcatV2(left, right));}

Page 94: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternAllowed Exception

Allowed exception -> negative test case

[PexAllowedException(typeof(ArgumentException))]void Test(object item) { var foo = new Foo(item) // validates item// generated test (C#)[ExpectedException(typeof(ArgumentException))]void Test01() { Test(null); // argument check}

Page 95: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternReachability

Indicate which portions of a PUT should be reachable.

[PexAssertReachEventually]public void Constructor(object input){ new Foo(input); PexAssert.ReachEventually(); }

Page 96: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

PatternRegression Tests

Generated test asserts any observed value Return value, out parameters, PexGoal

When code evolves, breaking changes in observable will be discovered

int AddTest(int a, int b) { return a + b; }

void AddTest01() { var result = AddTest(0, 0); Assert.AreEqual(0, result);}

Page 97: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

More Patterns

Read patterns paper:patterns.pdf

http://research.microsoft.com/Pex/patterns.pdf

Page 98: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Limitationsand other Details

Page 99: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

The yellow event bar notifies about important events, including certain limitations

Event Bar

Click on issue kind for more information

Page 100: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Events View

You should act on these events: Refactor your code, or tell Pex to ignore it in the future, let Pex analyze (“instrument”) more code,

if possible.

Page 101: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Instrumenting more code If Pex reports that some code was

uninstrumented, you may tell Pex to instrument and analyze it(if possible)

Page 102: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Instrumenting more code

Code instrumentation on Demand Instrumentation has high performance

overhead Some parts of the code better ignored

Use PexInstrument… attributes

Pex will often suggest and insert those attributes for you

[assembly: PexInstrumentAssembly(“Foo”)]

Page 103: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Pex understand managed .NET code only Pex does not understand native code.

Problem if branching over values obtained from the environment Pex may not automatically detect all such

cases.

Testability

if (!File.Exists(f)) throw ...

File System?

Page 104: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Hidden Complexity

Pex analyzes every executed .NET instruction

Some used libraries may be surprisingly expensive to analyze XML parsing repeatedly converting data between different

representationsvoid Sum(string[] A) { var sum = “0”; foreach(var a in A) sum = (int.Parse(a) + int.Parse(sum)).ToString(); if(sum == “123”) throw new Exception(); }

Don’t do this.

Page 105: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Exploration Boundaries

Configurable bounds include: TimeOut MaxBranches MaxCalls MaxConditions▪ Number of conditions that depend on test

inputs MaxRuns ConstraintSolverTimeOut ConstraintSolverMemoryLimit

Page 106: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Multi-threaded code

Unlike test inputs, thread-interleavings can normally not be controlled

Thus, Pex can only explore single-threaded code

Related approach to explore thread-schedules (but not input parameters) by controlling thread-scheduler: CHESShttp://research.microsoft.com/CHESS

Page 107: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Lack of Test Oracle

Write assertions and Pex will try to break them

Without assertions, Pex can only find violations of runtime contracts causing NullReferenceException, IndexOutOfRangeException, etc.

Assertions leveraged in product and test code

Pex can leverage Code Contracts (discussed later)

Page 108: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Exercise Limitations

Goal: Understand limitations.

Apply Pex to

if (File.Exists(fileName)) throw new Exception(“found it”);

if (DateTime.Parse(s).Year == 2009) throw new Exception(“found it”);

Page 109: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Wrapping up

Page 110: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

What you learned so far

The Definition of Test Unitaire

Unit Test Isolation through Moles

Unit Tests Isolation through Stubs

Stated-based Unit Tests with Behaved Types

Write Pex parameterized unit tests

Page 111: Moles, Stubs et Pex Test Unitaires Isolés et Paramétrisés Jonathan Peli de Halleux Microsoft Research.

Thank you

http://research.microsoft.com/pex