Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHPUnit: from zero to hero

14,530 views

Published on

Slides from talk given at Guelph PHP on February 29th 2012 introducing PHPUnit.

Published in: Technology, Business

PHPUnit: from zero to hero

  1. 1. From Zero to Hero
  2. 2. WHAT IS UNIT TESTING…  and why is it a Good Thing™?
  3. 3. WHAT IS UNIT TESTING?  “In computer programming, unit testing is a method by which individual units of source code are tested to determine if they are fit for use. A unit is the smallest testable part of an application.” Wikipedia
  4. 4. HAVE ANY OF THESE EVER APPLIED TO YOU?  You have a piece of code that everyone is too terrified to touch. You’re too scared to refactor or change a piece of code because you can’t predict the impact it will have on your application. Releases are a complete nightmare. You’ve had to work late or through a weekend to track down a bug.
  5. 5. WRITING TESTS IS HARD, WRITINGGOOD TESTS IS EVEN HARDER…
  6. 6. …BUT WORTHWHILE  A study conducted by Microsoft and IBM showed writing tests can add 15%-35% to development time but reduce the number of bugs by 40%-90%! Writing code that is easily testable encourages best practices, such as SOLID principles. Having a set of unit tests can help you make sure your deployments are painless rather than painful None of us want to be stuck at work all weekend trying to work out why a code change has broken the whole application.
  7. 7. WHAT IS PHPUNIT? 
  8. 8. INTRODUCTION TO PHPUNIT  PHPUnit is a unit testing framework written in PHP, created by Sebastian Bergman. Part of the xUnit family of testing frameworks. While there are other unit testing frameworks for PHP (such as SimpleTest or Atoum) PHPUnit has become the de facto standard. Major frameworks, such as Zend, Symfony and Cake, and many other PHP projects such as Doctrine have test suites written with PHPUnit.
  9. 9. INSTALLING PHPUNIT 
  10. 10. REQUIREMENTS  Minimum requirement is PHP 5.2.7 but 5.3.X is recommended. If you want code coverage analysis (you do!) you need to install the PECL xDebug extension. Best installed via the PEAR installer so you need to have run the pear installation.
  11. 11. INSTALLING VIA PEAR  If installing via PEAR you need two commands to get up and running: Full installation instructions (including other optional PHPUnit modules) can be found at http://www.phpunit.de/manual/3.6/en/installatio n.html
  12. 12. WRITING TESTS 
  13. 13. TEST WRITING BEST PRACTICES  The general aim is to make sure every possible path through your code is exercised at least once in a test. This means you need to write tests that exercise error conditions too. Rule of thumb: one test method per expected outcome per method tested. Have descriptive test method names. Name the test class after the class being tested.
  14. 14. TEST BASICS  Simply add ‘require_once PHPUnit/Autoload.php’ to each test file. A PHPUnit test is a class that (usually) extends PHPUnit_Framework_TestCase. The class name should end with the word ‘Test’, e.g. ‘FooBarTest’. Each test class should be in its own file named after the class, e.g. ‘FooBarTest.php’. Each test method name must begin with the word ‘test’, e.g. ‘testSomethingWorks’ or have an @test annotation. Test methods must be public. The class must contain one or more methods that perform tests or the test case will fail. A test method must contain one or more assertions, be marked as incomplete or skipped.
  15. 15. TEST FIXTURES  A fixture in a test is something (usually an object) that you want to test. Also known as System Under Test (SUT). PHPUnit will set up fixtures for you if you add protected methods setUp and optionally tearDown in your test class. You provide code to create/destroy fixtures in these methods. These methods are called before and after each test method so that each test runs on fresh fixtures. setUpBeforeClass and tearDownAfterClass are also available. These are run once at the beginning and end of the test class.
  16. 16. WRITING ASSERTIONS  Assertions are used to test expected behaviour from your SUT. PHPUnit provides many different assertions for all sorts of needs, e.g. assertEquals, assertEmpty, assertTrue, assertType, et c. You can also test output using expectOutputString. More complicated assertions can be constructed using assertThat. For a test to pass all assertions must evaluate to true.
  17. 17. ANNOTATIONS  PHPUnit supports annotations to give instructions to the test method being executed. Annotations are included in block comments before the method and always begin with an ‘@’. Examples: @depends, @expectedException, @dataProvider. Full details on supported annotations at http://www.phpunit.de/manual/3.6/en/appendix es.annotations.html
  18. 18. DATA PROVIDERS  A data provider is a method that returns an array of values to use in a test. PHPUnit will call the related test method once for each set of data, passing the values as arguments to the method. Set using the @dataProvider annotation. Allows you to easily add extra values to test with. Also makes tests shorter and more concise by keeping values to test with out of test methods.
  19. 19. TESTING EXCEPTIONS  You can tell PHPUnit that a test should expect an exception. This can be done in two ways:  Through the method setExpectedException($exception, $message = ‘’, $code = null)  Through @expectedException, @expectedExceptionMessage, @e xpectedExceptionCode annotations. PHP errors such as warnings are converted into exceptions by PHPUnit. These can also be tested for.
  20. 20. MOCK OBJECTS One of the most powerful features of PHPUnit.
  21. 21. WTF IS A MOCK OBJECT?  Allows you to replace a dependency of your SUT with an object that has predefined behaviour. The mock object becomes part of the test. If the methods defined are not called as expected the test fails. Proper use of mock objects allow you to make sure you’re only testing the SUT and not other code. Helps to ensure that if a test fails it’s in the SUT, not a dependency. However, you need to be using Dependency Injection to use mock objects.
  22. 22. MOCK OBJECT BASICS  PHPUnit creates a mock by sub-classing the original object. Once you have a mock object you can define what methods you expect to be called on it, with what arguments and what the mock should do.
  23. 23. OTHER MOCK OBJECT USES  Mock objects allow you to test concrete methods of abstract classes with getMockForAbstractClass. You can create a mock object representing a SOAP web service using getMockFromWsdl. PHPUnit has experimental support for mocking out file system calls using the package vfsStream. More information at http://www.phpunit.de/manual/3.6/en/test- doubles.html.
  24. 24. RUNNING TESTS 
  25. 25. COMMAND LINE RUNNER  Tests are normally run from the command line with the phpunit command. Just typing phpunit will get a ‘help’ output. Passing the name of the test will run just that test. You can also pass a path to a directory to run all tests in it or the name of a test file to run tests in that file. PHPUnit prints a ‘.’ for each test passed, ‘F’ for a failure, ‘E’ for an error, ‘I’ for incomplete or ‘S’ for skipped. More information is also printed for anything other than a pass.
  26. 26. SAMPLE COMMAND LINE OUTPUT 
  27. 27. OTHER WAYS TO RUN TESTS  Many IDE’s such as Zend Studio include PHPUnit integration. This enables you to write and run tests from within the IDE. Running tests can be integrated into continuous integration servers such as Jenkins. In this case your full test suite can be run automatically with each edit to your code. Any test failure will mean the build fails.
  28. 28. CODE COVERAGE ANALYSIS… or how to make sure you’re not feeling a false sense of security.
  29. 29. WTF IS CODE COVERAGE?  Code coverage tells you how much of your code is covered by tests. PHPUnit can generate code coverage reports in a number of formats including HTML but… You must have installed xDebug. (pecl install xdebug) Helps to avoid a false sense of security. Code coverage threshold percentage can be added to continuous integration builds. Add code coverage by passing the –coverage-xxx option, eg. phpunit –coverage-html ./reports ./
  30. 30. PHPUNIT TEST EXTENSIONS Writing tests for different situations.
  31. 31. INTRO TO EXTENSIONS  PHPUnit supports a number of extensions that allow you to write specialised tests. These include working with databases, Selenium, and running profiling with XHProf. Full details at http://www.phpunit.de/manual/3.6/en/installatio n.html.
  32. 32. TESTING WITH DATABASES  To do this install the DbUnit  You need to provide a extension, eg. ‘pear install schema with tables for phpunit/DbUnit’ PHPUnit to use. However, where possible  getConnection must return a PDO instance for PHPUnit avoid tests using a database to use. by using mock objects.  getDataSet returns data to Test case must extend populate database tables ‘PHPUnit_Extensions_Datab with. ase_TestCase’.  PHPUnit truncates tables Defines two extra methods before each test run and that you must implement: inserts data. This means getConnection and each test runs with a fresh set of predictable data. getDataSet.
  33. 33. PHPUNIT CONFIG 
  34. 34. ADDING A CONFIG FILE  Options can be passed to PHPUnit through the command line but it also supports adding an XML config file. This can include a number of options such as where to find test cases and which directories to include for code coverage analysis. To use this just create the file and name it phpunit.xml, adding it to the root of your tests directory. Especially useful when running tests as part of a CI build. Full details at http://www.phpunit.de/manual/3.6/en/appendixes.co nfiguration.html
  35. 35. LET’S WRITE SOME TESTS! 
  36. 36. QUESTIONS? 

×