Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
CI / CD w/ Codeception
CI / CD w/ Codeception
Loading in …3
×
1 of 40

More Related Content

You Might Also Like

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)

  1. 1. TEST DRIVEN DEVELOPMENT WITH DRUPAL AND CODECEPTION
  2. 2. WHO AM I? MATT CHAPMAN DEVELOPER TWITTER: @CHAPABU DRUPAL.ORG: /U/CHAPABU
  3. 3. WHAT IS TDD? -ScottWambler [Test driven development] is an evolutionary approach to development which combines test- first development where you write a test before you write just enough production code to fulfill that test and refactoring. IntroductiontoTestDrivenDevelopment(TDD)
  4. 4. TDD WORKFLOW Write a test Run your tests Watch them fail Write enough code to make your tests pass Run your tests again Refactor/tidy up Run your tests again Repeat... LET YOUR TESTS DRIVE YOUR DEVELOPMENT!
  5. 5. WHY USE TDD? For the entire lifespan of your project, you have tests for the features you build. Forces you to think about features before implementation (do you really need to install that really cool module?) Speeds up development Ensures you write good quality code/build good quality features It's fun! No, really! Again; for the entire lifespan of your project, you have tests for the features you build
  6. 6. WHAT IS CODECEPTION PHP Test framework Can run almost any kind of test you can think of
  7. 7. WHY CHOOSE CODECEPTION? Powered by PHPUnit VERY easy to extend Run any type of test you may want to Acceptance Functional Unit Or build your own suite with a combination of provided modules (CLI suite for custom Drush commands? You got it!) Run all your different test types from one source
  8. 8. INSTALLATION composer require codeception/codeception --dev
  9. 9. SETUP vendor/bin/codecept bootstrap PROTIP Add vendor/bin to your $PATH
  10. 10. EXAMPLE TIME!
  11. 11. WHAT FEATURE DO WE WANT TO IMPLEMENT? Scenario: Authors should be able to create Articles Given I have a user named "Bill" And "Bill" has the role of Author When "Bill" tries to create an Article node Then "Bill" should see the node/add page for an Article And "Bill" should be able to create an Article node
  12. 12. LET'S START WITH A TEST codecept generate:cest acceptance AuthorPermissions
  13. 13. ./TESTS/ACCEPTANCE/AUTHORPERMISSIONCEST.PHP <?php use AcceptanceTester; class AuthorPermissionsCest { public function _before(AcceptanceTester $I) { } public function _after(AcceptanceTester $I) { } // tests public function tryToTest(AcceptanceTester $I) { } }
  14. 14. HOW MIGHT OUR TEST LOOK?
  15. 15. public function _before(AcceptanceTester $I) { $this->faker = Faker::create(); } public function an_author_can_create_article_content(AcceptanceTester $I) { $I->am('an author'); $I->wantTo('create an Article'); $I->expect('to be able to create an Article node.'); $I->amOnPage('/user/login'); $I->submitForm('#user-login', ['name' => 'Bill', 'pass' => 'password']); $I->seeElement('body.logged-in'); $I->amOnPage('/node/add/article'); $I->seeResponseCodeIs('200'); $node_title = $this->faker->text(30); $I->submitForm( '#article-node-form', [ 'title' => $node_title, 'body[und][0][value]' => $this->faker->text(400), ] ); $I->see($node_title, '#page-title'); }
  16. 16. LET'S RUN IT
  17. 17. WHY DID IT FAIL? We haven't added the permission to the user role. Let's add it and re-run the test.
  18. 18. EXTENDING CODECEPTION
  19. 19. PAGEOBJECTS
  20. 20. WHAT IS A PAGEOBJECT -Codeceptiondocs The PageObject pattern represents a web page as a class and the DOM elements on that page as its properties, and some basic interactions as its methods. AdvancedUsage
  21. 21. CREATING PAGEOBJECTS codecept generate:pageobject acceptance LoginPage
  22. 22. EXAMPLE PAGEOBJECT <?php class LoginPage { public static $URL = '/user/login'; public static $usernameField = '#edit-name'; public static $passwordField = '#edit-pass'; protected $acceptanceTester; public static function route() { return static::$URL; } }
  23. 23. PAGEOBJECT USAGE public function an_author_can_create_article_content(AcceptanceTester $I) { ... $I->amOnPage(LoginPage::$URL); $I->submitForm(LoginPage::$formId, [ LoginPage::$usernameField => 'Bill', LoginPage::$passwordField => 'password' ] ); $I->seeElement('body.logged-in'); ... }
  24. 24. STEPOBJECTS
  25. 25. WHAT IS A STEPOBJECT? A StepObject is a class consisting of methods containing actions (steps) that are run. BEFORE $I->amOnPage('/user/login'); $I->submitForm('#user-login', [ 'name' => 'Bill', 'pass' => 'password' ] ); AFTER $I->login('Bill', 'password');
  26. 26. CREATING STEPOBJECTS codecept generate:stepobject acceptance UserSteps
  27. 27. EXAMPLE STEPOBJECT ... use LoginPage; class UserSteps extends AcceptanceTester { public function login($userName, $userPassword) { $I = $this; $I->amOnPage(LoginPage::$URL); $I->submitForm(LoginPage::$formId, [ LoginPage::$usernameField => $userName, LoginPage::$passwordField => $userPassword ] ); } ... }
  28. 28. STEPOBJECT USAGE use AcceptanceTesterUserSteps; ... public function an_author_can_create_article_content(UserSteps $I) { ... $I->login('Bill', 'password'); $I->seeElement('body.logged-in'); ... }
  29. 29. REFACTORING TIME Copy and paste once - any more, extract to a StepObject or PageObject A readable test is a useful test; if a set of steps would benefit from a description, then extract to a StepObject
  30. 30. HOW DID OUR TEST LOOK? public function an_author_can_create_article_content(AcceptanceTester $I) { $I->am('an author'); $I->wantTo('create an Article'); $I->expect('to be able to create an Article node.'); $I->amOnPage('/user/login'); $I->submitForm('#user-login', ['name' => 'Bill', 'pass' => 'password']); $I->seeElement('body.logged-in'); $I->amOnPage('/node/add/article'); $I->seeResponseCodeIs('200'); $node_title = $this->faker->text(30); $I->submitForm( '#article-node-form', [ 'title' => $node_title, 'body[und][0][value]' => $this->faker->text(400), ] ); $I->see($node_title, '#page-title'); }
  31. 31. WE CREATE PAGEOBJECTS AND STEPOBJECTS... PageObjects LoginPage ArticleNode StepObjects UserSteps
  32. 32. HOW DOES OUR TEST LOOK NOW? use ArticleNode; public function an_author_can_create_article_content(AcceptanceTester $I) { $I->am('an author'); $I->wantTo('create an Article'); $I->expect('to be able to create an Article node.'); $I->login('Bill', 'password'); $I->amOnPage(ArticleNode::$nodeAddFormURL); $I->seeResponseCodeIs('200'); $node_title = $this->faker->text(30); $I->submitForm( ArticleNode::$nodeFormId, [ ArticleNode::$titleEditField => $node_title, ArticleNode::$bodyEditField => $this->faker->text(400), ] ); $I->see($node_title, ArticleNode::$pageTitleSelector); }
  33. 33. USEFUL EXTENSIONS A set of standard page objects for use in Codeception tests on Drupal sites. codeception-drupal-pages A Codeception module for managing test users Drupal User Registry A Codeception module to provide a set of classes that encapsulate Drupal content types. Drupal Content Type Registry The Codeception extension for automatically starting and stopping PhantomJS when running tests. Phantoman Codeception curated list of addons Codeception Addons page
  34. 34. POSSIBLE ALTERNATIVES PHPUnit PHPSpec CasperJS Selenium
  35. 35. WE'RE HIRING SENIOR FRONT END DEVELOPER GRADUATE DEVELOPER
  36. 36. THANK YOU!

×