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.

Test all the things! Automated testing with Drupal 8

1,273 views

Published on

With Drupal 8 released, one of the most important aspects of building a website or module has changed dramatically for the better. Developers now have a myriad of tools at their disposal to be able to test their code. If you are interested in improving your code and preventing bugs, but are unfamiliar with acronyms like BTB, KTB and WTB, this session is for you. If you’ve dabbled in testing but haven’t explored the depths of PHPUnit or Mink, then this session is for you.

Published in: Technology
  • Login to see the comments

  • Be the first to like this

Test all the things! Automated testing with Drupal 8

  1. 1. Test all the things! Automated testing with Drupal 8 27th Oct. 2016
  2. 2. Who am I?
  3. 3. In this session ● High level introduction of different testing concepts used in core and contrib ● How these concepts can be used to test bespoke Drupal site builds ● When to apply different types of tests to different situations
  4. 4. What are tests? Why test your code? ● Code that executes code ● Asserts a set of constraints ● Usually run on regular intervals ● See fewer bugs in production ● Make stakeholders (and developers!) happy ● Release and deploy more confidently ● Write better code ● Refactor more confidently
  5. 5. How do we test code in Drupal 8? ● All tools found in Drupal core ● All based on PHPUnit ● Base classes help with interacting with Drupal ○ UnitTestCase ○ KernelTestBase ○ BrowserTestBase ○ JavascriptTestBase ○ … more on these later ● Useful for contrib, core and client projects ● Useful outside of Drupal?
  6. 6. PHPUnit ● Testing framework written in PHP ● Adopted by many other PHP frameworks
  7. 7. Basic anatomy of a PHPUnit test ● Live in the DrupalTestsmodule namespace ● They usually extend a Drupal test base ● Setup method is run for every test method ● Each test method is prefixed with the word “test” ● A test method contains a series of assertions ● PHPUnit provides lots of assertion methods
  8. 8. PHPUnit assertions assertArrayHasKey assertClassHasAttribute assertArraySubset assertClassHasStaticAttribute assertContains assertContainsOnly assertContainsOnlyInstancesOf assertCount assertDirectoryExists assertDirectoryIsReadable assertDirectoryIsWritable assertEmpty assertEqualXMLStructure assertEquals assertFalse assertFileEquals assertFileExists assertFileIsReadable assertFileIsWritable assertGreaterThan assertGreaterThanOrEqual assertInfinite assertInstanceOf assertInternalType assertIsReadable assertIsWritable … and others (https://phpunit.de/manual/)
  9. 9. PHPUnit mocking ● Create classes your test code depends on ● Define exactly how they should behave ● Use as much or as little as the dependency as you like More on mocking: https://phpunit.de/manual/current/en/test-doubles.html
  10. 10. PHPUnit @dataProvder ● Data providers run a test method with lots of different inputs ● Allows you to name you test cases ● Helps cover lots of scenarios and quickly identify what is broken
  11. 11. Running tests ● Configure all the environment variables required to run tests (https://www.drupal.org/docs/8/phpunit/running-phpunit-tests) ● Use the phpunit binary ● PHPStorm integration!
  12. 12. UnitTestCase ● Drupals unit testing base class ● Tests the behavior of a class in isolation ● Mock your dependencies, inject them ● No access to a Drupal bootstrap or database ● Very fast ● Test lots of inputs/outputs very quickly
  13. 13. Tests informing design ● Testable code is good code ● Clearly reveals your dependencies (some you never knew you had) ● Illustrates when you might have too many dependencies ● Encourages you to expose the minimum amount of information required between classes
  14. 14. Real world examples
  15. 15. ● Very simple unit test with single assertion. ● Simple input/out scenario, not mocking required. ● ~10ms per test case
  16. 16. Reference Table Formatter List of Content Entities =>
  17. 17. Test doubles required for: ● EntityTypeInterface ● FieldDefinitionInterface ● FieldItemListInterface ● EntityManagerInterface ● EntityTypeInterface ● EntityStorageInterface ● EntityViewDisplayInterface ● RendererInterface ● Possibly a sign of bad design, should some of the logic in the module be split into different class? ● Pain to write and maintain, 150 lines of code to mock dependencies. ● Possibly should have been an integration test, testing against real world instances of these dependencies. Under the hood
  18. 18. There are limits...
  19. 19. KernelTestBase ● New concept to Drupal 8 ● Write test code within a bootstrapped Drupal site ● Tests your codes integration with Drupal and other components ● Gives you access to Drupal APIs (entities, services, plugins etc) ● Still have access to all of the PHPUnit assertions and mocking ● Still pretty fast
  20. 20. ● Install parts of Drupal required for the test on demand ● Entity schema and module configuration needs to be explicitly installed ● Drupal content and configuration can be created as part of the test
  21. 21. ● Creates an entity ● ● Sets a field value and ● calls the view method Runs through full entity API system. ● ~3s per test case ●
  22. 22. ● Introduces a web browser ● Functional, end-to-end testing, using a UI, simulating a user ● Write instructions for the web browser and make assertions about the UI along the way ● Verbose output can show you a snapshot of the page at each step in the test ● Slow to run BrowserTestBase
  23. 23. Mink ● Pluggable browsers, one API ● Two browsers used in core (for now) ● Brings a whole library of assertions with it ● ...more at http://mink.behat.org/
  24. 24. The testing pyramid ● Write lots of unit tests ● Write integration tests ● Write some end-to-end UI tests ● Just a guide, common sense applies!
  25. 25. JavascriptTestBase ● BrowserTestBase but with JavaScript! ● Same assertion library as BTB ● Uses PhantomJS mink plugin ● Required for testing any kind of AJAX ● Test any JS UI interaction ○ Opening a lightbox ○ Scrolling the page ○ Resizing your window ○ Hovering over a menu
  26. 26. WebKit under the hood
  27. 27. Utility Traits ● Add useful functionality to test classes ○ Create test content ○ Load entities ○ Custom more specific assertions ● Extend KTB, BTB or JTB and use the same methods.
  28. 28. Cheating setUp ● Run tests against a pre-setup site: https://www.drupal.org/node/2793 445 ● Useful for functional tests that broadly cover a whole site ● Let CI do the heavy lifting
  29. 29. ● WebTestBase, based on simpletest in Drupal 7 ○ Still lots of core tests being converted ● The other KernelTestBase before it was based on phpunit ○ … when KTB was KTBTNG Deprecated test classes
  30. 30. Consider not writing a test when... ● The code isn’t complex ● The test will only fails with false positives ● It has a maintenance cost with no benefit
  31. 31. Final thoughts ● Testing in Drupal 8 is awesome ● Write lots of tests
  32. 32. Questions?

×