Upload
deck36
View
654
Download
1
Embed Size (px)
DESCRIPTION
Introduction: How to use Unit Testing (TDD) and Behaviour Testing (BDD) for Wordpress, building a Continuous Integration workflow.
Citation preview
About DECK36
• Small team of 7 engineers• Longstanding expertise in designing, implementing and operatingcomplex web systems
• Developing own data intelligence-focused tools and web services• Offering our expert knowledge in Automation & Operation,Architecture & Engineering, Analytics & Data Logistics
1. Dev & Test Environments
2. Testing VariantsStatic Code AnalysisUnit TestingIntegration TestingBehaviour Testing
3. Integration & Automation
Main Questions
How can I know (my) software is correct?
How does my boss know software is correct?
How do I know software implements a given design?
How can we discuss what “correct” is, anyway?
We always need:• implicit assumptions,• explicit specifications.
Levels of Testing
..
abstract
.
specific
.
Unit Tests
.
Integration Tests
.
AcceptanceTests
Example Plugin: Freifunkmeta
Use a DevEnvironment
Vagrant
Configuration tool for (VirtualBox) VMsetup and provisioning.
“Local cloud”• Self service• Instant provisioning
Useful for development• reproducible environment• independent PHP 5.x setups• try things and not jeopardiseyour dev environment
VagrantPress
$ git clone https://github.com/chad-thompson/vagrantpress.git$ cd vagrantpress$ vagrant up
will setup VM with:
• Ubuntu Precise (12.04), Apache 2.2, MySQL 5.5, PHP 5.3• Wordpress 3.8• phpMyAdmin• PHPUnit• phpcs, phploc, phpdepend, …
Testing Variants
Coding Style
$ phpcs --standard=WordPress freifunkmeta.php
FILE: [...]/plugins/freifunkmeta/freifunkmeta.php---------------------------------------------------------------------FOUND 360 ERROR(S) AND 406 WARNING(S) AFFECTING 338 LINE(S)---------------------------------------------------------------------
21 | ERROR | Incorrect indentation; expected 1 space, found 422 | WARNING | Line is indented with space not tab33 | ERROR | String "Unable to retrieve URL %s, error: %s" does
| | not require double quotes; use single quotes instead322 | ERROR | Closing parenthesis of a multi-line function
| | definition must be on a line by itself440 | ERROR | Expected next thing to be a escaping function,
| | not '"<option value='$city' $selected>$prettycity| | </option>"'
Code Metrics
$ php pdepend_summary.php freifunkmeta.php
Package/Class Method LoC %Comment CCN NPath------------- ------ --- -------- --- -----FF_Meta output_ff_contact 49 6.1 10 384FF_Meta shortcode_handler 41 2.4 9 48FF_Community __construct 12 0.0 7 15625FF_Meta register_stuff 18 0.0 5 16FF_Meta aux_get_all_locations 23 8.7 5 6FF_Community make_from_city 15 0.0 4 20[...]
Example Plugin: Freifunkmeta
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
Unit Testing
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
Simple PHPUnit Test Case
class LowLevelTests extends PHPUnit_Framework_TestCase {function setUp() {
$this->FFM = new FF_Meta();}
function test_output_ff_state() {$data = array("state" => array("nodes" => 429));$ret = $this->FFM->output_ff_state($data);$this->assertRegExp('/429/', $ret);
}}
Unit Testing (contd.)
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
Integration Testing
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
Unit Testing with Mock Object
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
Example: Test with Dependency Injection
class MockDataService {function get($url) {
return $some_fixed_data;}
}
class WpIntegrationTests extends WP_UnitTestCase {function setUp() {
parent::setUp();// get plugin instance and replace ext. data service:$this->plugin = $GLOBALS['wp-plugin-ffmeta'];$this->plugin->reset_external_data_service(
new MockDataService() );}
// ...
Example: Test with Dependency Injection
// ...function test_post_ff_services() {
$post_attribs = array('post_title' => 'Test','post_content' => '[ff_services]' );
$post = $this->factory->post->create_and_get($post_attribs );
// w/o filter:$this->assertEquals($post_content, $post->post_content);
// with filter:$output = apply_filters( 'the_content',
$post->post_content );$this->assertRegExp('/radio\.ffhh/', $output);
}}
PHPUnit Output
Behaviour Testing
..WP Blog.
FF_Meta
.
WP Core
.
Other Plugins
.
FF_Community
.
FF_Dir
.
OutputFormatter
.
HTTP GetService
WordPress Shortcode Plugin Test..
Feature: Use ShortcodesIn order to use my PluginAs a website authorI need to write posts with shortcodes
Background:Given I am logged in as "admin" with "vagrant"
Scenario: Without the pluginGiven the plugin "freifunkmeta" is "inactive"When I write a post with title "test" and content "[ff_contact]"Then I should see "ff_contact"
Scenario: With the pluginGiven the plugin "freifunkmeta" is "active"When I write a post with title "test" and content "[ff_contact]"Then I should see "Twitter" in the ".ff_contact" elementAnd I should not see "ff_contact"
Behat Output
Implementation / Translation
A look behind the curtain:• framework is clever but not magical• some translation needed• statements have to become executable code
Mechanism:• plain sentence → method name• quoted words → arguments• matching with annotated regular expressions• methods yield success, exception, or pending exception
Example: Behat Context (PHP)
/*** from MinkContext* Checks, that page contains specified text.** @Then /^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/*/
public function assertPageContainsText($text){
$this->assertSession()->pageTextContains($this->fixStepArgument($text));
}
The Big Picture
..Features.
Step Definitions
.
WebDriver
.
Browser
The Big Picture
..Features.
Behat (PHP)
.
cucumber.js
.
Cucumber(Ruby)
.
PhantomJS
.
Goutte
.
Selenium
.
Firefox
.
Chrome
Unit & Behaviour Testing
Unit Tests• unit testing• programmers• programming language• bottom-up• assertXYZ• tests derived from user stories
⇒ development tool
Behaviour Tests• acceptance test scenarios• non-developers• language of business domain• top-down / outside-in• X should do Y• execute user stories
⇒ design & communication tool
Automate!
Scripting
Basis for all automation.Lots of useful builtins and packages:
• wp core download/install/config/…• wp export/import• wp plugin get/install/update/…• wp scaffold _s/plugin/plugin-tests• wp server
wp scaffold
Generate skeleton code for a new plugin & unit tests:
$ cd wordpress/wp-content/plugins$ wp scaffold plugin-tests awesome$ find awesomeawesome/awesome/awesome.phpawesome/binawesome/bin/install-wp-tests.shawesome/testsawesome/tests/bootstrap.phpawesome/tests/test-sample.phpawesome/.travis.ymlawesome/phpunit.xml
wp scaffold (contd.)
Create WP instance and run unit tests:$ cd awesome$ bash ./bin/install-wp-tests.sh wp_tests root vagrant latest...$ phpunitPHPUnit 4.0.17 by Sebastian Bergmann.[...]
Configuration read from [...]/plugins/awesome/phpunit.xml
.
Time: 5.52 seconds, Memory: 23.50Mb
OK (1 test, 1 assertion)
Version Control
• use version control!• many possible workflows,e. g. branches for dev and release
• use pre-commit hooks,e. g. with php -l syntax check
Travis-CI
Continuous Integration service for GitHub1. gets notified on push
2. builds project
3. runs phpunit
4. summarizes results,alert on failure
Example .travis.yml
language: php
php:- 5.4- 5.5- hhvm
env:- WP_VERSION=3.8.3- WP_VERSION=latest
before_script:- bash bin/install-wp-tests.sh wordpress_test \
root '' localhost $WP_VERSION
script: phpunit
Travis-CI Pass
Automated Testing
Target: no manual effort.
Continuous Integration:• frequent code check-ins• verified by automatedbuilds and tests
• quickly find bugsand regressions
Continuous Deployment:• (semi-)automated deployment• plan for rollback
Costs and Benefits of Testing
• Testing (like Documentation) has a cost• usually: productivity improvement > cost• but find the right balance
Conclusion
I get paid for code that works, not for tests, so my philosophy is to testas little as possible to reach a given level of confidence.
– Kent Beck
Links
• http://phpqatools.org/: PHP Quality Assurance Toolchain• http://wpgear.org/: compendium of useful WP developer tools• http://wptest.io/: test data for WP plugins and themes
• Ptah Dunbar: Automated Testing in WordPress, Really?!• tuts+ articles by Tom McFarlin• Conversation “Is TDD Dead?”
Thank You