$30 off During Our Annual Pro Sale. View Details »

Unit Testing WordPress Plugins

Bryan Petty
January 29, 2014

Unit Testing WordPress Plugins

With such a wide matrix of WordPress versions, browsers, and plugin combinations out there, it can be a daunting task releasing your own plugin with highly forgiving compatibility requirements. In this presentation, I will demonstrate how you can write your plugins to support more users than you thought possible using automated unit tests while feeling confident that your new plugin changes didn’t break your other features or even WordPress itself.

Bryan Petty

January 29, 2014
Tweet

More Decks by Bryan Petty

Other Decks in Technology

Transcript

  1. Unit Testing WordPress Plugins Bryan Petty bpetty@bluehost.com github.com/tierra @ibakunet

  2. • Unit tests are tests that verify that your smallest

    pieces of code ("units") in your plugin work as they were intended to. • Unit tests are fast. • Unit tests are reliable. • Unit tests are flexible. What are Unit Tests?
  3. • Detect Problems Early • More Flexible Code • Faster

    Release Cycles • Living Code Specifications • Backwards Compatibility The Benefits of Automated Testing
  4. WordPress Core Unit Testing Framework

  5. • Built on PHPUnit • Develop Code Repository ◦ http://develop.svn.wordpress.org/

    • 1,918 Tests Currently • See the Core Contributor Handbook: ◦ make.wordpress.org/core/handbook/automated-testing Core Tests Architecture
  6. class Tests_Tests extends WP_UnitTestCase { function test_tests() { $this->assertTrue( true

    ); } } • MySQL Transactions • Automatically Flushes the Object Cache • Clears Form Data • Skips Tests Marked with Open Tickets WP_UnitTestCase
  7. • Quickly create test posts, comments, users, terms, categories, and

    even entire blogs. $this->factory->post->create_many( 25 ); $this->factory->post->create( array( 'post_type' => 'page' ) ); $this->factory->user->create( array( 'role' => 'author' ) ); $this->factory->blog->create_many( 5 ); $this->factory->term->create( array( 'taxonomy' => 'category' ) ); Another Day at the Factory
  8. • Fake AJAX requests without performing an external HTTP request.

    $_POST['_ajax_nonce'] = wp_create_nonce( 'get-comments' ); $_POST['action'] = 'get-comments'; $_POST['p'] = $this->_comment_post->ID; // Make the request try { $this->_handleAjax( 'get-comments' ); } catch ( WPAjaxDieContinueException $e ) { unset( $e ); } // Get the response $response = $this->_last_response; WP_Ajax_UnitTestCase
  9. Testing Your Plugin

  10. github.com/tierra/wordpress-plugin-tests WordPress Plugin Test Code • Copy .travis.yml, phpunit. xml.dist,

    and the tests directory into the root folder of your plugin. • Open tests/bootstrap.php and update the active_plugins setting to point to your main plugin file.
  11. • Update the bootstrap.php file with the location of your

    plugin. $GLOBALS['wp_tests_options'] = array( 'active_plugins' => array( 'your-plugin-slug/your-main-plugin-file.php' ), ); • Example Plugin: WP Slider Captcha ◦ github.com/tierra/WP-Slider-Captcha Setup Your Plugin with WP Tests
  12. $ cd wordpress/src/wp-content/plugins/WP-Slider-Captcha $ phpunit Running as single site... To

    run multisite, use -c multisite.xml Not running ajax tests... To execute these, use --group ajax. PHPUnit 3.6.11 by Sebastian Bergmann. Configuration read from phpunit.xml .S. Time: 1 second, Memory: 41.00Mb OK, but incomplete or skipped tests! Tests: 3, Assertions: 2, Skipped: 1. Run the Tests!
  13. Writing Unit Tests

  14. class WP_Test_WP_Slider_Captcha extends WP_UnitTestCase { function test_init_hook_was_added() { $this->assertGreaterThan( 0,

    has_filter( 'init', 'wpsc_scripts' ) ); } } test_wp_slider_captcha.php
  15. function test_threshold_sanitize_less_than_one() { $this->assertEquals( 60, wpsc_threshold_sanitize( 0 ) ); }

    function test_threshold_sanitize_more_than_100() { $this->assertEquals( 60, wpsc_threshold_sanitize( 101 ) ); } function test_threshold_sanitize_non_number() { $this->assertEquals( 0, wpsc_threshold_sanitize( 'I am a string' ) ); } function test_threshold_sanitize_valid_number() { $this->assertEquals( 40, wpsc_threshold_sanitize( 40 ) ); } test_wp_slider_captcha.php
  16. Covering All Your Bases

  17. The WordPress core unit tests can be easily configured to

    run with your plugin activated by adding this code to the beginning of wordpress/tests/phpunit/includes/bootstrap.php: $GLOBALS['wp_tests_options'] = array( 'active_plugins' => array( "WP_Slider_Captcha/wp-slider-captcha.php" ), ); Does Your Plugin Break Anything in WordPress Itself?
  18. Configure Travis CI for Truly Automated Tests

  19. Copy .travis.yml to the root of your plugin, activate Travis

    CI with your GitHub repo, then push the changes to your plugin on GitHub. Travis CI Settings # Tell Travis CI we're using PHP language: php php: - "5.5" env: - WP_VERSION=master matrix: include: - php: "5.3" env: WP_VERSION=master - php: "5.4" env: WP_VERSION=3.8 - php: "5.2" env: WP_VERSION=3.8
  20. None
  21. wordpress.tv/speakers/aaron-jorbin Write Javascript Unit Tests with QUnit

  22. wordpress.tv/speakers/nikolay-bachiyski Another Unit Testing Example

  23. Questions speakerdeck.com/u/tierra Bryan Petty bpetty@bluehost.com github.com/tierra @ibakunet