automated php unit testing in drupal 8

30
AUTOMATED TESTING IN DRUPAL 8

Upload: jay-friendly

Post on 07-Feb-2017

167 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Automated php unit testing in drupal 8

AUTOMATED TESTING IN DRUPAL

8

Page 2: Automated php unit testing in drupal 8

• @jaypan on Drupal.org and drupal.stackexchange.com• Acquia certified Drupal Grandmaster

• Acquia Certified Developer• Acquia Certified Developer – Front end specialist• Acquia Certified Developer – Back end specialist

• Living in Japan since 2000• Working with Drupal since 2007• Currently writing a book on coding in Drupal

JAY FRIENDLY

Page 3: Automated php unit testing in drupal 8

JAY FRIENDLY

• Owner of Jaypan in Yokohama• English https://www.jaypan.com• Japanese https://www.jaypan.jp

• Jaypan specializes in• high-performance AJAX/JavaScript heavy applications• Custom module/theme development• App Development• Drupal integration with outside technologies

• JavaScript libraries• Linux programs• Multiple Drupal instances

• Technical consulting and translation (Japanese/English)

Page 4: Automated php unit testing in drupal 8

OVERVIEW

• Manual testing vs. automated testing

• How do automated tests work?

• History of testing in Drupal

• Types of automated tests in Drupal

• Discussion of each type of test

Page 5: Automated php unit testing in drupal 8

MANUAL TESTING

• Developer creates new functionality

• Developer tests new functionality

• Other people (client, team-members) test new functionality

• Found bugs are fixed

Page 6: Automated php unit testing in drupal 8

PROBLEMS WITH MANUAL TESTING

• Complex functionality requires significant time to test

• Easy to forget to test a given scenario

• Changes to code require re-testing every scenario after any change

• Changes to code in other parts of the system may break functionality without anyone realizing it

• As time passes, the conditions that need to be tested may be forgotten or lost as project members change

• Coming back to code after a period of time means the developer is not sure what is required

Page 7: Automated php unit testing in drupal 8

AUTOMATED TESTING

• Developer creates automated tests that run through all testing scenarios

• Testing system runs all tests and reports any behaviors that are unexpected (aka bugs)

Page 8: Automated php unit testing in drupal 8

BENEFITS OF AUTOMATED TESTING

• Removes requirement of getting humans to test after each code change

• Tests are faster than human testing

• Tests for the whole system can be run before committing any code to a production server, to ensure new functionality in one part of the system hasn’t broken functionality in another part of the system.

• If (or rather, when) new bugs are found, tests can be added along with the fix, to ensure that the bug never arises again

• Overall system is more stable.

Page 9: Automated php unit testing in drupal 8

PROBLEMS WITH AUTOMATED TESTING

• Writing tests takes a significant amount of time

• Extra time means extra development resources

• Clients cannot directly see tests, and may not understand the extra costs in developing when there is nothing for them to look at.

• Tests only test what they have been written to test. If the developer does not think to test something, a bug could exist. The existence of automated tests in such a case may create a false sense of security

• Tests happen in a virtual (non-visible) environment, making them hard to debug (and even create)

• Changing code often requires re-writing old tests

Page 10: Automated php unit testing in drupal 8

OR IN OTHER WORDS, WHAT IS IT?HOW DOES A TEST WORK?

• A test will first run some code, then do ‘assertions’ to ensure that the results work as expected.

• For example, in Drupal 8, nodes have a method id(), that returns the ID of the node.

• An automated test would create a new node object, then run $node->id() and test:

• Was a result returned?

• Is the result an integer?

• Is the returned ID the expected (correct) ID of the node that was created?

• Any failed assertions result in a failed test, telling the developer exactly what failed, so they know what to fix.

Page 11: Automated php unit testing in drupal 8

AUTOMATED TESTING IN DRUPAL - HISTORY

• Drupal 6 - Simpletest module

• Drupal 7 - Simpletest in core

• Drupal 8 -

• Simpletest still in core but deprecated (to be removed in D9)

• PHPUnit introduced into core

• This presentation focuses exclusively on PHPUnit

Page 12: Automated php unit testing in drupal 8

TYPES OF TESTS IN DRUPAL 8

• Unit tests

• Kernel tests

• Functional tests

• JavaScript functional tests

Page 13: Automated php unit testing in drupal 8

UNIT TESTS IN DRUPAL 8

• A Unit is a PHP Class (OOP)

• Unit tests test code, not user-end functionality

• Unit tests will test a single class, to ensure that it behaves as expected

• Unit tests test the unit (class) alone in isolation, rather than in the Drupal environment

• Unit testing is very fast, as the system does not need to be bootstrapped to run the tests

Page 14: Automated php unit testing in drupal 8

UNIT TEST OVERVIEW

• Unit tests go in [MODULENAME]/tests/src/Unit

• Namespace is Drupal\Tests\[MODULENAME]\Unit

• Unit tests extend Drupal\Tests\UnitTestCase

• Annotation should include (at a minimum)

• Class:

• @coversDefaultClass - the class the the test is testing

• @group - the group of tests (usually module name) that the test belongs to

• Method:

• @covers - the method of the class being tested

Page 15: Automated php unit testing in drupal 8

UNIT TEST OVERVIEW

• Testing class name should end in ‘Test’

• Example: the test for the Person class would be PersonTest

• Testing method (function) name must start with ‘test’

• Example: the method used to test the id() method of Person would be testId()

Page 16: Automated php unit testing in drupal 8

UNIT TEST OVERVIEW

• Test classes can have a setUp() method, that sets up conditions/objects before each test in the test class.

• Useful when all tests require a similar set of conditions

• Test classes can also have a tearDown() method, where objects are cleaned up after each test in the test class.

• Test classes can have a setUpBeforeClass() method that is run once before the test class is run

• Test classes can have a tearDownAfterClass() method that is run once after the test class is finished

Page 17: Automated php unit testing in drupal 8

CLASS (UNIT) TO BE TESTED

class Person {

private $id;

public function setId($id) {

$this->id = $id;

}

public function id() {

return $this->id();

}

}

Page 18: Automated php unit testing in drupal 8

EXAMPLE UNIT TEST FOR PERSON CLASS

/** * @coversDefaultClass Person */class PersonTest { /** * @covers ::setId() */ public testId() { $person = new Person(); $person->setId(123); $this->assertNotNull($person->getId(), ‘A value is returned for the ID’); $this->assertTrue(is_int($person->id()), ‘The returned ID is an integer’); $this->assertEqual(123, $this->getId(), ‘The returned ID is correct’); }}

Page 19: Automated php unit testing in drupal 8

KERNEL TESTSKERNEL TESTS IN DRUPAL 8

• Kernel tests are executed in a limited Drupal environment, similar to the environment before Drupal has been installed

• Tests can access files and the database

• Declared modules are loaded, but not installed. Installation needs to be done manually

• Kernel tests are slower than Unit tests, but faster than Functional tests

Page 20: Automated php unit testing in drupal 8

KERNEL TEST OVERVIEW

• Kernel tests go in [MODULENAME]/tests/src/Kernel

• Namespace is Drupal\Tests\[MODULENAME]\Kernel

• Kernel tests extend Drupal\Tests\KernelTestBast

Page 21: Automated php unit testing in drupal 8

EXAMPLE KERNEL TEST

Sorry no example!

Page 22: Automated php unit testing in drupal 8

FUNCTIONAL TESTS IN DRUPAL 8

• Functional tests work in an installed Drupal environment

• Modules needed for the test need to be declared for installation

• Tests use an internal browser (aka code - not visual), where links can be clicked, form elements can be filled out, and pages can be requested, all programmatically

• Users, roles, blocks and other entities can be created

• Tests are slow as each test builds a new Drupal instance in which to run the tests

Page 23: Automated php unit testing in drupal 8

FUNCTIONAL TEST OVERVIEW

• Unit tests go in [MODULENAME]/tests/src/Functional

• Namespace is Drupal\Tests\[MODULENAME]\Functional

• Unit tests extend Drupal\Tests\BrowserTestBase

• Annotation should include (at a minimum)

• Class:

• @group - the group of tests (usually module name) that the test belongs to

• $modules property contains an array of modules to be installed

• example: $modules = [‘node’, ‘restrict_ip’]

Page 24: Automated php unit testing in drupal 8

FROM RESTRICT IP MODULEEXAMPLE FUNCTIONAL TEST

namespace Drupal\Tests\restrict_ip\Functional;

/** * @group restrict_ip */class RestrictIpAccessTest extends RestrictIpBrowserTestBase // which extends BrowserTestBase{

protected static $modules = ['restrict_ip', 'node'];

/** * Test that a user is blocked when the module is enabled */public function testModuleEnabled(){

$adminUser = $this->drupalCreateUser(['administer restricted ip addresses', 'access administration pages', 'administer modules']);

$this->drupalLogin($adminUser);$this->drupalGet('admin/config/people/restrict_ip');$this->assertStatusCodeEquals(200);$this->checkCheckbox('#edit-enable');$this->click('#edit-submit');$this->assertSession()->pageTextContains('The page you are trying to access cannot be

accessed from your IP address.');}

}

Page 25: Automated php unit testing in drupal 8

JAVASCRIPT FUNCTIONAL TESTS IN DRUPAL 8

• JavaScript Functional tests work in a fully installed Drupal environment

• Extends Functional tests to include JavaScript

• Require PhantomJS browser

• Virtual browser (no GUI)

• Requires installation on testing computer/server

• Can test #ajax methods, as well as other JavaScript functionality

Page 26: Automated php unit testing in drupal 8

JAVASCRIPT FUNCTIONAL TEST OVERVIEW

• Unit tests go in [MODULENAME]/tests/src/FunctionalJavascript

• Namespace is Drupal\Tests\[MODULENAME]\FunctionalJavascript

• Unit tests extend Drupal\FunctionalJavascriptTests\JavascriptTestBase

• Annotation should include (at a minimum)

• Class:

• @group - the group of tests (usually module name) that the test belongs to

Page 27: Automated php unit testing in drupal 8

FROM FANCY LOGIN MODULEEXAMPLE JAVASCRIPT FUNCTIONAL TEST

namespace Drupal\Tests\fancy_login\FunctionalJavascript;

/** * @group fancy_login */class FancyLoginJavascriptTest extends FancyLoginJavascriptTestBase // which extends JavascriptTestBase{

public function testDimmerBackgroundColor(){

$this->openPopup();

$this->assertJsCondition('jQuery("#fancy_login_dim_screen").not(":animated")');$this->assertJsCondition('jQuery("#fancy-login-user-login-form").not(":animated")');

$script = $this->createScriptString('#fancy_login_dim_screen', 'background-color', 'rgb(255, 255, 255)');

if(!$this->getSession()->evaluateScript($script)){

throw new \Exception('background-color is not white');}

// …}

}

Page 28: Automated php unit testing in drupal 8

WRITE TESTS THEN CODETESTING DRIVEN DEVELOPMENT

• Write tests as the start of the project, rather than the end

• Developers build and test as they go

• Gives a clear indicator of what to do next

• Gives a clear indication of when the project is complete

• Note - testing driven development is purely theoretical for me - I’ve never done it

Page 29: Automated php unit testing in drupal 8

WHERE TO GO FROM HERE

• PHPUnit in Drupal 8 - https://www.drupal.org/docs/8/phpunit

• Documentation is limited

• Lots and lots of Googling

Page 30: Automated php unit testing in drupal 8

Thank you!(Questions?)