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!
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"
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
▪ 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
• $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"
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
◦ 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
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)