Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Upcoming SlideShare
Loading in...5
×
 

Effizientere WordPress-Plugin-Entwicklung mit Softwaretests

on

  • 552 views

Introduction: How to use Unit Testing (TDD) and Behaviour Testing (BDD) for Wordpress, building a Continuous Integration workflow.

Introduction: How to use Unit Testing (TDD) and Behaviour Testing (BDD) for Wordpress, building a Continuous Integration workflow.

Statistics

Views

Total Views
552
Views on SlideShare
543
Embed Views
9

Actions

Likes
0
Downloads
2
Comments
0

1 Embed 9

https://twitter.com 9

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Effizientere WordPress-Plugin-Entwicklung mit Softwaretests Effizientere WordPress-Plugin-Entwicklung mit Softwaretests Presentation Transcript

  • Effizientere WordPress-Plugin-Entwicklung mit Softwaretests Martin Schütte
  • About DECK36 • Small team of 7 engineers • Longstanding expertise in designing, implementing and operating complex 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 Variants Static Code Analysis Unit Testing Integration Testing Behaviour 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 . Acceptance Tests
  • Example Plugin: Freifunkmeta
  • Use a Dev Environment
  • Vagrant Configuration tool for (VirtualBox) VM setup and provisioning. “Local cloud” • Self service • Instant provisioning Useful for development • reproducible environment • independent PHP 5.x setups • try things and not jeopardise your 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 4 22 | WARNING | Line is indented with space not tab 33 | ERROR | String "Unable to retrieve URL %s, error: %s" does | | not require double quotes; use single quotes instead 322 | ERROR | Closing parenthesis of a multi-line function | | definition must be on a line by itself 440 | 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 384 FF_Meta shortcode_handler 41 2.4 9 48 FF_Community __construct 12 0.0 7 15625 FF_Meta register_stuff 18 0.0 5 16 FF_Meta aux_get_all_locations 23 8.7 5 6 FF_Community make_from_city 15 0.0 4 20 [...]
  • Example Plugin: Freifunkmeta ..WP Blog. FF_Meta . WP Core . Other Plugins . FF_Community . FF_Dir . Output Formatter . HTTP Get Service
  • Unit Testing ..WP Blog. FF_Meta . WP Core . Other Plugins . FF_Community . FF_Dir . Output Formatter . HTTP Get Service
  • 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 . Output Formatter . HTTP Get Service
  • Integration Testing ..WP Blog. FF_Meta . WP Core . Other Plugins . FF_Community . FF_Dir . Output Formatter . HTTP Get Service
  • Unit Testing with Mock Object ..WP Blog. FF_Meta . WP Core . Other Plugins . FF_Community . FF_Dir . Output Formatter . HTTP Get Service
  • 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 . Output Formatter . HTTP Get Service
  • WordPress Shortcode Plugin Test .. Feature: Use Shortcodes In order to use my Plugin As a website author I need to write posts with shortcodes Background: Given I am logged in as "admin" with "vagrant" Scenario: Without the plugin Given 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 plugin Given 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" element And 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 awesome awesome/ awesome/awesome.php awesome/bin awesome/bin/install-wp-tests.sh awesome/tests awesome/tests/bootstrap.php awesome/tests/test-sample.php awesome/.travis.yml awesome/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 ... $ phpunit PHPUnit 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 GitHub 1. 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 automated builds and tests • quickly find bugs and 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 test as 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