Automatiser les tests
d’acceptation :
Comment s’y prendre ?
Vincent Tencé
@testinfected
http://vtence.com
http://github.co...
Terminé ?
Livraison habituelle stress inclus
Livraison souhaitée sourire inclus
Les tests clients sont
essentiels
à une livraison réussie
Test d’acceptation de bout en bout
Persistence
Time
UserInterface
Mail
Payment
Test
Tests instables
• Échouent de façon imprévisible

• Dépendent d’un jeu unique et vivant de données de test

• Dépendent de...
Visez l’atomicité
• Partez d’un état initial connu minimal

• Utilisez le jeu de données minimal suffisant pour le scénario ...
Utilisez vos API
public void registerUser(String email, String password) {

HttpResponse response =
request.content(Form.u...
Waits
WebDriver driver = new FirefoxDriver();
driver.get(“http://some_domain/url_that_delays_login”);
WebDriverWait wait =...
Acceptez l’asynchronisme
BrowserDriver browser = new BrowserDriver(
new UnsynchronizedProber(2000, 50),
new FirefoxDriver(...
Manque d’abstraction
DesiredCapabilities capabilities = DesiredCapabilities.firefox();

WebDriver driver = new FirefoxDriv...
Trop de détails
Scenario: Successful login


Given a user "Bob" with password "secret"

And I am on the login page
# Ces l...
Page Objects
DesiredCapabilities capabilities = DesiredCapabilities.firefox();

WebDriver driver = new FirefoxDriver(capab...
Tests liés aux conditions d’acceptation
Scenario: Successful login


Given the user "Bob" has registered
When he logs in s...
Tests des récits utilisateurs
• Mènent à un trop grand nombre de tests

• Créent une batterie de tests difficile à maintenir...
Testez les parcours utilisateurs
• Testez les interactions complètes d’un utilisateur avec le système 

en vue de l’attein...
Ne cherchez pas à être exhaustif
@Test

public void joinsToGetPremiumFeaturesBySelectingAPayingPlan() {

Join registration...
Pensez comme des utilisateurs
• Rôles : Qui ?

• Objectifs : Pour quoi ?
• Activités et tâches : Quoi ?

• Actions : Comme...
Acteurs
// Plusieurs acteurs vont collaborer
Actors actors = new Actors(config);
// Un acteur initialement anonyme, avec u...
Objectifs
// Les objectifs des utilisateurs s’expriment dans les noms des
// classes de test et des scénarios de test
publ...
Activités et tâches
// Les tâches sont groupées en activités auxquelles
// les acteurs participent
public class Join {

pu...
Actions
// Les acteurs interagissent avec des éléments de l’interface
// utilisateur pour accomplir leurs tâches
public cl...
Évaluations
// Les interactions ont des conséquences que les acteurs
// vont évaluer en posant des questions
public class ...
Au final
@Test

public void joinsToGetPremiumFeaturesBySelectingAPayingPlan() {

Join registration = anonymous.signUp().as(...
En incluant les acteurs externes
@Test

public void joinsAndSelectsAPayingPlan() throws Exception {

Join registration = a...
À vous de jouer !
• Acceptez la nature asynchrone du Web

• Écrivez des tests atomiques

• Testez les parcours utilisateur...
Automatiser les tests d’acceptation : comment s’y prendre ? - Vincent Tencé
Automatiser les tests d’acceptation : comment s’y prendre ? - Vincent Tencé
Automatiser les tests d’acceptation : comment s’y prendre ? - Vincent Tencé
Prochain SlideShare
Chargement dans…5
×

Automatiser les tests d’acceptation : comment s’y prendre ? - Vincent Tencé

141 vues

Publié le

Automatiser les tests d’acceptation : comment s’y prendre?
Si vous rencontrez des défis dans l’automatisation de vos tests d’acceptation ou si vous vous posez des questions sur la meilleure marche à suivre, cette séance est pour vous.
Découvrez comment mettre en place une batterie de tests d’acceptation utile et maintenable en ayant du plaisir à le faire. Attention, code en vue!

À propos de Vincent Tencé
Vincent a la passion du développement logiciel. Il œuvre à construire un monde meilleur dans lequel les logiciels enrichissent et simplifient nos vies. Au cours de sa carrière, il a participé à de nombreux projets de développement logiciel dans une grande variété d’industries, que ce soit en tant que coéquipier, Scrum Master, Product Owner ou coach. Il est un fervent promoteur de l’Agilité depuis ses premières expériences avec Extreme Programming en 2000 et Scrum en 2002. À Pyxis, il occupe son temps à changer le monde soit une ligne de code à la fois soit en enseignant Scrum quelque part sur la planète.

Vincent s’intéresse tout particulièrement au développement piloté par les tests (test-driven development), aux sciences cognitives et aux systèmes décentralisés. Il est un ingénieur diplômé de l’École Nationale de l’Aéronautique et de l’Espace (Toulouse, France). Il est également titulaire d’un MBA du Collège des Ingénieurs (Paris, France).

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
141
Sur SlideShare
0
Issues des intégrations
0
Intégrations
0
Actions
Partages
0
Téléchargements
8
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Automatiser les tests d’acceptation : comment s’y prendre ? - Vincent Tencé

  1. 1. Automatiser les tests d’acceptation : Comment s’y prendre ? Vincent Tencé @testinfected http://vtence.com http://github.com/testinfected
  2. 2. Terminé ?
  3. 3. Livraison habituelle stress inclus
  4. 4. Livraison souhaitée sourire inclus
  5. 5. Les tests clients sont essentiels à une livraison réussie
  6. 6. Test d’acceptation de bout en bout Persistence Time UserInterface Mail Payment Test
  7. 7. Tests instables • Échouent de façon imprévisible • Dépendent d’un jeu unique et vivant de données de test • Dépendent de systèmes externes hors de notre contrôle • Gèrent mal la nature asynchrone du Web
  8. 8. Visez l’atomicité • Partez d’un état initial connu minimal • Utilisez le jeu de données minimal suffisant pour le scénario décrit • Nettoyez avant plutôt qu’après • Remplacez les systèmes externes par des « faux » qui sont programmables et que vous contrôlez
  9. 9. Utilisez vos API public void registerUser(String email, String password) {
 HttpResponse response = request.content(Form.urlEncoded() .addField("email", email)
 .addField("password", password)
 .addField("conditions", "on"))
 .post("/accounts");
 // Pour améliorer le diagnostique du test
 assertThat(response).hasStatusCode(303); }

  10. 10. Waits WebDriver driver = new FirefoxDriver(); driver.get(“http://some_domain/url_that_delays_login”); WebDriverWait wait = new WebDriverWait(driver, 2, 50); WebElement display = wait.until(presenceOfElementLocated( By.id("some-dynamic-element"))); assertThat("display text", display.getText(), equalTo("Loaded")) WebElement button = wait.until(elementToBeClickable( By.id(“some-button"))); button.click();
  11. 11. Acceptez l’asynchronisme BrowserDriver browser = new BrowserDriver( new UnsynchronizedProber(2000, 50), new FirefoxDriver()); browser.navigate().to(“http://somedomain/url_that_delays_loading"); browser.element(By.id(“some-dynamic-element")).hasText("Loaded"); browser.element(By.id(“some-button”)).click(); java.lang.AssertionError: Tried to: check that an element by id "some-button" is enabled but: it was disabled
  12. 12. Manque d’abstraction DesiredCapabilities capabilities = DesiredCapabilities.firefox();
 WebDriver driver = new FirefoxDriver(capabilities);
 
 // Enter username and password
 driver.findElement(By.id("username")).sendKeys("Bob");
 driver.findElement(By.id("password")).sendKeys("secret");
 
 // Click login button
 driver.findElement(By.id("login")).submit();
 
 // Wait for home page to load
 WebDriverWait wait = new WebDriverWait(driver, 5000); wait.until(ExpectedConditions.titleIs("Home")); 
 // Check the greeting message String greeting = driver.findElement(By.id("greeting")).getText();
 assertThat(greeting, equalTo("Welcome, Bob!"));
  13. 13. Trop de détails Scenario: Successful login 
 Given a user "Bob" with password "secret"
 And I am on the login page # Ces lignes là vont toujours ensemble
 And I fill in "Username" with "Bob"
 And I fill in "Password" with "secret" # J’ai vraiment besoin de connaître tous ces détails ?
 When I press "Log In" 
 Then I should see "Welcome, Bob!"
  14. 14. Page Objects DesiredCapabilities capabilities = DesiredCapabilities.firefox();
 WebDriver driver = new FirefoxDriver(capabilities);
 // Euh, vraiment ? LogInPage loginPage = PageFactory.initElements(driver, LogInPage.class);
 
 // Voilà la partie intéressante HomePage page = loginPage.loginAs("Bob", "secret"); // Et si l’affichage est asynchrone ? assertThat(page.greetingMessage(), equalTo("Welcome, Bob!"));
  15. 15. Tests liés aux conditions d’acceptation Scenario: Successful login 
 Given the user "Bob" has registered When he logs in successfully Then he should see "Welcome, Bob!"
  16. 16. Tests des récits utilisateurs • Mènent à un trop grand nombre de tests • Créent une batterie de tests difficile à maintenir • Diminuent la valeurs des tests d’acceptation comme source de documentation fonctionnelle • Ne renseignent pas sur la valeur disponible aux utilisateurs
  17. 17. Testez les parcours utilisateurs • Testez les interactions complètes d’un utilisateur avec le système 
 en vue de l’atteinte d’un objectif donné • Utilisez un petit nombre de tests de parcours utilisateurs seulement 
 pour tester l’intégration de l’ensemble du système
  18. 18. Ne cherchez pas à être exhaustif @Test
 public void joinsToGetPremiumFeaturesBySelectingAPayingPlan() {
 Join registration = anonymous.signUp().as(bob());
 
 User bob = registration.selectPayingPlan("micro")
 .enterBillingDetails("5555555555554444", "12/18", "999"); 
 bob.manageAccount()
 .showsCurrentlyOnPlan("micro")
 .seesCreditCardDetails("**** **** **** 4444", "12/18");
 }

  19. 19. Pensez comme des utilisateurs • Rôles : Qui ? • Objectifs : Pour quoi ? • Activités et tâches : Quoi ? • Actions : Comment ? • Évaluations : Conséquences ?
  20. 20. Acteurs // Plusieurs acteurs vont collaborer Actors actors = new Actors(config); // Un acteur initialement anonyme, avec un rôle de visiteur
 User anonymous = actors.visitor(); // Les systèmes externes aussi sont des acteurs importants
 RemoteApplication api = actors.remoteApplication();

  21. 21. Objectifs // Les objectifs des utilisateurs s’expriment dans les noms des // classes de test et des scénarios de test public class JoiningTheCommunityTest {
 @Test
 public void joinsToLearnMoreBySelectingAFreePlan() { … } @Test
 public void joinsToGetPremiumFeaturesBySelectingAPayingPlan() { … } }
  22. 22. Activités et tâches // Les tâches sont groupées en activités auxquelles // les acteurs participent public class Join {
 public Join signUp() { … }
 
 public Join as(AccountDetails details) { screen.enterEmail(details.email) .enterPassword(details.password) .acceptConditions() .signUp(); } 
 public User chooseFreePlan() { … } 
 
 public Join selectPayingPlan(String name) { … } 
 … }
  23. 23. Actions // Les acteurs interagissent avec des éléments de l’interface // utilisateur pour accomplir leurs tâches public class SignUpScreen { 
 public SignUpScreen enterEmail(String email) {
 browser.element( id("sign-up")).element(id("email")).type(email); return this; }
 public SignUpScreen enterPassword(String password) {
 browser.element( id("sign-up")).element(id("password")).type(password); return this; }
 … }
  24. 24. Évaluations // Les interactions ont des conséquences que les acteurs // vont évaluer en posant des questions public class BillingScreen {
 
 public BillingScreen showsCurrentPlan(String planName) {
 browser.element(By.id("plan")) .hasText(containsStringIgnoringCase(planName));
 return this;
 }
 
 public BillingScreen showsCurrentCardDetails(String description, String validity) {
 browser.element(By.id("payment")) .hasText(containsStringIgnoringCase(description));
 browser.element(By.id("payment")) .hasText(containsStringIgnoringCase(validity));
 return this;
 }
 }
  25. 25. Au final @Test
 public void joinsToGetPremiumFeaturesBySelectingAPayingPlan() {
 Join registration = anonymous.signUp().as(bob());
 
 User bob = registration.selectPayingPlan("micro")
 .enterBillingDetails("5555555555554444", "12/18", "999"); 
 bob.manageAccount()
 .showsCurrentlyOnPlan("micro")
 .seesCreditCardDetails("**** **** **** 4444", "12/18");
 }

  26. 26. En incluant les acteurs externes @Test
 public void joinsAndSelectsAPayingPlan() throws Exception {
 Join registration = anonymous.signUp().as(bob()); paymentGateway.hasCreatedCustomerAccount(bob().email), "free");
 mailServer.hasSentWelcomeEmailTo(bob().email); 
 User bob = registration.selectPayingPlan("micro")
 .enterBillingDetails("5555555555554444", "12/18", "999"); paymentGateway.hasCreatedCreditCard(bob().email, "5555555555554444", "12/18","999")
 .hasUpgradedCustomerPlan(bob().email, "micro"); 
 bob.manageAccount()
 .showsCurrentlyOnPlan("micro")
 .seesCreditCardDetails("**** **** **** 4444", "12/18");
 }

  27. 27. À vous de jouer ! • Acceptez la nature asynchrone du Web • Écrivez des tests atomiques • Testez les parcours utilisateurs • Pensez comme des utilisateurs

×