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.
4. 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
5. 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
6. 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?
8. 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
10. 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
11. 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
12. 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!
13. 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
14. 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
19. 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
21. 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
22. ● 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
23. ● Creates an entity
●
● Sets a field value and
● calls the view method
Runs through full entity
API system.
● ~3s per test case
●
24. ● 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
25. 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/
26. The testing pyramid
● Write lots of unit tests
● Write integration tests
● Write some end-to-end UI tests
● Just a guide, common sense applies!
27. 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
30. 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.
31. 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
32. ● 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
33. 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