Jump to: navigation, search

OpenStack-SDK-PHP/Design/Test-tooling

Key differences between phpspec and phpunit

There are a few subtle differences between the way phpspec and phpunit does business:

  • With phpunit, you are testing dozens of individual and isolated unit results. There is no direct or enforced correlation between project goals and what you're testing.
  • With phpspec, the focus is simply on specifying behaviour. By specifying behaviour you are guaranteeing that features work according to established project specifications and that your code is not drifting away from expectations. In a nutshell: you use behaviour, not unit results or assertions, to guarantee project success.


phpspec forces you to think about good design and clean workflow:

  1. You first need to think about your feature and isolate a strand of behaviour. You then write a very small test that specifies this behaviour. It will fail.
  2. You then write just enough code to turn this test green.
  3. After a series of these steps, you're in a position to refactor. You turn "what works" into "how can it best work".


I used to roll my eyes at the above and dismiss it as people trying to enforce their way of working on others, but after using this technique for the past 2 weeks I can honestly say it's changed the way I develop. My thoughts are clearer, my designs are more crystallized, my code is significantly cleaner and better implemented. In fact, I now love and genuinely enjoy testing. I've used phpunit for years and always dreaded it - it was an unfortunate necessity. With phpspec, it's the first thing I do and it continually informs the way I interact with my code.

Jeffrey Way did a great videocast which introduces phpspec and highlights some of the elegant differences it has over phpunit.

7 advantages phpspec has over phpunit

1. It allows your code to align perfectly with project expectations. By specifying the behaviour of your class, it allows you to directly map what you're coding to the described specifications of your project. You don't have to drift aimlessly: you can instead ensure what you're speccing directly aligns with common and end-user expectations. In other words, every single piece of code you write has measurable business value - you're not wasting energy or time. You're always focused and on-track.

2. It enforces good design. You can get away with murder in phpunit - it does absolutely nothing to point you in the right direction. phpspec on the other hand makes it very difficult to enforce bad design. By making certain bad practices extremely difficult to implement, it forces you to continually think about good design. Dependency injection, for example, is an important concept in phpspec. After using this tool for 2 weeks, my code became cleaner because I was forced to think about good design from the beginning.

3. It forces you to think about collaborators. In phpunit, everything executes like it would in a normal thread of execution. Which is bad because it makes you complacent on things "just working", when really you could have no idea what's happening beneath the surface. phpspec forces you to define how your class behaves with collaborators. If you're testing a piece of behaviour that relies on the response of an external class, that's fine, but you must define what your expectations are. Which method should it call? What arguments should it provide? What will it return? After defining this relationship, you have a really clear idea of what's happening - allowing you to quickly refactor dependencies if you need to.

4. It speeds up development. The above steps of Red, Green, Refactor can save you hundreds of hours of scratching your head and wondering why what you coded 2 hours ago doesn't align with your expectations. phpspec also has a bunch of awesome code generation features built in. So you write a test for a class that doesn't exist yet, and when you run the test it offers to create it for you. It also does this for methods that don't exist. Generating code like this saves you even more time.

5. It makes your workflow much more efficient. Point 4 already touched on this, but it makes you a more efficient coder. Because you're continually thinking about your code, and because your tests are always aligned to expected behaviour, you'll never go on autopilot and end up writing hundreds of lines of boilerplate code.

6. It makes coding more enjoyable. It genuinely does!

7. It results in tests that are more readable and akin to documentation. You're encouraged to use whole sentences as test names - making your tests easy to understand and more like documentation than phpunit assertions.

Useful links

Testimonials on Twitter over the past 2 weeks

  • Pretty stoked on @phpspec . I find myself actually having fun writing tests! link
  • #phpspec has changed my life, helps to point out design issues and to re-work legacy code. Try it ! #php link
  • @phpspec to me: "Quick and easy tests for your classes? Sure, decouple the hell out of them!" #it_forces_you_to_design link
  • I can not wait to use #phpspec at work! Thanks @_md @everzet link
  • Spent a weekend with #phpspec and #prophecy, so impressed with their ability to guide towards simple correct design! /cc @everzet @_md link
  • @phpspec makes testing code fun all over again! Not sure when I'll be touching on PHPUnit again... #BDD link
  • Man, I absolutely love #phpspec - it's a refreshing coding experience. And I feel that my code is much stronger now. Ty @everzet /cc @_md link
  • Just started using @phpspec this week and already loving it! #php #symfony #specbdd link
  • coming from @phpspec and writing plain old @phpunit tests feels weird, to much boilerplate code, to less intuitive mocking api link
  • #phpspec is better than kittens. link