1. Unit Testing & TDD
Jean-Baptiste Vigneron
j.vigneron@epsi.fr
@jbvigneron
David Bottiau
david.bottiau@epsi.fr
@dbottiau
2. • Vérifier un processus
• Eviter les imprévus
• Ne pas « régresser »
• Passer plus de temps à
développer qu'à supprimer les
bugs
Les tests unitaires ?
Pourquoi faire ?
3. • 1 livrable = 1 blocs de tests
• A chaque livrable, vérification des
nouveaux et des anciens tests
• Si > 1 test échoue
=> régression probable
=> livrable invalide
La non-régression
4. La méthode AAA
1. Arrange
• Création des objets
2. Act
• Exécution des méthodes
• Obtention des valeurs
3. Assert
• Vérification des données
[TestClass]
public class GameTest
{
[TestMethod]
public void Can_Instantiate_Soldiers()
{
// arrange – create objects
var soldier = new Soldier();
// act – execute actions (methods)
// assert – verify values
Assert.AreEqual(soldier.Health, 100);
Assert.AreEqual(soldier.Attack, 10);
Assert.AreEqual(soldier.Defense, 7);
Assert.AreEqual(soldier.IsDead, false);
}
}
5. Les attributs
Attribut Utilité
[TestClass] Précise que la classe est une classe de tests : repérable par l’outil
Test Runner
[TestMethod] Précise que la méthode est un test de la classe de tests :
repérable par l’outil Test Runner
[ExpectedException] Evite l’échec d’un test en sachant quel type d’exception pourrait
être lancée lors de l’exécution du test
[ClassInitialize] Permet d’initialiser les propriétés de la classe de test
[ClassCleanup] Permet de « nettoyer » la classe à la fin des tests
[TestInitialize] Permet de réinitialiser les propriétés de la classe à chaque test
[TestCleanup] Permet de « nettoyer » la classe à chaque fin de test
7. TDD - Fail
Test
[TestClass]
public class MathsTest
{
[TestMethod]
public void Can_Add()
{
// act
int x = Maths.Add(4, 9);
// assert
Assert.AreEqual(x, 13);
}
}
Code
public static class Maths
{
public static int Add(int x, int y)
{
throw new NotImplementedException();
}
}
8. TDD - Pass
Test
[TestClass]
public class MathsTest
{
[TestMethod]
public void Can_Add()
{
// act
int x = Maths.Add(4, 9);
// assert
Assert.AreEqual(x, 13);
}
}
Code
public static class Maths
{
public static int Add(int x, int y)
{
return 13;
}
}
9. TDD - Refactor
Test
[TestClass]
public class MathsTest
{
[TestMethod]
public void Can_Add()
{
// act
int x = Maths.Add(4, 9);
// assert
Assert.AreEqual(x, 13);
}
[TestMethod]
public void Can_Add_Two_RandomNumbers()
{
// arrange
Random random = new Random();
int a = random.Next(100), b = random.Next(100);
// act
int x = Maths.Add(a, b);
// assert
Assert.AreEqual(x, a + b);
}
}
Code
public static class Maths
{
public static int Add(int x, int y)
{
// TODO : Refactor this
return 13;
}
}
10. TDD & Pair programming
Pilot / Driver
• Développe les fonctionnalités
en fonction du test à réussir
• Exécute le test de réussite
tant qu’il échoue
• Pose des conditions de
refactoring (futurs tests)
Copilot / Partner
• Développe les tests
• Exécute le test d’échec
• Exécute le test de réussite
final
11. Automatisation des tests
L’intégration continue
• Déploiement automatique grâce à
• Visual Studio Online
• Azure
• Automatisation des tests
• à chaque Build (déploiement)
• à chaque commit / push (TFS / Git)
12. Not only Unit Test
• Tests de l’interface (UI)
• Tester l’interface et les actions potentielles
• Tests d'intégration
• A l’inverse des tests unitaires, on teste l’interaction entre les
fonctionnalités
• Tests de charge
• Tester les performances et la résistance de l’application
13. En résumé…
Test - Code - Test - ...
• Maximiser votre couverture de code
• Au plus votre code est testé, au plus votre code est fonctionnel
• Utiliser TDD
• Soyez sûr de votre code avant même qu'il ne soit écrit
• Eviter les imprévus
• Automatiser les tests
• Soyez sûr que le livrable est fonctionnel à tout moment
• Produit livré sans effort avec l’intégration continue