phpunit-testingtestingbehatphpspec

PHPSpec and Behat


I just started to learn the concept of BDD.

I learn PHPSpec and Behat for that, but it is not clear to my why do I need to use both. I understand that behat is for the functional/acceptance testing and PHPSpec is mainly for unit testing, but the articles and videos I found on this is basicly testing the the code twice: once with behat (with scenarios) and once with with phpspec. Can someone explain to my with easy examples what is the difference and when do I need to use behat and whan phpspec?

Thanks the anwers in advance, Br.


Solution

  • Well, before starting with the answer, I would like to point out that what follows is a more general answer than a "phpspec and behat" one.

    As you correctly stated, phpspec is a tool designed to write unit tests whereas behat is something for other kind of tests (let's say from integration to e2e/smoke tests). So far so good. So now we can abstract and distinct between unit test tools and other testing tools.

    Let's start defining what a unit test is and what is not. A unit test is a kind of test done against a "small" part (the unit) of a system. Typically it's focus is on a single class or method (whereas not always true). Unit tests promote fast refactor as they run fast and in isolation. Please, focus on fast and isolation, we'll be back at them sooner.

    Other kind of tests are more cumbersome and oriented to test an interaction between some components, or a whole function, or the "whole" system as the user would use it. Why cumbersome? Because you may have to setup a database, you may have to run a webserver, you may have need for a browser simulator like selenium, and so on. Because of this, those kind of test are much slower than unit ones. Moreover, when an error arise from other tests but unit, as you have a "whole" funcionality, it will be more painful to hunt down the bug whereas with unit tests, at least, you know what class (or group of them) are causing the bug.

    Having said that, remeber the statement about unit test speed and isolation? Well, speed helps you to "fail faster" (you don't need to wait the whole system bootstrap, whatever it means for your project) and fail in a more "localized" way (isolation).

    My suggestion is to follow the test pyramid: a lot of unit tests (all possibile permutation of I/O, for instance, of a method) and only what's valuable for integration and above. Just to make an example: you can test a repository (that iteracts with DB, so something you can not do with unit) for a particular query, you can test for the login page or homepage to be reached (as a status for the application health) and so on.

    My answer is just a short summary; hope that drives you in the right direction.