Des tests modernes pour Drupal

1 307 vues

Publié le

Présentation effectuée au DrupalCamp Montréal 2014 sur "des tests modernes pour Drupal"

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

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

Aucune remarque pour cette diapositive

Des tests modernes pour Drupal

  1. 1. Des tests 'MODERNES' pour Drupal Christophe Villeneuve @hellosct1
  2. 2. Qui... est Christophe Villeneuve ? << afup – lemug.fr – mysql – mariadb – drupal – demoscene – firefoxos – drupagora – phptour – forumphp – solutionlinux – demoinparis – ici et maintenant – eyrolles – editions eni – programmez – linux pratique – webriver – phptv – neuros - elephpant
  3. 3. Support présentation aujourd'hui Disponible sur http://www.eyrolles.fr Drupal avancé – un CMS pour développeurs par Christophe Villeneuve et Vanessa Kovalsky David aux Editions EYROLLES
  4. 4. Expérience sur... Les tests Citations ✔ « Des fois cela plante » ✔ « On a testé, … il y a 3 mois lors de la dernière livraison... Pas eu le temps... »
  5. 5. L'importance des tests Pourquoi c'est utile ? Et L'intérêt... ✔ Le code peut casser ✔ Changer le nom d'un fichier ✔ Pas le temps d'en faire ✔ C'est long manuellement ✔ Coûte du temps au début ✔ En fait gain après ✔ Nécessite de la rigueur et de la constante
  6. 6. Les différents types de tests Tests Unitaires ● Module / classe / méthode Tests fonctionnels ● l'interface utilisateur testée par le client Tests intégrations ● Tester la navigation, et l'interface utilisateur Tests Automatisés Tests de charges Tests d'ergonomie Tests de sécurité
  7. 7. Tests unitaires... En pratique
  8. 8. Tests unitaires Déroulement Quoi tester ? ✔ Existe-t-il ? ✔ Ecrire un test qui échoue ✔ Ecrire un test qui est bon ✔ Un test de sécurité ✔ Un test de contrôle ✔ Un module ✔ Une classe ✔ Une méthode ✔ Tester ✔ Ce qui est important ✔ Le risque de casser ✔ Les parties que vous touchez souvent
  9. 9. Tests unitaires : Les API ✔ jUnit ✔ SimpleTest ✔ Zend_test ✔ PHPUnit ✔ Atoum Roadmap ✔ ... D7 D8 D9 SimpleTest PHPUnit
  10. 10. Cas pratique avec PHPUnit
  11. 11. Installation En ligne de commandes # sudo apt-get install phpunit # pear channel-discover pear.phpunit.de # pear channel-discover components.ez.no # pear channel-discover pear.symfony-project.com En mode assistée Avec IDE - Windows - Eclipse PDT - Linux - Netbeans - Mac
  12. 12. Tests unitaires : cas 1 Du code... +ieurs commentaires <?php class calculs { public function add($a, $b) { return $a + $b; } } ?> <?php class calculs { /** * @assert (0, 0) == 0 * @assert (0, 1) == 1 * @assert (1, 0) == 1 * @assert (1, 1) == 2 * @assert (1, 2) == 3 */ public function add($a, $b) { return $a + $b; } } ?>
  13. 13. Tests unitaires : cas 1 1 commentaire Passer au test <?php class calculs { /** * @assert (1, 1) == 2 */ public function add($a, $b) { return $a + $b; } } ?> <?php /** * Generated from @assert (1, 1) == 2 */ public function testAdd() { $this->assertEquals( 2, $this->object->add(1, 1) ); } ?>
  14. 14. Fonctionnement PHPUnit avec Drupal ✔ Boostrap ✔ Script d'amorcage ✔ Construction autonome ✔ Etendre le Boostrap ✔ Emplacement du fichier ✔ Déclarer les SLASHs ✔ Recherche de racine Drupal ✔ Chargeons boostrap.inc ✔ Execution
  15. 15. PHPUnit avec Drupal : Comprendre <?php define('DRUPAL_ROOT', realpath(dirname(__FILE__) ) . DS ); set_include_path(DRUPAL_ROOT . get_include_path()); include_once DRUPAL_ROOT . 'includes' . DS . 'bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); class base_test extends PHPUnit_Framework_TestCase { public function test_one_more_one_is_two() { $this->assertEquals(1+1,2); } } ?>
  16. 16. Résultat . Le test est réussi F l'assertion a échoué E Erreur Exécution S Problème inconnu I Test incomplet
  17. 17. Module & PHPUnit & Drupal
  18. 18. Module & PHPUnit & Drupal (1/2) <?php /** * Implementation hook_help() */ function drupalcampmontreal_help($path, $arg) { switch ($path) { case 'admin/help#drupalcampmontreal': $output = '<h3>A propos de : DrupalCamp Montréal</h3>'; $output .= '<p>Exemple de module test DrupalCamp Montréal 2014</p>'; return $output; } } ✔ drupalmontreal.module
  19. 19. Module & PHPUnit & Drupal (2/2) drupalcampmontreal.test.php <?php include_once DRUPAL_ROOT . 'includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); class drupalcampmontreal_test extends PHPUnit_Framework_TestCase { public function test_function_help() { $output = '<h3>A propos de : DrupalCamp Montréal</h3>'; $output .= '<p>Exemple de module test DrupalCamp Montréal 2014</p>'; $this->assertEquals(drupalcampmontreal_help('admin/help#drupalcampmontreal'), $output ); } ...
  20. 20. Résultat
  21. 21. Tests Fonctionnels... En pratique
  22. 22. Tests Fonctionnels Déroulement Quoi tester ? ✔ Prépare outil & API ✔ Vérifie l'intégration des différents composants ✔ On le partage ✔ On récupère le résultat ✔ Nous... Rien ✔ C'est le client
  23. 23. Tests Fonctionnels : utilisation Outils ✔ Selenium ✔ Casper.js & Phantom.js ✔ Cucumber ✔ GreenPepper ✔ ... D7 D8 D9 Roadmap Selenium Casper.js Phantom.js
  24. 24. Cas pratique avec Selenium
  25. 25. Tests Fonctionnels : utilisation
  26. 26. Différents Selenium ● Selenium *.jar ● Selenium IDE – Extension Firefox ● SeleniumHQ – Compatible avec tous les navigateurs http://www.seleniumhq.org/
  27. 27. Utilisation de Selenium
  28. 28. Selenium seul
  29. 29. Selenium et Drupal ✔ Module selenium ✔ S'appuie sur SimpleTest Selenium pour PHPUnit
  30. 30. Installation PHP Unit & Selenium # sudo apt-get install phpunit # sudo apt-get install php5-curl # sudo apt-get install php-selenium En mode assistée - Windows - Linux - Mac Avec IDE - Eclipse PDT - Netbeans
  31. 31. Utilisation PHP Unit & Selenium (1/2) <?php class TestLogin extends PHPUnit_Extensions_Selenium2TestCase { public function setUp() { $this->setHost('localhost'); $this->setPort(4444); $this->setBrowser('firefox'); $this->setBrowserUrl('http://localhost/seleniumTut'); } public function testHasLoginForm() { $this->url('index.php'); $username = $this->byName('username'); $password = $this->byName('password'); $this->assertEquals('', $username->value()); $this->assertEquals('', $password->value()); }
  32. 32. Utilisation PHP Unit & Selenium (2/2) <?php public function testSubmitButtonIsDisabledUntilFieldsAreFilled() { $this->url('index.php'); $username = $this->byName('username'); $password = $this->byName('password'); $submit = $this->byId('submit'); $this->assertFalse($submit->enabled()); $username->value('votreLogin'); $password->value('votrePassword'); $this->assertTrue($submit->enabled()); $username->clear(); $password->clear(); $username->value(' '); $this->assertFalse($submit->enabled()); } ?>
  33. 33. PHPUnit / Selenium / Drupal (1/3)
  34. 34. PHPUnit / Selenium / Drupal (2/3) <?php class drupalcampmontreal_test extends PHPUnit_Extensions_Selenium2TestCase { public function setUp() { $this->setHost('localhost'); $this->setPort(4444); $this->setBrowser('firefox'); $this->setBrowserUrl('http://localhost/drupal7'); } public function testSite() { $this->setBrowserurl ('index.php'); }
  35. 35. PHPUnit / Selenium / Drupal (3/3) public function testOuverturePageTypeMenu() { $this->open ( "http://localhost/drupal-test/admin/menus/diner" ); $this->assertElementValueEquals ( 'name', '' ); $this->assertElementValueEquals ( 'listlieu', '' ); }
  36. 36. Au final... les tests associés $ cd votreSite $ phpunit sites/all/modules/menus/menus.test.php
  37. 37. Tests Intégrations... En pratique
  38. 38. Tests Intégrations Déroulement Pourquoi ? ✔ 1 Navigation de la prod. ✔ Générer le script pour repérer les modifications de comportement ✔ 1 exécution sur le nouveau serveur ✔ Simulation d'un être humain ✔ Détection des problèmes éventuels
  39. 39. Tests Intégrations : utilisation Outils ✔ Selenium ✔ Sikuli ✔ Hudson / Jenkins ✔ PhpUnderControl ✔ Behat/Mink ✔ Sahi ✔ PHPCov ✔ ... D7 D8 D9 Roadmap Selenium Behat+mink
  40. 40. Cas pratique avec Behat
  41. 41. Utilisation # pear channel-discover pear.symfony.com # pear channel-discover pear.behat.org # pear install behat/behat http://docs.behat.org/ { "require": { "behat/behat": "2.4.*@stable" }, "minimum-stability": "dev", "config": { "bin-dir": "bin/" } } Contexte Evénements Résultat
  42. 42. Utilisation par le code Behat/Mink require_once 'mink/autoload.php'; class FeatureContext extends BehatMinkBehatContextMinkContext { /** * @Given /^Je suis identifie "([^"]*)"$/ */ public function jeSuisIdentifie($username) { return array( new StepGiven('I go to "login.php"') ,new StepWhen("I fill in 'Mon nom' with '$username' ") ,new StepWhen("I fill in 'Mon mot de passe' with '$password' ") ,new StepWhen('I press "Login"') ); } }
  43. 43. Behat / Mint / Drupal (1/3) Module behat # curl -s https://getcomposer.org/installer | php # php composer.phar install # wget http://selenium...../selenium-server-standalone-2.26.0.jar Behat.yml default: context: extensions: BehatMinkExtensionExtension: base_url: 'http://localhost' goutte: ~ selenium2: ~
  44. 44. Behat / Mint / Drupal (2/3) menus.feature Scenario: Submits diner when required fields are filled out Given I am on "/" When I follow "diner" And I fill in "Your name" with "#name" And I fill in "Your lieu" with "#lieu" And I press "add" Then I should see "diner ajouter"
  45. 45. Behat / Mint / Drupal (3/3) $ bin/behat features/menus.feature © http://drupalwatchdog.com/volume-2/issue-2/behat-and-mink
  46. 46. Les autres Tests …. Ils seront abordés dans la journée Ils seront abordés dans la journée
  47. 47. Merci http://blog.hello-design.fr @hellosct1 Questions ?

×