SlideShare a Scribd company logo
1 of 146
Download to read offline
Automated Testing in

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

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
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
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
“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
Fail.
Manual Testing

Pull out the tools
●
●
●
●
●

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

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
#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
results.

#dc4d - Automated Testing in WordPress with @ptahdunbar
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

Continuous Inspection
Releasing early, releasing often
#dc4d - Automated Testing in WordPress with @ptahdunbar
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 @ptahdunbar
{
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/phpunit-selenium" : "*",
}
}

http://getcomposer.org

vim composer.json && composer update

#dc4d - Automated Testing in WordPress with @ptahdunbar
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 - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
PHPUnit
plugin/
loader.php
includes/
admin.php
api.php
…
phpunit.xml
tests/
adminTest.php
ApiTest.php
…
…

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit
plugin/
loader.php
includes/
admin.php
functions.php
…
phpunit.xml
tests/
integration/
…
acceptance/
…
…

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
PHPUnit

Assertions
Explicitly check expected outcome
agaisnt actual outcome.

#dc4d - Automated Testing in WordPress with @ptahdunbar
PHPUnit

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

#dc4d - Automated Testing in WordPress with @ptahdunbar
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 Testing in WordPress with @ptahdunbar
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
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
PHPUnit

Example

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
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
./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
./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
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
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
./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
./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
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
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
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
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
./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
./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
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
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
./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
./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
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
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
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
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
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
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
./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
./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
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
WordPress Testsuite
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
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>
<testsuite name="tests">
<directory suffix="Test.php">tests/</directory>
</testsuite>
</testsuites>
</phpunit>

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
WordPress Testsuite

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

plugin/tests/integration/PluginTest.php

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

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

plugin/tests/integration/PluginTest.php

#dc4d - Automated Testing in WordPress with @ptahdunbar
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 @ptahdunbar
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
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
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
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
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
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
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
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
./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
./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
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
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
./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
./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
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
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
./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
./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
http://www.seleniumhq.org/

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
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
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
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
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
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
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
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 knowledge of internals.

#dc4d - Automated Testing in WordPress with @ptahdunbar
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
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
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
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
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
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
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
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 WordPress // @ptahdunbar
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

#ATWP // Automated Testing in WordPress // @ptahdunbar
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
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 Testing in WordPress // @ptahdunbar
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
What’s Next?
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
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
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
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/10115

#dc4d - Automated Testing in WordPress with @ptahdunbar

More Related Content

Viewers also liked

Viewers also liked (20)

品質アップ、30分でできる簡単テストから始めよう for WordPress
品質アップ、30分でできる簡単テストから始めよう for WordPress品質アップ、30分でできる簡単テストから始めよう for WordPress
品質アップ、30分でできる簡単テストから始めよう for WordPress
 
Breaking social barriers and creating opportunities
Breaking social barriers and creating opportunitiesBreaking social barriers and creating opportunities
Breaking social barriers and creating opportunities
 
chapters
chapterschapters
chapters
 
IPC 2013 - High Performance PHP with HipHop
IPC 2013 - High Performance PHP with HipHopIPC 2013 - High Performance PHP with HipHop
IPC 2013 - High Performance PHP with HipHop
 
PHPUnit
PHPUnitPHPUnit
PHPUnit
 
WordBench京都9月号
WordBench京都9月号WordBench京都9月号
WordBench京都9月号
 
PHP Unit y TDD
PHP Unit y TDDPHP Unit y TDD
PHP Unit y TDD
 
Automated php unit testing in drupal 8
Automated php unit testing in drupal 8Automated php unit testing in drupal 8
Automated php unit testing in drupal 8
 
Help Me, I got a team of junior testers!
Help Me, I got a team of junior testers!Help Me, I got a team of junior testers!
Help Me, I got a team of junior testers!
 
PHPUnit with CakePHP and Yii
PHPUnit with CakePHP and YiiPHPUnit with CakePHP and Yii
PHPUnit with CakePHP and Yii
 
WordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオンWordBench京都 9月号:kintone×WordPressハンズオン
WordBench京都 9月号:kintone×WordPressハンズオン
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
8 Ways to Hack a WordPress website
8 Ways to Hack a WordPress website8 Ways to Hack a WordPress website
8 Ways to Hack a WordPress website
 
10 signs your testing is not enough
10 signs your testing is not enough10 signs your testing is not enough
10 signs your testing is not enough
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 
How to reduce your test cases... magically!
How to reduce your test cases... magically!How to reduce your test cases... magically!
How to reduce your test cases... magically!
 
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LTGazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
Gazelle & CPAN modules for performance. Shibuya.pm Tech Talk #17 LT
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Mackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LTMackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LT
 
Why vREST?
Why vREST?Why vREST?
Why vREST?
 

Similar to Automated Testing in WordPress, Really?!

Continuous integration with Git & CI Joe
Continuous integration with Git & CI JoeContinuous integration with Git & CI Joe
Continuous integration with Git & CI Joe
Shawn Price
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 

Similar to Automated Testing in WordPress, Really?! (20)

Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
 
Test
TestTest
Test
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
 
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
 
Continuous integration with Git & CI Joe
Continuous integration with Git & CI JoeContinuous integration with Git & CI Joe
Continuous integration with Git & CI Joe
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
 
Frida Android run time hooking - Bhargav Gajera & Vitthal Shinde
Frida  Android run time hooking - Bhargav Gajera & Vitthal ShindeFrida  Android run time hooking - Bhargav Gajera & Vitthal Shinde
Frida Android run time hooking - Bhargav Gajera & Vitthal Shinde
 
Php Debugger
Php DebuggerPhp Debugger
Php Debugger
 
PHPVigo #26 - Lightning Docker phpUnit
PHPVigo #26 - Lightning Docker phpUnitPHPVigo #26 - Lightning Docker phpUnit
PHPVigo #26 - Lightning Docker phpUnit
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Developers, Be a Bada$$ with WP-CLI
Developers, Be a Bada$$ with WP-CLIDevelopers, Be a Bada$$ with WP-CLI
Developers, Be a Bada$$ with WP-CLI
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsEffizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
 
Plugin development demystified 2017
Plugin development demystified 2017Plugin development demystified 2017
Plugin development demystified 2017
 

More from Ptah Dunbar (6)

Unit testing like a pirate #wceu 2013
Unit testing like a pirate #wceu 2013Unit testing like a pirate #wceu 2013
Unit testing like a pirate #wceu 2013
 
Wcphx 2012-workshop
Wcphx 2012-workshopWcphx 2012-workshop
Wcphx 2012-workshop
 
@wcmtl
@wcmtl@wcmtl
@wcmtl
 
wcmia2011
wcmia2011wcmia2011
wcmia2011
 
WordCamp MSP 2010
WordCamp MSP 2010WordCamp MSP 2010
WordCamp MSP 2010
 
WordCamp Miami 09 - WP Framework
WordCamp Miami 09 - WP FrameworkWordCamp Miami 09 - WP Framework
WordCamp Miami 09 - WP Framework
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Automated Testing in WordPress, Really?!

  • 1. Automated Testing in WordPress, Really?! Rate this talk: https://joind.in/10115 #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 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. 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. 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. 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. 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
  • 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.
  • 10. Fail.
  • 11. Manual Testing Pull out the tools ● ● ● ● ● WP_DEBUG var_dump(); print_r(); error_log(); debug_backtrace(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 16. 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
  • 17. Automated Testing Persistent var_dumps(); #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 18. Automated Testing Better than checking the logs #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 19. 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
  • 20. Automate Testing Getting started #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 21. CHOOSE YOUR FRAMEWORK There are so many Frameworks #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 22. CHOOSE YOUR FRAMEWORK PHPUnit http://phpunit.de/manual/ Sebastian Bergmann #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 23. { "require-dev": { "phpunit/phpunit": "3.7.*", "phpunit/phpunit-selenium" : "*", } } http://getcomposer.org vim composer.json && composer update #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 24. PHPUnit $>./vendor/bin/phpunit #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 25. PHPUnit Terminology #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 26. 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
  • 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 #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 28. 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
  • 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. 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
  • 33. 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
  • 34. 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
  • 35. 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
  • 36. 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
  • 37. PHPUnit Assertions Explicitly check expected outcome agaisnt actual outcome. #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 38. PHPUnit Assertions Explicitly check expected outcome agaisnt actual outcome. $this->assertTrue(condition); #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 39. PHPUnit Arrange, Act, Assert #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 40. PHPUnit function testThatItsTestingTime() { 1. A 2. A 3. A } #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 41. PHPUnit function testThatItsTestingTime() { 1. A 2. A 3. Assert (check for the expected behavior) } #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 42. 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
  • 43. 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
  • 44. PHPUnit Example #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 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. 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
  • 47. 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
  • 48. 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
  • 49. 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. ./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
  • 51. ./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
  • 52. 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
  • 53. 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. ./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
  • 55. ./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
  • 56. 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
  • 57. 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
  • 58. 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
  • 59. 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. ./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
  • 61. ./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
  • 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 ‘LiveNinjaUserEntity’); } //… } plugin/tests/unit/LiveNinja/User/ServiceTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 63. 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. ./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
  • 65. ./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
  • 66. 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
  • 67. 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
  • 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. 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
  • 70. 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
  • 71. 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
  • 72. ./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
  • 73. ./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
  • 74. 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
  • 76. 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
  • 77. WordPress Testsuite #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 78. #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 79. WordPress Testsuite #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 80. WordPress Testsuite Getting started #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 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> </testsuites> </phpunit> #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 82. 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
  • 83. WordPress Testsuite <?php class PluginTest extends PHPUnit_Framework_TestCase { // test cases... } plugin/tests/integration/PluginTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 84. WordPress Testsuite <?php class PluginTest extends WP_UnitTestCase { // test cases... } plugin/tests/integration/PluginTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 85. WordPress Testsuite $>./vendor/bin/phpunit #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 86. WordPress Testsuite Run Tests inside of an isolated WordPress Environment #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 87. 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
  • 88. 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
  • 89. 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
  • 90. 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
  • 91. 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
  • 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. 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. 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. ./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
  • 96. ./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
  • 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. 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. ./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
  • 100. ./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
  • 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. 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. ./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
  • 104. ./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
  • 105. http://www.seleniumhq.org/ #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 106. 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
  • 107. 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
  • 108. 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
  • 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("/"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 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"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 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"); } } plugin/tests/acceptance/ConnectTest.php #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 112. 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
  • 113. 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
  • 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. 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
  • 116. How can we be confident that our tests cover everything? #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 117. Testing boundaries #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 118. 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
  • 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. #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 120. 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
  • 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. 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. 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
  • 124. 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
  • 125. 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
  • 126. What to not tests? 1. WordPress APIs #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 127. What to not tests? 1. WordPress APIs 2. PHP language features #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 128. What to not tests? 1. WordPress APIs 2. PHP language features 3. Third party vendor code #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 129. Getting into the groove #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 130. Getting into the groove ● Build out templates #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 131. Getting into the groove ● Build out templates ○ Create HTML/CSS #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 132. Getting into the groove ● Build out templates ○ Create HTML/CSS ○ Identify dynamic elements and their data structure #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 133. 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
  • 134. Getting into the groove ○ Verbally state your trying to do #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 135. Getting into the groove ○ Verbally state your trying to do ○ Verbally explain what the code does #ATWP // Automated Testing in WordPress // @ptahdunbar
  • 136. 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
  • 138. 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
  • 139. 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
  • 140. 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
  • 141. Automated Testing #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 142. Automated Testing increases your productivity #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 143. Automated Testing facilitates more shipping #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 144. Automated Testing scales with you #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 145. Automated Testing is your professional duty as a developer #dc4d - Automated Testing in WordPress with @ptahdunbar
  • 146. 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