0
Automated Testing in

WordPress,
Really?!
Rate this talk: https://joind.in/10115

#dc4d - Automated Testing in WordPress w...
Ptah (Pirate) Dunbar

●

Started with WordPress and PHP
in ‘05

●

Contributing developer to
WordPress, BuddyPress, bbPres...
Ptah (Pirate) Dunbar

●

Started with WordPress and PHP
in ‘05

●

Contributing developer to
WordPress, BuddyPress, bbPres...
Ptah (Pirate) Dunbar

●

Started with WordPress and PHP
in ‘05

●

Contributing developer to
WordPress, BuddyPress, bbPres...
Agenda

In one hour
● Understand automated testing concepts,
ideas and best practices.
● Learn PHPUnit basics and the Word...
WordPress
powers

1 in 5
websites
source: http://w3techs.com/blog/entry/wordpress_powers_1_in_5_websites

#dc4d - Automate...
WordPress
community

28,510
2,177
source: http://w3techs.com/blog/entry/wordpress_powers_1_in_5_websites

#dc4d - Automate...
“The result is that a lot of the
plugins are written in poor code
and turn out to be poorly
compatible with other plugins”...
Fail.
Manual Testing

Pull out the tools
●
●
●
●
●

WP_DEBUG
var_dump();
print_r();
error_log();
debug_backtrace();

#dc4d - Aut...
Manual Testing

Pull out the tools
●
●
●
●
●

WP_DEBUG
var_dump(); Temporary
Ad-hoc &
print_r();
error_log();
debug_backtr...
Manual Testing

Pull out the tools
●
●
●
●
●

WP_DEBUG
var_dump(); Error Prone
SLOW &
print_r();
error_log();
debug_backtr...
Manual Testing

Pull out the tools
●
●
●
●
●

WP_DEBUG
var_dump();
Doesn’t scale
print_r();
error_log();
debug_backtrace()...
#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing

A scripted process that
invokes your app to test
features and compares the
outcome with expected
result...
Automated Testing

Persistent var_dumps();

#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing

Better than checking the logs

#dc4d - Automated Testing in WordPress with @ptahdunbar
The Bigger Picture

Continuous Integration
vagrant
Phing

Continuous Delivery

BDD

Automated Testing
Scrum
Agile

TDD

Co...
Automate Testing

Getting started

#dc4d - Automated Testing in WordPress with @ptahdunbar
CHOOSE YOUR FRAMEWORK

There are so many

Frameworks
#dc4d - Automated Testing in WordPress with @ptahdunbar
CHOOSE YOUR FRAMEWORK

PHPUnit
http://phpunit.de/manual/
Sebastian Bergmann

#dc4d - Automated Testing in WordPress with @...
{
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/phpunit-selenium" : "*",
}
}

http://getcomposer.org

vim composer...
PHPUnit

$>./vendor/bin/phpunit

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit

Terminology

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit

Terminology
● Test Case
A set of conditions that you set up in order
to assert expected outcome.

#dc4d - Automat...
PHPUnit

Terminology
● Test Case
A set of conditions that you set up in order
to assert expected outcome.
● Test Class
A c...
PHPUnit

Terminology
● Test Case
A set of conditions that you set up in order
to assert expected outcome.
● Test Class
A c...
PHPUnit

TEST CLASS
<?php
// test class
class CalTest extends PHPUnit_Framework_TestCase
{
// test case
public function te...
PHPUnit

TEST CLASS
<?php
// test class
class CalTest extends PHPUnit_Framework_TestCase
{
// test case
public function te...
PHPUnit
plugin/
loader.php
includes/
admin.php
api.php
…
phpunit.xml
tests/
adminTest.php
ApiTest.php
…
…

#dc4d - Automat...
PHPUnit
plugin/
loader.php
includes/
admin.php
functions.php
…
phpunit.xml
tests/
integration/
…
acceptance/
…
…

#dc4d - ...
PHPUnit

phpunit.xml - configuration file for PHPUnit
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/au...
PHPUnit

phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsu...
PHPUnit

phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsu...
PHPUnit

phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsu...
PHPUnit

Assertions
Explicitly check expected outcome
agaisnt actual outcome.

#dc4d - Automated Testing in WordPress with...
PHPUnit

Assertions
Explicitly check expected outcome
agaisnt actual outcome.
$this->assertTrue(condition);

#dc4d - Autom...
PHPUnit

Arrange, Act, Assert

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit

function testThatItsTestingTime()
{
1. A
2. A
3. A
}

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit

function testThatItsTestingTime()
{
1. A
2. A
3. Assert (check for the expected behavior)
}

#dc4d - Automated Te...
PHPUnit

function testThatItsTestingTime()
{
1. A
2. Act (call the method/trigger the action)
3. Assert (check for the exp...
PHPUnit

function testThatItsTestingTime()
{
1. Arrange (the context/dependencies)
2. Act (call the method/trigger the act...
PHPUnit

Example

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
./vendor/bin/phpunit

PHPUnit

<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumO...
./vendor/bin/phpunit

PHPUnit

<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumO...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
PHPUnit
<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumOfTwoPositiveIntegers()
...
./vendor/bin/phpunit

PHPUnit

<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumO...
./vendor/bin/phpunit

PHPUnit

<?php
class CalTest extends PHPUnit_Framework_TestCase
{
public function testAddReturnsSumO...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
./vendor/bin/phpunit

PHPUnit

<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersis...
./vendor/bin/phpunit

PHPUnit

<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersis...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
./vendor/bin/phpunit

PHPUnit

<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersis...
./vendor/bin/phpunit

PHPUnit

<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersis...
PHPUnit

ASSERTIONS
Appendix: http://phpunit.de/manual/3.7/en/appendixes.assertions.html

Use the most specific assertion ...
PHPUnit

FAIL

There was 1 failure:
1) Tests_Basic::test_readme
readme.html's version needs to be updated to 3.9.
Failed a...
FAIL
There was 1 failure:
1) Tests_User_Author::test_get_the_author
Failed asserting that two objects are equal.
--- Expec...
FAIL
There was 1 failure:
1) Tests_User_Author::test_get_the_author
Failed asserting that two objects are equal.
--- Expec...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValidUserdataRetur...
./vendor/bin/phpunit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValid...
./vendor/bin/phpunit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithValid...
PHPUnit
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testPersistWithInvalidUserdataRet...
WordPress Testsuite
WordPress Testsuite

WordPress with Tests
http://develop.svn.wordpress.org/trunk/
1858 Tests, 8611 Assertions, 2.59 minute...
WordPress Testsuite

#dc4d - Automated Testing in WordPress with @ptahdunbar
#dc4d - Automated Testing in WordPress with @ptahdunbar
WordPress Testsuite

#dc4d - Automated Testing in WordPress with @ptahdunbar
WordPress Testsuite

Getting started

#dc4d - Automated Testing in WordPress with @ptahdunbar
WordPress Testsuite

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap-wp.php">
<testsuites>
<tes...
WordPress Testsuite
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap-wp.php">
<testsuites>
<test...
WordPress Testsuite

<?php
class PluginTest extends PHPUnit_Framework_TestCase
{
// test cases...
}

plugin/tests/integrat...
WordPress Testsuite

<?php
class PluginTest extends WP_UnitTestCase
{
// test cases...
}

plugin/tests/integration/PluginT...
WordPress Testsuite

$>./vendor/bin/phpunit

#dc4d - Automated Testing in WordPress with @ptahdunbar
WordPress Testsuite

Run Tests
inside of an isolated

WordPress Environment

#dc4d - Automated Testing in WordPress with @...
WordPress Testsuite
bootstrap.php

Configure

$GLOBALS['wp_tests_options'] = [
'active_plugins' => [
'hello.php',
...
],
'...
WordPress Testsuite

Configure

bootstrap.php

WordPress
Includes

function __muplugins_loaded()
{
// code and stuff.
requ...
WordPress Testsuite
●

Navigate to site URL (Updates globals)
$this->get_url($url);

●

Test WP_Query for Conditionals (is...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
function testRedirectForDateBa...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
function testRedirectForDateBa...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
function testRedirectForDateBa...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
function testRedirectForDateBa...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
function testRedirectForDateBa...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
functio...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
// test cases
functio...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider getRequiredPlugins
*/
fu...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider getRequiredPlugins
*/
fu...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider g...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider g...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider getWPOptions
*/
function...
WordPress Testsuite
<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider getWPOptions
*/
function...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider g...
./vendor/bin/phpunit

WordPress Testsuite

<?php
class WPCustomizationTest extends WP_UnitTestCase
{
/**
* @dataProvider g...
http://www.seleniumhq.org/

#dc4d - Automated Testing in WordPress with @ptahdunbar
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Framework_TestCase
{
protected function setUp()
{

}
public fun...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{

}
...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance Testing
<?php
class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$th...
Acceptance
Selenium IDE Plugin

●

Visually navigate throughout your
site and generate a PHPUnit
test case.

●

Download E...
Acceptance
Selenium IDE Plugin

●

Visually navigate throughout your
site and generate a PHPUnit
test case.

●

Download E...
How can we be
confident that our tests
cover everything?

#dc4d - Automated Testing in WordPress with @ptahdunbar
Testing boundaries

#dc4d - Automated Testing in WordPress with @ptahdunbar
Testing boundaries

●

(User) Acceptance Testing
○

Verify that all features are done done.

○

Black-box testing, no know...
Testing boundaries

●

(User) Acceptance Testing
○
○

●

Verify that all features are done done.
Black-box testing, no kno...
Testing boundaries

●

(User) Acceptance Testing
○
○

●

Verify that all features are done done.
Black-box testing, no kno...
Testing boundaries

●

(User) Acceptance Testing
Verify that all features are done done,
black-box testing, no knowledge o...
Testing boundaries

●

(User) Acceptance Testing
Verify that all features are done done,
black-box testing, no knowledge o...
Testing boundaries

●

(User) Acceptance Testing
Verify that all features are done done,
black-box testing, no knowledge o...
What to tests?

● Test plugin works in various WordPress setups
○ Does it work under multisite?
○ What about a custom cont...
What to tests?

● Test for theme support
● Test that post formats contain property elements
● Test any required assets tha...
What to not tests?

1. WordPress APIs

#ATWP // Automated Testing in WordPress // @ptahdunbar
What to not tests?

1. WordPress APIs
2. PHP language features

#ATWP // Automated Testing in WordPress // @ptahdunbar
What to not tests?

1. WordPress APIs
2. PHP language features
3. Third party vendor code

#ATWP // Automated Testing in W...
Getting into the groove

#ATWP // Automated Testing in WordPress // @ptahdunbar
Getting into the groove

● Build out templates

#ATWP // Automated Testing in WordPress // @ptahdunbar
Getting into the groove

● Build out templates
○ Create HTML/CSS

#ATWP // Automated Testing in WordPress // @ptahdunbar
Getting into the groove

● Build out templates
○ Create HTML/CSS
○ Identify dynamic elements and their data
structure

#AT...
Getting into the groove

● Build out templates
○ Create HTML/CSS
○ Identify dynamic elements and their data
structure
○ La...
Getting into the groove

○ Verbally state your trying to do

#ATWP // Automated Testing in WordPress // @ptahdunbar
Getting into the groove

○ Verbally state your trying to do
○ Verbally explain what the code does

#ATWP // Automated Test...
Getting into the groove

○ Verbally state your trying to do
○ Verbally explain what the code does
○ Do this alone or with ...
What’s Next?
Get started

“A Walking Skeleton is a tiny implementation of the thinnest
possible slice of real functionality that we can...
Resources
● Art of Unit Testing (.NET)
○ https://leanpub.com/u/royosherove
○ Udemy Five day course
● #GOOS Book (Java)
● X...
Homework!

TODO
● Learn moar PHPUnit features
○ data providers,
○ mocks and stubs
○ wordpress testsuite
● Goal: Write at l...
Automated Testing

#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing
increases your productivity

#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing
facilitates more shipping

#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing
scales with you

#dc4d - Automated Testing in WordPress with @ptahdunbar
Automated Testing
is your professional duty
as a developer

#dc4d - Automated Testing in WordPress with @ptahdunbar
Thank you
Automated Testing in WordPress
Pirate Dunbar
@ptahdunbar
yarr@piratedunbar.com

Rate this talk:
https://joind.in...
Automated Testing in WordPress, Really?!
Upcoming SlideShare
Loading in...5
×

Automated Testing in WordPress, Really?!

9,068

Published on

Did you know that WordPress has an automated test suite? It contains well over 1500 integration tests and growing. However one of the primary culprits of WordPress is in the quality of its plugins. Most plugins don't have an automated test suite you can run to verify all features are working as expected, and fail gracefully.

In this talk, Ptah will introduce you to automated testing in WordPress using PHPUnit. We will cover concepts like unit testing, integration testing and end-to-end testing with examples in WordPress. You will leave the talk equipped with practical knowledge and ready to start adding an automated test suite to your plugins.

Published in: Technology, Business

Transcript of "Automated Testing in WordPress, Really?!"

  1. 1. Automated Testing in WordPress, Really?! Rate this talk: https://joind.in/10115 #dc4d - Automated Testing in WordPress with @ptahdunbar
  2. 2. Ptah (Pirate) Dunbar ● Started with WordPress and PHP in ‘05 ● Contributing developer to WordPress, BuddyPress, bbPress ● Full stack Web Developer ● Architect at LiveNinja.com ● WPMIA co-organizer and SoFloPHP member ☠ Became Pirate Dunbar #dc4d - Automated Testing in WordPress with @ptahdunbar
  3. 3. Ptah (Pirate) Dunbar ● Started with WordPress and PHP in ‘05 ● Contributing developer to WordPress, BuddyPress, bbPress ● Full stack Web Developer ● Architect at LiveNinja.com ● WPMIA co-organizer and SoFloPHP member ☠ Became Pirate Dunbar #dc4d - Automated Testing in WordPress with @ptahdunbar
  4. 4. Ptah (Pirate) Dunbar ● Started with WordPress and PHP in ‘05 ● Contributing developer to WordPress, BuddyPress, bbPress ● Full stack Web Developer ● Architect at LiveNinja.com ● WPMIA co-organizer and SoFloPHP member ☠ Became Pirate Dunbar #dc4d - Automated Testing in WordPress with @ptahdunbar
  5. 5. Agenda In one hour ● Understand automated testing concepts, ideas and best practices. ● Learn PHPUnit basics and the WordPress testsuite. ● Resources and homework #dc4d - Automated Testing in WordPress with @ptahdunbar
  6. 6. WordPress powers 1 in 5 websites source: http://w3techs.com/blog/entry/wordpress_powers_1_in_5_websites #dc4d - Automated Testing in WordPress with @ptahdunbar
  7. 7. WordPress community 28,510 2,177 source: http://w3techs.com/blog/entry/wordpress_powers_1_in_5_websites #dc4d - Automated Testing in WordPress with @ptahdunbar
  8. 8. “The result is that a lot of the plugins are written in poor code and turn out to be poorly compatible with other plugins” — Yoast http://yoast.com/plugin-future/ #dc4d - Automated Testing in WordPress with @ptahdunbar
  9. 9. Fail.
  10. 10. Manual Testing Pull out the tools ● ● ● ● ● WP_DEBUG var_dump(); print_r(); error_log(); debug_backtrace(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  11. 11. Manual Testing Pull out the tools ● ● ● ● ● WP_DEBUG var_dump(); Temporary Ad-hoc & print_r(); error_log(); debug_backtrace(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  12. 12. Manual Testing Pull out the tools ● ● ● ● ● WP_DEBUG var_dump(); Error Prone SLOW & print_r(); error_log(); debug_backtrace(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  13. 13. Manual Testing Pull out the tools ● ● ● ● ● WP_DEBUG var_dump(); Doesn’t scale print_r(); error_log(); debug_backtrace(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  14. 14. #dc4d - Automated Testing in WordPress with @ptahdunbar
  15. 15. Automated Testing A scripted process that invokes your app to test features and compares the outcome with expected results. #dc4d - Automated Testing in WordPress with @ptahdunbar
  16. 16. Automated Testing Persistent var_dumps(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  17. 17. Automated Testing Better than checking the logs #dc4d - Automated Testing in WordPress with @ptahdunbar
  18. 18. The Bigger Picture Continuous Integration vagrant Phing Continuous Delivery BDD Automated Testing Scrum Agile TDD Continuous Inspection Releasing early, releasing often #dc4d - Automated Testing in WordPress with @ptahdunbar
  19. 19. Automate Testing Getting started #dc4d - Automated Testing in WordPress with @ptahdunbar
  20. 20. CHOOSE YOUR FRAMEWORK There are so many Frameworks #dc4d - Automated Testing in WordPress with @ptahdunbar
  21. 21. CHOOSE YOUR FRAMEWORK PHPUnit http://phpunit.de/manual/ Sebastian Bergmann #dc4d - Automated Testing in WordPress with @ptahdunbar
  22. 22. { "require-dev": { "phpunit/phpunit": "3.7.*", "phpunit/phpunit-selenium" : "*", } } http://getcomposer.org vim composer.json && composer update #dc4d - Automated Testing in WordPress with @ptahdunbar
  23. 23. PHPUnit $>./vendor/bin/phpunit #dc4d - Automated Testing in WordPress with @ptahdunbar
  24. 24. PHPUnit Terminology #dc4d - Automated Testing in WordPress with @ptahdunbar
  25. 25. PHPUnit Terminology ● Test Case A set of conditions that you set up in order to assert expected outcome. #dc4d - Automated Testing in WordPress with @ptahdunbar
  26. 26. PHPUnit Terminology ● Test Case A set of conditions that you set up in order to assert expected outcome. ● Test Class A collection of test cases, extends PHPUnit #dc4d - Automated Testing in WordPress with @ptahdunbar
  27. 27. PHPUnit Terminology ● Test Case A set of conditions that you set up in order to assert expected outcome. ● Test Class A collection of test cases, extends PHPUnit ● Test Suite A collection of test classes #dc4d - Automated Testing in WordPress with @ptahdunbar
  28. 28. PHPUnit TEST CLASS <?php // test class class CalTest extends PHPUnit_Framework_TestCase { // test case public function testAddReturnsSumOfTwoPositiveIntegers() { // assert stuff. } } #dc4d - Automated Testing in WordPress with @ptahdunbar
  29. 29. PHPUnit TEST CLASS <?php // test class class CalTest extends PHPUnit_Framework_TestCase { // test case public function testAddReturnsSumOfTwoPositiveIntegers() { // assert stuff. } } #dc4d - Automated Testing in WordPress with @ptahdunbar
  30. 30. PHPUnit plugin/ loader.php includes/ admin.php api.php … phpunit.xml tests/ adminTest.php ApiTest.php … … #dc4d - Automated Testing in WordPress with @ptahdunbar
  31. 31. PHPUnit plugin/ loader.php includes/ admin.php functions.php … phpunit.xml tests/ integration/ … acceptance/ … … #dc4d - Automated Testing in WordPress with @ptahdunbar
  32. 32. PHPUnit phpunit.xml - configuration file for PHPUnit <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php"> <testsuites> <testsuite name="tests"> <directory suffix="Test.php">tests/</directory> </testsuite> </testsuites> </phpunit> #dc4d - Automated Testing in WordPress with @ptahdunbar
  33. 33. PHPUnit phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php"> <testsuites> <testsuite name="tests"> <directory suffix="Test.php">tests/</directory> </testsuite> </testsuites> </phpunit> Configure your test suite location #dc4d - Automated Testing in WordPress with @ptahdunbar
  34. 34. PHPUnit phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php"> <testsuites> <testsuite name="integration"> <directory suffix="Test.php">tests/integration</directory> </testsuite> <testsuite name="acceptance"> <directory suffix="Test.php">tests/acceptance</directory> </testsuite> </testsuites> </phpunit> Configure your test suite location #dc4d - Automated Testing in WordPress with @ptahdunbar
  35. 35. PHPUnit phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php"> <testsuites> <testsuite name="tests"> <directory suffix="Test.php">tests/</directory> </testsuite> </testsuites> </phpunit> Bootstrap file is included before any tests run #dc4d - Automated Testing in WordPress with @ptahdunbar
  36. 36. PHPUnit Assertions Explicitly check expected outcome agaisnt actual outcome. #dc4d - Automated Testing in WordPress with @ptahdunbar
  37. 37. PHPUnit Assertions Explicitly check expected outcome agaisnt actual outcome. $this->assertTrue(condition); #dc4d - Automated Testing in WordPress with @ptahdunbar
  38. 38. PHPUnit Arrange, Act, Assert #dc4d - Automated Testing in WordPress with @ptahdunbar
  39. 39. PHPUnit function testThatItsTestingTime() { 1. A 2. A 3. A } #dc4d - Automated Testing in WordPress with @ptahdunbar
  40. 40. PHPUnit function testThatItsTestingTime() { 1. A 2. A 3. Assert (check for the expected behavior) } #dc4d - Automated Testing in WordPress with @ptahdunbar
  41. 41. PHPUnit function testThatItsTestingTime() { 1. A 2. Act (call the method/trigger the action) 3. Assert (check for the expected behavior) } #dc4d - Automated Testing in WordPress with @ptahdunbar
  42. 42. PHPUnit function testThatItsTestingTime() { 1. Arrange (the context/dependencies) 2. Act (call the method/trigger the action) 3. Assert (check for the expected behavior) } #dc4d - Automated Testing in WordPress with @ptahdunbar
  43. 43. PHPUnit Example #dc4d - Automated Testing in WordPress with @ptahdunbar
  44. 44. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange // Act // Assert } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  45. 45. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange // Act // Assert } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  46. 46. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange // Act // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  47. 47. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange // Act $result = $calculator->add(1,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  48. 48. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); // Act $result = $calculator->add(1,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  49. 49. ./vendor/bin/phpunit PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); // Act $result = $calculator->add(1,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  50. 50. ./vendor/bin/phpunit PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); Time: 148ms, Memory: 2.75Mb // 1 OK: (1 test, Actassertions) $result = $calculator->add(1,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  51. 51. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); // Act $result = $calculator->add(1,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  52. 52. PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); // Act $result = $calculator->add(2,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  53. 53. ./vendor/bin/phpunit PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); // Act $result = $calculator->add(2,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  54. 54. ./vendor/bin/phpunit PHPUnit <?php class CalTest extends PHPUnit_Framework_TestCase { public function testAddReturnsSumOfTwoPositiveIntegers() { // Arrange $calculator = new Calculator(); Failed asserting that 4 equals 3 // Act $result = $calculator->add(2,2); // Assert $this->assertEquals(3, $result); } } plugin/tests/unit/calTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  55. 55. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange // Act // Assert } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  56. 56. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange // Act // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  57. 57. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  58. 58. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  59. 59. ./vendor/bin/phpunit PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  60. 60. ./vendor/bin/phpunit PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; Time: 248ms, Memory: 1.95Mb // Act $user = $service->persist($validUserdata); OK: (1 test, 1 assertions) // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  61. 61. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  62. 62. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveRacoonsUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  63. 63. ./vendor/bin/phpunit PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveRacoonsUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  64. 64. ./vendor/bin/phpunit PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; Failed asserting that false equals true // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveRacoonsUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  65. 65. PHPUnit ASSERTIONS Appendix: http://phpunit.de/manual/3.7/en/appendixes.assertions.html Use the most specific assertion possible ● assertTrue(); ● assertFalse(); ● assertEquals(); ● assertNotEquals(); ● assertContains(); ● assertContainsOnly(); ● assertGreaterThan(); ● assertLessThan(); ● assertNotNull(); ● assertSame(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  66. 66. PHPUnit FAIL There was 1 failure: 1) Tests_Basic::test_readme readme.html's version needs to be updated to 3.9. Failed asserting that '3.8' matches expected '3.9'. /private/tmp/wordpress-tests/tests/phpunit/tests/basic.php:29 #dc4d - Automated Testing in WordPress with @ptahdunbar
  67. 67. FAIL There was 1 failure: 1) Tests_User_Author::test_get_the_author Failed asserting that two objects are equal. --- Expected +++ Actual @@ @@ WP_User Object ( 'data' => stdClass Object ( 'ID' => '3' 'user_login' => 'User 1' 'user_pass' => '$P$BpIqOzMNRGZNy9qxKL/3cCDCMe85o2.' 'user_nicename' => 'user-1' 'user_email' => 'user_2@example.org' + 'ID' => '2' + 'user_login' => 'test_author' + 'user_pass' => '$P$BUdMebxEjJ23.6LbH9ujvVUFBsUuZv/' + 'user_nicename' => 'test_author' + 'user_email' => 'user_1@example.org' 'user_url' => '' 'user_registered' => '2013-12-20 15:31:01' 'user_activation_key' => '' 'user_status' => '0' 'display_name' => 'User 1' + 'display_name' => 'test_author' ) 'ID' => 3 + 'ID' => 2 #dc4d - Automated Testing in WordPress with @ptahdunbar 'caps' => Array ( PHPUnit
  68. 68. FAIL There was 1 failure: 1) Tests_User_Author::test_get_the_author Failed asserting that two objects are equal. --- Expected +++ Actual @@ @@ WP_User Object ( 'data' => stdClass Object ( 'ID' => '3' 'user_login' => 'User 1' 'user_pass' => '$P$BpIqOzMNRGZNy9qxKL/3cCDCMe85o2.' 'user_nicename' => 'user-1' 'user_email' => 'user_2@example.org' + 'ID' => '2' + 'user_login' => 'test_author' + 'user_pass' => '$P$BUdMebxEjJ23.6LbH9ujvVUFBsUuZv/' + 'user_nicename' => 'test_author' + 'user_email' => 'user_1@example.org' 'user_url' => '' 'user_registered' => '2013-12-20 15:31:01' 'user_activation_key' => '' 'user_status' => '0' 'display_name' => 'User 1' + 'display_name' => 'test_author' ) 'ID' => 3 + 'ID' => 2 #dc4d - Automated Testing in WordPress with @ptahdunbar 'caps' => Array ( PHPUnit
  69. 69. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertTrue($user instanceof ‘LiveRacoonUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  70. 70. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertInstanceOf(‘LiveNinjaUserEntity’, $user); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  71. 71. ./vendor/bin/phpunit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; // Act $user = $service->persist($validUserdata); // Assert $this->assertInstanceOf(‘LiveNinjaUserEntity’, $user); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar PHPUnit
  72. 72. ./vendor/bin/phpunit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithValidUserdataReturnsUserObject() { // Arrange $service = new LiveNinjaUserService; $validUserdata = [...]; Time: 148ms, Memory: 2.75Mb // Act $user = $service->persist($validUserdata); OK: (1 test, 1 assertions) // Assert $this->assertInstanceOf(‘LiveNinjaUserEntity’, $user); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar PHPUnit
  73. 73. PHPUnit <?php class UserServiceTest extends PHPUnit_Framework_TestCase { public function testPersistWithInvalidUserdataReturnsWPError() { // Arrange $service = new LiveNinjaUserService; $invalidUserdata = []; // Act $user = $service->persist($invalidUserdata); // Assert $this->assertInstanceOf(‘WP_Error’, $user); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  74. 74. WordPress Testsuite
  75. 75. WordPress Testsuite WordPress with Tests http://develop.svn.wordpress.org/trunk/ 1858 Tests, 8611 Assertions, 2.59 minutes #dc4d - Automated Testing in WordPress with @ptahdunbar
  76. 76. WordPress Testsuite #dc4d - Automated Testing in WordPress with @ptahdunbar
  77. 77. #dc4d - Automated Testing in WordPress with @ptahdunbar
  78. 78. WordPress Testsuite #dc4d - Automated Testing in WordPress with @ptahdunbar
  79. 79. WordPress Testsuite Getting started #dc4d - Automated Testing in WordPress with @ptahdunbar
  80. 80. WordPress Testsuite <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="tests/bootstrap-wp.php"> <testsuites> <testsuite name="tests"> <directory suffix="Test.php">tests/</directory> </testsuite> </testsuites> </phpunit> #dc4d - Automated Testing in WordPress with @ptahdunbar
  81. 81. WordPress Testsuite <?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="tests/bootstrap-wp.php"> <testsuites> <testsuite name="tests"> <directory suffix="Test.php">tests/</directory> </testsuite> <testsuite name="integration"> <directory suffix="Test.php">integration/</directory> </testsuite> </testsuites> </phpunit> #dc4d - Automated Testing in WordPress with @ptahdunbar
  82. 82. WordPress Testsuite <?php class PluginTest extends PHPUnit_Framework_TestCase { // test cases... } plugin/tests/integration/PluginTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  83. 83. WordPress Testsuite <?php class PluginTest extends WP_UnitTestCase { // test cases... } plugin/tests/integration/PluginTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  84. 84. WordPress Testsuite $>./vendor/bin/phpunit #dc4d - Automated Testing in WordPress with @ptahdunbar
  85. 85. WordPress Testsuite Run Tests inside of an isolated WordPress Environment #dc4d - Automated Testing in WordPress with @ptahdunbar
  86. 86. WordPress Testsuite bootstrap.php Configure $GLOBALS['wp_tests_options'] = [ 'active_plugins' => [ 'hello.php', ... ], 'current_theme' => 'kubrick', ... ]; WordPress Options #dc4d - Automated Testing in WordPress with @ptahdunbar
  87. 87. WordPress Testsuite Configure bootstrap.php WordPress Includes function __muplugins_loaded() { // code and stuff. require_once 'env-debug.php'; } tests_add_filter('muplugins_loaded', '__muplugins_loaded'); #dc4d - Automated Testing in WordPress with @ptahdunbar
  88. 88. WordPress Testsuite ● Navigate to site URL (Updates globals) $this->get_url($url); ● Test WP_Query for Conditionals (is_page, is_single, is_404) $this->assertQueryTrue($arg1, $arg2, ...); ● Test for Errors $this->assertWPError($thing); ● Genereate WordPress data fixtures $this->factory->post->create_and_get(); $this->factory->comment->create_post_comments($pid, 100); $this->factory->user->create_many(5); $this->factory->blog->create(); and more… #dc4d - Automated Testing in WordPress with @ptahdunbar
  89. 89. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange // Act // Assert } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  90. 90. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange // Act // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  91. 91. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange $customWP = new WPCustomization; $this->factory->post->create(['post_date' => '2007-09-04 00:00:00']); // Act $customWP->deprecate_unused_pages(); $this->go_to('/2007/'); // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  92. 92. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange $customWP = new WPCustomization; $this->factory->post->create(['post_date' => '2007-09-04 00:00:00']); // Act $customWP->deprecate_unused_pages(); $this->go_to('/2007/'); // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  93. 93. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange $customWP = new WPCustomization; $this->factory->post->create(['post_date' => '2007-09-04 00:00:00']); // Act $customWP->deprecate_unused_pages(); $this->go_to('/2007/'); // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  94. 94. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange $customWP = new WPCustomization; $this->factory->post->create(['post_date' => '2007-09-04 00:00:00']); // Act $customWP->deprecate_unused_pages(); $this->go_to('/2007/'); // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  95. 95. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { // test cases function testRedirectForDateBasedPermalinks() { // Arrange $customWP = new WPCustomization; $this->factory->post->create(['post_date' => '2007-09-04 00:00:00']); Time: 148ms, Memory: 2.75Mb OK: (1// Act 1 assertions) test, $customWP->deprecate_unused_pages(); $this->go_to('/2007/'); // Assert $this->assertQueryTrue( 'is_404' ); } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  96. 96. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getRequiredPlugins */ function testAllRequiredPluginsAreActive($plugin) { // Assert $this->assertTrue( is_plugin_active($plugin), sprintf('%s is not activated.', $plugin) ); } function getRequiredPlugins() { return [ [‘hello.php’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  97. 97. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getRequiredPlugins */ function testAllRequiredPluginsAreActive($plugin) { // Assert $this->assertTrue( is_plugin_active($plugin), sprintf('%s is not activated.', $plugin) ); } function getRequiredPlugins() { return [ [‘hello.php’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  98. 98. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getRequiredPlugins */ function testAllRequiredPluginsAreActive($plugin) { // Assert $this->assertTrue( is_plugin_active($plugin), sprintf('%s is not activated.', $plugin) ); } function getRequiredPlugins() { return [ [‘hello.php’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  99. 99. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getRequiredPlugins */ function testAllRequiredPluginsAreActive($plugin) { // Assert $this->assertTrue( is_plugin_active($plugin), sprintf('%s is not activated.', $plugin) ); } Time: 148ms, Memory: 2.75Mb OK: (1 test, 1 assertions) function getRequiredPlugins() { return [ [‘hello.php’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  100. 100. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getWPOptions */ function testWPOptionSettingsAreConfigured($option_name, $option_value) { // Assert $this->assertSame($option_value, get_option($option_name)); } function getWPOptions() { return [ [‘home’, ‘http://example.org/wp/’], [‘siteurl’, ‘http://example.org/’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  101. 101. WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getWPOptions */ function testWPOptionSettingsAreConfigured($option_name, $option_value) { // Assert $this->assertSame($option_value, get_option($option_name)); } function getWPOptions() { return [ [‘home’, ‘http://example.org/wp/’], [‘siteurl’, ‘http://example.org/’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  102. 102. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getWPOptions */ function testWPOptionSettingsAreConfigured($option_name, $option_value) { // Assert $this->assertSame($option_value, get_option($option_name)); } function getWPOptions() { return [ [‘home’, ‘http://example.org/wp/’], [‘siteurl’, ‘http://example.org/’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  103. 103. ./vendor/bin/phpunit WordPress Testsuite <?php class WPCustomizationTest extends WP_UnitTestCase { /** * @dataProvider getWPOptions */ function testWPOptionSettingsAreConfigured($option_name, $option_value) { // Assert $this->assertSame($option_value, get_option($option_name)); } Time: 148ms, Memory: 2.75Mb OK: (1 test, 1 assertions) function getWPOptions() { return [ [‘home’, ‘http://example.org/wp/’], [‘siteurl’, ‘http://example.org/’], ]; } } plugin/tests/integration/WPCustomizationTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  104. 104. http://www.seleniumhq.org/ #dc4d - Automated Testing in WordPress with @ptahdunbar
  105. 105. Acceptance Testing <?php class ConnectTest extends PHPUnit_Framework_TestCase { protected function setUp() { } public function testUserCanLogInViaTwitter() { } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  106. 106. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { } public function testUserCanLogInViaTwitter() { } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  107. 107. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } public function testUserCanLogInViaTwitter() { } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  108. 108. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } public function testUserCanLogInViaTwitter() { $this->open("/"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  109. 109. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } public function testUserCanLogInViaTwitter() { $this->open("/"); $this->click("link=Log in"); $this->waitForPageToLoad("30000"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  110. 110. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } public function testUserCanLogInViaTwitter() { $this->open("/"); $this->click("link=Log in"); $this->waitForPageToLoad("30000"); $this->click("css=img[alt="Twitter"]"); $this->waitForPageToLoad("30000"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  111. 111. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } public function testUserCanLogInViaTwitter() { $this->open("/"); $this->click("link=Log in"); $this->waitForPageToLoad("30000"); $this->click("css=img[alt="Twitter"]"); $this->waitForPageToLoad("30000"); $this->assertContains( ‘dashboard’, $this->title() ); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  112. 112. Acceptance Testing <?php class ConnectTest extends PHPUnit_Extensions_Selenium2TestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("https://wpss.dev/"); } Time: 148ms, Memory: 2.75Mb public function testUserCanLogInViaTwitter() { $this->open("/"); $this->click("link=Log in"); $this->waitForPageToLoad("30000"); $this->click("css=img[alt="Twitter"]"); $this->waitForPageToLoad("30000"); $this->assertContains( ‘dashboard’, $this->title() ); } OK: (1 test, 1 assertions) } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  113. 113. Acceptance Selenium IDE Plugin ● Visually navigate throughout your site and generate a PHPUnit test case. ● Download Extension ○ http://www.seleniumhq. org/projects/ide/ ● Download PHPUnit Formatter ○ https://addons.mozilla.org/enUS/firefox/addon/seleniumide-php-formatters/ #dc4d - Automated Testing in WordPress with @ptahdunbar
  114. 114. Acceptance Selenium IDE Plugin ● Visually navigate throughout your site and generate a PHPUnit test case. ● Download Extension ○ http://www.seleniumhq. org/projects/ide/ ● Download PHPUnit Formatter ○ https://addons.mozilla.org/enUS/firefox/addon/seleniumide-php-formatters/ #dc4d - Automated Testing in WordPress with @ptahdunbar
  115. 115. How can we be confident that our tests cover everything? #dc4d - Automated Testing in WordPress with @ptahdunbar
  116. 116. Testing boundaries #dc4d - Automated Testing in WordPress with @ptahdunbar
  117. 117. Testing boundaries ● (User) Acceptance Testing ○ Verify that all features are done done. ○ Black-box testing, no knowledge of internals. #dc4d - Automated Testing in WordPress with @ptahdunbar
  118. 118. Testing boundaries ● (User) Acceptance Testing ○ ○ ● Verify that all features are done done. Black-box testing, no knowledge of internals. Integration Testing ○ Test WordPress settings/configuration; ○ Compatibility between plugins and themes. #dc4d - Automated Testing in WordPress with @ptahdunbar
  119. 119. Testing boundaries ● (User) Acceptance Testing ○ ○ ● Verify that all features are done done. Black-box testing, no knowledge of internals. Integration Testing ○ ○ ● Test WordPress settings/configuration, Compatibility between plugins and themes Unit Testing ○ Test class methods and functions in isolation, zero dependencies ○ Does one “behavoir” #dc4d - Automated Testing in WordPress with @ptahdunbar
  120. 120. Testing boundaries ● (User) Acceptance Testing Verify that all features are done done, black-box testing, no knowledge of Acceptance Testing internals ● Integration Testing Test WordPress settings/configuration, compatibility between plugins and Integration Testing themes ● Unit Testing Unit Testing Test class methods and functions in isolation, zero dependencies, does one “behavoir”. #dc4d - Automated Testing in WordPress with @ptahdunbar
  121. 121. Testing boundaries ● (User) Acceptance Testing Verify that all features are done done, black-box testing, no knowledge of Acceptance Testing internals ● Integration Testing Test WordPress settings/configuration, compatibility between plugins and Integration Testing themes ● Unit Testing Unit Testing Test class methods and functions in isolation, zero dependencies, does one “behavoir”. #dc4d - Automated Testing in WordPress with @ptahdunbar
  122. 122. Testing boundaries ● (User) Acceptance Testing Verify that all features are done done, black-box testing, no knowledge of Acceptance Testing internals ● Integration Testing Test WordPress settings/configuration, compatibility between plugins and Integration Testing themes ● Unit Testing Unit Testing Test class methods and functions in isolation, zero dependencies, does one “behavoir”. #dc4d - Automated Testing in WordPress with @ptahdunbar
  123. 123. What to tests? ● Test plugin works in various WordPress setups ○ Does it work under multisite? ○ What about a custom content directory? ● Test all code paths in functions and methods ● Test compatiblity between most popular plugins ● Test that default pages exists #ATWP // Automated Testing in WordPress // @ptahdunbar
  124. 124. What to tests? ● Test for theme support ● Test that post formats contain property elements ● Test any required assets that need to be loaded in templates ● Test for required elements on a page ● Verify search results template displays search term ● Verify SEO meta tags #ATWP // Automated Testing in WordPress // @ptahdunbar
  125. 125. What to not tests? 1. WordPress APIs #ATWP // Automated Testing in WordPress // @ptahdunbar
  126. 126. What to not tests? 1. WordPress APIs 2. PHP language features #ATWP // Automated Testing in WordPress // @ptahdunbar
  127. 127. What to not tests? 1. WordPress APIs 2. PHP language features 3. Third party vendor code #ATWP // Automated Testing in WordPress // @ptahdunbar
  128. 128. Getting into the groove #ATWP // Automated Testing in WordPress // @ptahdunbar
  129. 129. Getting into the groove ● Build out templates #ATWP // Automated Testing in WordPress // @ptahdunbar
  130. 130. Getting into the groove ● Build out templates ○ Create HTML/CSS #ATWP // Automated Testing in WordPress // @ptahdunbar
  131. 131. Getting into the groove ● Build out templates ○ Create HTML/CSS ○ Identify dynamic elements and their data structure #ATWP // Automated Testing in WordPress // @ptahdunbar
  132. 132. Getting into the groove ● Build out templates ○ Create HTML/CSS ○ Identify dynamic elements and their data structure ○ Label them and fill them with dummy data #ATWP // Automated Testing in WordPress // @ptahdunbar
  133. 133. Getting into the groove ○ Verbally state your trying to do #ATWP // Automated Testing in WordPress // @ptahdunbar
  134. 134. Getting into the groove ○ Verbally state your trying to do ○ Verbally explain what the code does #ATWP // Automated Testing in WordPress // @ptahdunbar
  135. 135. Getting into the groove ○ Verbally state your trying to do ○ Verbally explain what the code does ○ Do this alone or with a fellow dev :) #ATWP // Automated Testing in WordPress // @ptahdunbar
  136. 136. What’s Next?
  137. 137. Get started “A Walking Skeleton is a tiny implementation of the thinnest possible slice of real functionality that we can automatically build, deploy and test end-to-end.” ● Download WP Skeleton Family ○ https://github.com/ptahdunbar/wp-skeleton-site ○ https://github.com/ptahdunbar/wp-skeleton-plugin ○ https://github.com/ptahdunbar/wp-skeleton-theme #dc4d - Automated Testing in WordPress with @ptahdunbar
  138. 138. Resources ● Art of Unit Testing (.NET) ○ https://leanpub.com/u/royosherove ○ Udemy Five day course ● #GOOS Book (Java) ● XUnit Test Patterns (Java) ● Grumpy Books (PHP) ○ https://leanpub.com/u/chartjes ● Misko Hevery #dc4d - Automated Testing in WordPress with @ptahdunbar
  139. 139. Homework! TODO ● Learn moar PHPUnit features ○ data providers, ○ mocks and stubs ○ wordpress testsuite ● Goal: Write at least 100 assertions! #dc4d - Automated Testing in WordPress with @ptahdunbar
  140. 140. Automated Testing #dc4d - Automated Testing in WordPress with @ptahdunbar
  141. 141. Automated Testing increases your productivity #dc4d - Automated Testing in WordPress with @ptahdunbar
  142. 142. Automated Testing facilitates more shipping #dc4d - Automated Testing in WordPress with @ptahdunbar
  143. 143. Automated Testing scales with you #dc4d - Automated Testing in WordPress with @ptahdunbar
  144. 144. Automated Testing is your professional duty as a developer #dc4d - Automated Testing in WordPress with @ptahdunbar
  145. 145. Thank you Automated Testing in WordPress Pirate Dunbar @ptahdunbar yarr@piratedunbar.com Rate this talk: https://joind.in/10115 #dc4d - Automated Testing in WordPress with @ptahdunbar
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×