Upload
ptah-dunbar
View
9.309
Download
1
Tags:
Embed Size (px)
Citation preview
UNIT TESTINGlike a
cPirate
WordCamp Europe 2013
with
pirate dunbarSaturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
YES,I am a Pirate.
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
nAPP PlatformWordPress as a
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
nAPP PlatformWordPress as a
Video chat marketplace for experts to monetize
their know-how.
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
nAPP PlatformWordPress as a
“I think WordPress is going in a direction that isn’t well framed or
described by any existing alternatives or historical platforms.”
— Matt Mullenweghttp://jakegoldman.me/2013/09/wordpress-app-platform/
Saturday, October 5, 13
“Plugins represent the heartbeat ofWordPress.”
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
• sdsdsd
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
“The result is that a lot of the plugins are written in poor code
and turn out to be poorly compatible with other plugins.”
— Yoasthttp://yoast.com/plugin-future/
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Manual Testing
Saturday, October 5, 13
• sdsdsd
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Problems of manual testing
1. Ad-hoc ☹
Saturday, October 5, 13
• sdsdsd
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Problems of manual testing
1. Ad-hoc ☹2. Slow & Error Prone ☹
Saturday, October 5, 13
• sdsdsd
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Problems of manual testing
1. Ad-hoc ☹2. Slow & Error Prone ☹3. High risk that I missed something ☹
Saturday, October 5, 13
• sdsdsd
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what we need
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what we need
• Fast & Instant feedback
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what we need
• Fast & Instant feedback
• Reusable and organized
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what we need
• Fast & Instant feedback
• Reusable and organized
• Verify that I didn’t break anything.
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
Unit Testing Series
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
Unit Testing Series
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
1. Unit Testing like a Pirate
2. Buccaneering the high seas with PHPUnit
3. Mo’ plugins mo’ problems
4. Steering clear of wreckages and skulls
5. Avast! TDD for sailors and salty dogs
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is unit testing
“An automated piece of code that invokes your application code to
check a single assumption.”
— Pirate Dunbar
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is unit testing
“Separatingthe application
design & implementation
process.”
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
“A command line tool that runs unit tests & reports their results.”
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
$>phpunit
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
Time: 1 sec, Memory: 8.75Mb
OK (200 tests, 355 assertions)
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
There was 1 failure:
1) WPSkeletonPluginTest\AutoloadTest::testThatItsTestingTime
What time is it? - it's testing time! :D
/Users/ptah/Sites/wp.t/public/content/mu-plugins/wp-skeleton-plugin/tests/WPSkeletonPluginTest/AutoloadTest.php:9
FAILURES!
Tests: 2, Assertions: 1, Failures: 1.
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
Test Casea set of conditions or variables that you set up in order to assert an expected outcome.
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
what is PHPUNIT
Test SUITEA collection of test cases.
Saturday, October 5, 13
<?php
class SubscriptionTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testHasAccessWithPassDueCustomerBlocksAccess()
{
// AAA
}
public function testAddSubscriptionWithInvalidCustIdReturnsWPError()
{
// AAA
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Assertions“a way of explicitly checking the
assumptions that your code makes”
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
n• $this->assertTrue();
• $this->assertEquals();
• $this->assertContains();
• $this->assertGreaterThan();
• $this->assertNotNull();
• $this->assertFalse();
• $this->assertNotEquals();
• $this->assertContainsOnly();
• $this->assertLessThan();
• $this->assertType();
Assertions Appendix:http://phpunit.de/manual/3.7/en/appendixes.assertions.html
common Assertions
Saturday, October 5, 13
“How do I actually write out the test cases?”
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
http://www.flickr.com/photos/mutsmuts/4695658106
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Anatomy of a test case
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Anatomy of a test case
1. a
2. A
3. A
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Anatomy of a test case
1. A
2. A
3. Assert (check for the expected value)
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Anatomy of a test case
1. A
2. Act (call the method/trigger the action)
3. Assert (check for the expected value)
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Anatomy of a test case
1. arrange (the context)
2. Act (call the method/trigger the action)
3. Assert (check for the expected value)
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
// Act
// Assert
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
int Calculator::add(int $a, int $b);
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
// Act
// Assert
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
// Act
// Assert
$this->assertEquals(3, $result);
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
// Act
$result = $calculator->add($a, $b);
// Assert
$this->assertEquals(3, $result);
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
$calculator = new Calculator();
$a = 1;
$b = 2;
// Act
$result = $calculator->add($a, $b);
// Assert
$this->assertEquals(3, $result);
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?phpclass CalculatorTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testAddReturnsSumOfTwoPositiveIntegers()
{
// Arrange
$calculator = new Calculator();
$a = 1;
$b = 2;
// Act
$result = $calculator->add($a, $b);
// Assert
$this->assertEquals(3, $result);
}
}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Time: 148 ms, Memory: 2.75Mb
OK (1 test, 1 assertions)
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
bool Cache::set(string $key);
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange
// Act
// Assert$this->assertSame( [ 1, 2, 3 ], $cache->get(‘user_ids’) );
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange
// Act$cache->add(‘user_ids’, [ 1, 2, 3 ]);
// Assert$this->assertSame( [ 1, 2, 3 ], $cache->get(‘user_ids’) );
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange$cache = new \LiveNinja\Storage\Cache();
// Act$cache->add(‘user_ids’, [ 1, 2, 3 ]);
// Assert$this->assertSame( [ 1, 2, 3 ], $cache->get(‘user_ids’) );
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class LiveNinjaCacheTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testSetWithNewDataPersistsToCache(){
// Arrange$cache = new \LiveNinja\Storage\Cache();
// Act$cache->add(‘user_ids’, [ 1, 2, 3 ]);
// Assert$this->assertSame( [ 1, 2, 3 ], $cache->get(‘user_ids’) );
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Time: 125 ms, Memory: 2.35Mb
OK (1 test, 1 assertions)
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
object|WP_Error User\Service::persist(User $user);
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange
// Act
// Assert$this->assertInstanceOf(‘WP_Error’, $user);
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange
// Act$user = $service->persist($inCompleteUserObject);
// Assert$this->assertInstanceOf(‘WP_Error’, $user);
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange$service = new \LiveNinja\User\Service;$inCompleteUserObject = new \LiveNinja\User\Entity(...);
// Act$user = $service->persist($inCompleteUserObject);
// Assert$this->assertInstanceOf(‘WP_Error’, $user);
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testPersistReturnsWPErrorIfItDoesntContainRequiredFields(){
// Arrange$service = new \LiveNinja\User\Service;$inCompleteUserObject = new \LiveNinja\User\Entity(...);
// Act$user = $service->persist($inCompleteUserObject);
// Assert$this->assertInstanceOf(‘WP_Error’, $user);
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Time: 85 ms, Memory: 1.25Mb
OK (1 test, 1 assertions)
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
array|WP_Error User\Service::get_ninjas(array $args);
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange
// Act
// Assert
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange
// Act
// Assert$this->assertContains($expected, $service->getLastResultAsSQL());
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange
// Act$service->get_ninjas([‘plan’ => ‘blackbelt’]);
// Assert$this->assertContains($expected, $service->getLastResultAsSQL());
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange$expected = “SELECT * FROM ninjas WHERE ...”;$service = new \LiveNinja\User\Service;
// Act$service->get_ninjas([‘plan’ => ‘blackbelt’]);
// Assert$this->assertSame($expected, $service->getLastResultAsSQL());
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Saturday, October 5, 13
<?php
class UserServiceTest extends PHPUnit_Framework_TestCase{
// test cases ...
public function testGetNinjasWithBlackBeltSubscriptionQuery(){
// Arrange$expected = “SELECT * FROM ninjas WHERE ...”;$service = new \LiveNinja\User\Service;
// Act$service->get_ninjas([‘plan’ => ‘blackbelt’]);
// Assert$this->assertContains($expected, $service->getLastResultAsSQL());
}}
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Time: 101 ms, Memory: 1.55Mb
OK (1 test, 1 assertions)
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
nWAYS TO TEST CODE
• test if/else conditionals
• test all cases in switch
• verify loops contain proper data.
• Check for expected state
• Check return value type
• Pass unexpected data
• Verify correct amount
• assertContains for SQL Queries
• Verify that third party method was called.
• $this->assertType();
• etc...
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
nWAYS TO kickstart your brain
• write out list of requirements for each feature
• do the UI first
Saturday, October 5, 13
cwp skeleton plugin
https://github.com/ptahdunbar/wp-skeleton-plugin/
Saturday, October 5, 13
UNIT TESTING like A PIRATE — @ptahdunbar #wceu
Thank you!
Slides - http://ptahdunbar.com/
cPirate Dunbar
Saturday, October 5, 13