Unit Testing in PHP
Lee Boynton
Advantages to Automating Testing
● Faster to test
○ Don't need to "click about"
○ Don't need to login
○ Don't need to have commented out test code
● Prevent recurring bugs
○ Write a test for bug, run the test after every change
● Easier to test edge cases
● Less fear when making changes
○ You may have forgotten how the code works
○ You may inherit someone else's code
● Find bugs before your users
○ This means you keep your customers happy, this
means more money!
Advantages to Automating Testing
● Better designed code, especially with TDD
○ Unit tested code tends to be
■ Less coupled
■ Less complex
● Tests document how code should work
● Once you are good at unit testing, it's
probably faster
● Tests don't have to be amazing: "Imperfect
tests, run frequently, are much better than
perfect tests that are never written at all"
Disadvantages
● You have to suck it up and write tests to
really see the benefits
● Hard to retrofit tests
○ You may have to refactor old code, or
○ You may have to write a lot of test code for code
which is not easy to test
● Harder to write bad code
● You probably won't want to write code
without tests again
Goals When Writing Tests
● Tests should be
○ Simple
■ Don't have ifs or loops
○ Easy to write
○ Easy to read
○ Easy to run
○ Isolated
● But these ideas may conflict or be hard to
achieve
○ Do your best
○ Can improve tests over time
○ Bad tests better than no tests
Common PHPUnit Methods
● $this->assertTrue($value, 'Value should
have been true')
● $this->assertFalse($value, 'Value should
have been false')
● $this->assertEquals($expected, $actual,
'The result is not what was expected')
● Try to write a message to indicate what
specifically is being asserted
○ Easier to understand what's wrong instead of e.g.
"Failed asserting that false is true"
Common PHPUnit Patterns
● Use setUp() method to instantiate the class
you are testing
○ This works well if you don't have lots of constructor
parameters
● Use data providers to test lots of different
inputs
○ Tests shouldn't have duplicate code either
● Use tearDown() method if you need to clean
up external resources after each test is run
○ Files
○ Database
Hard to Test Things
● Static calls to other classes
○ You cannot mock the dependency
● Singletons
○ Constructor is private or protected
○ Uses static call to get instance
○ Cannot guarantee there are no side effects when
running multiple tests
● Private methods
○ Usually you indirectly test these when you test public
methods
○ Can use reflection if you really want, but this
probably means you should refactor
Hard to Test Things
● Hard coded dependencies
○ Such as when a class instantiates another class
● Magic methods
○ __call
○ __get
○ __set
How to Write Testable Code
● Use dependency injection
○ This means you don't instantiate classes unless
you're in a factory
● Keep methods relatively small
● Avoid having lots of private methods
● Write classes which do one thing (single
responsibility principle)
Go go go!
● http://www.phpunit.
de/manual/current/en/index.html

Unit testing in PHP

  • 1.
    Unit Testing inPHP Lee Boynton
  • 2.
    Advantages to AutomatingTesting ● Faster to test ○ Don't need to "click about" ○ Don't need to login ○ Don't need to have commented out test code ● Prevent recurring bugs ○ Write a test for bug, run the test after every change ● Easier to test edge cases ● Less fear when making changes ○ You may have forgotten how the code works ○ You may inherit someone else's code ● Find bugs before your users ○ This means you keep your customers happy, this means more money!
  • 3.
    Advantages to AutomatingTesting ● Better designed code, especially with TDD ○ Unit tested code tends to be ■ Less coupled ■ Less complex ● Tests document how code should work ● Once you are good at unit testing, it's probably faster ● Tests don't have to be amazing: "Imperfect tests, run frequently, are much better than perfect tests that are never written at all"
  • 4.
    Disadvantages ● You haveto suck it up and write tests to really see the benefits ● Hard to retrofit tests ○ You may have to refactor old code, or ○ You may have to write a lot of test code for code which is not easy to test ● Harder to write bad code ● You probably won't want to write code without tests again
  • 5.
    Goals When WritingTests ● Tests should be ○ Simple ■ Don't have ifs or loops ○ Easy to write ○ Easy to read ○ Easy to run ○ Isolated ● But these ideas may conflict or be hard to achieve ○ Do your best ○ Can improve tests over time ○ Bad tests better than no tests
  • 6.
    Common PHPUnit Methods ●$this->assertTrue($value, 'Value should have been true') ● $this->assertFalse($value, 'Value should have been false') ● $this->assertEquals($expected, $actual, 'The result is not what was expected') ● Try to write a message to indicate what specifically is being asserted ○ Easier to understand what's wrong instead of e.g. "Failed asserting that false is true"
  • 7.
    Common PHPUnit Patterns ●Use setUp() method to instantiate the class you are testing ○ This works well if you don't have lots of constructor parameters ● Use data providers to test lots of different inputs ○ Tests shouldn't have duplicate code either ● Use tearDown() method if you need to clean up external resources after each test is run ○ Files ○ Database
  • 8.
    Hard to TestThings ● Static calls to other classes ○ You cannot mock the dependency ● Singletons ○ Constructor is private or protected ○ Uses static call to get instance ○ Cannot guarantee there are no side effects when running multiple tests ● Private methods ○ Usually you indirectly test these when you test public methods ○ Can use reflection if you really want, but this probably means you should refactor
  • 9.
    Hard to TestThings ● Hard coded dependencies ○ Such as when a class instantiates another class ● Magic methods ○ __call ○ __get ○ __set
  • 10.
    How to WriteTestable Code ● Use dependency injection ○ This means you don't instantiate classes unless you're in a factory ● Keep methods relatively small ● Avoid having lots of private methods ● Write classes which do one thing (single responsibility principle)
  • 11.
    Go go go! ●http://www.phpunit. de/manual/current/en/index.html