Upload
sam-becker
View
310
Download
4
Embed Size (px)
Citation preview
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
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
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?
Basic anatomy of a PHPUnit test● Live in the Drupal\Tests\module
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
PHPUnit assertionsassertArrayHasKeyassertClassHasAttributeassertArraySubsetassertClassHasStaticAttributeassertContainsassertContainsOnlyassertContainsOnlyInstancesOfassertCountassertDirectoryExistsassertDirectoryIsReadableassertDirectoryIsWritableassertEmptyassertEqualXMLStructureassertEquals
assertFalseassertFileEqualsassertFileExistsassertFileIsReadableassertFileIsWritableassertGreaterThanassertGreaterThanOrEqualassertInfiniteassertInstanceOfassertInternalTypeassertIsReadableassertIsWritable… and others (https://phpunit.de/manual/)
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
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
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!
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
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
● Very simple unit test with single assertion.
● Simple input/out scenario, not mocking required.
● ~10ms per test case
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
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
● 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
● Creates an entity●● Sets a field value and● calls the view method
Runs through full entity API system.
● ~3s per test case●
● 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
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/
The testing pyramid● Write lots of unit tests● Write integration tests● Write some end-to-end UI tests
● Just a guide, common sense applies!
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
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.
Cheating setUp● Run tests against a pre-setup site:
https://www.drupal.org/node/2793445
● Useful for functional tests that broadly cover a whole site
● Let CI do the heavy lifting
● 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
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