Tests cheat sheet 02/04/2014
TL;DR: jump to the conclusion.
This article concludes the series on Tests:
- Introduction
- Tools overview
- Test Driven Development
- TDD: just do it!
- spec BDD
- phpspec: a quick tour
- Behavior Driven Development: story BDD
- Behat: a quick tour
- Conclusion
I've tried to put as much general information and references to blogs which could help you to go further, in each article. In this final post, I'll regroup those references and the conclusions.
Definitions
A test is a way to check if something behaves correctly. This something is called a System Under Test (SUT) and can be:
- the User Interface (HTML, console output, etc): integration tests
- classes, functions: unit tests
- interractions between those classes and functions: functional tests
- the business value: acceptance tests
Generally, you proceed as follow:
- have a set of input (parameters, fixtures, etc)
- put it in the SUT
- check the output
When doing unit tests, you'll need to isolate your SUT from its collaborators (the dependencies, the other classes used by it). To do so, you'll need test doubles and Dependency Injection.
References
- Tests doubles explained by Martin Fowler
- Dependency Injection explained
- Test coverage can be deceptive, by Jason Gorman
Tools overview
Frameworks can help you to automate your tests. You'll generally find these tools:
- integration tests:
- Alexandre Salome's webdriver (PHP)
- Facebook's webdriver (PHP)
- Goutte (PHP)
- PhantomJS
- xUnit frameworks:
- PHPUnit (PHP)
- Atoum (PHP)
- Codeception (PHP)
- Mocha (js)
- CasperJs (js)
- tests double libraries:
- assertion libraries:
- Chai (js)
- behavior frameworks:
Note: xUnit frameworks allows many kinds of tests (they're not limited to unit tests).
Note: WebDriver is an API for Selenium, a java server which allows you to interract with a browser.
References
Test driven development (TDD)
A process in which:
- you write the test first
- then you write the code to make the test pass as quickly as possible (commit any sins)
- refactor the code, clean your sins
This allows you to naturally have a 100% test coverage, and it has the side effect of making your code more decoupled (you need your code to be decoupled in order to test it).
References:
- Kent Beck's book: Test Driven Development by Example
- Ian Cooper coming back to the sources of TDD
- False arguments against TDD
- What TDD is and is not
- Where is the design phase in TDD
About writing the code as quickly as possible, commiting any sins:
Behavior Driven Development (BDD)
BDD is divided in two sections: spec and story. It comes from the lack of direction in TDD and introduces the concept of business value.
- spec BDD: test methods should be sentences
- story BDD: acceptance criteria (from user stories) should be executable
Behat and phpspec allows you to automate the process by allowing you to:
- bootstrap the test
- then you have to manually implement the test
- bootstrap the code from the written tests
- then you have to manually implement the code
References:
- Introductiong BDD
- Whose domain is it anyway?
- Slides by Liz Keogh
- Are you really doing BDD?
- Acceptance Test fail!
Conclusion
Automated tests allow you to make sure your system isn't full of bug, and help to detect any regressions.
Theres many kinds out there: you can test what the user sees, what the computer sees and what the product owner expects.
I'd be really glad if this cheat sheet was of some use to you. If you have any comments, you can contact me on Twitter :) .
Note about BDD, behat and selenium
I had great feedbacks about the Behat article: which were triggered by the following statement: "if you're using Mink or Selenium, then you're doing it wrong". Let me re-phrase that.
If you're using Selenium or Mink, then you're doing integration tests, not behavior ones. Those tools are fine: the UI is what the user sees and interacts with, so it's important to make sure it isn't broken.
What isn't fine is to use Behat with these tools and then to say that you're doing BDD. Use the right tools for the job: PHPUnit can perfectly be used with selenium, and libraries like webdriver allow you to work with selenium without using Behat.
One of the question raised was: "If I can't interract with the UI, how do I test the behavior of my application?"" Well there's many ways and the answer deserves a whole article or even a whole series! I'll just give you the douchebag (it's the actual application name, I mean no offense!) example:
Inner conclusion: make a distinction between integration (HTML, UI, etc) and Behavior (business value, acceptance criteria from user stories) tests. If you can't do both, then the choice is yours: which one is the most important to you?