Below you will find pages that utilize the taxonomy term “PHPUnit”
A better PHP testing experience Part II: Pick your test doubles wisely
In the introduction to this series I mentioned that testing object interactions can be really hard. Most unit testing tutorials cover this subject by introducing the PHPUnit mocking sub-framework. The word “mock” in the context of PHPUnit is given the meaning of the general concept of a “test double”. In reality, a mock is a very particular kind of test double. I can say after writing lots of unit tests for a couple of years now that my testing experience would have definitely been much better if I had known about the different kinds of test doubles that you can use in unit tests. Each type of test double has its own merits and it is vital to the quality of your test suite that you know when to use which one.
The PHP testing experience: Interview by Fernando Arconada
Fernando Arconada interviewed me about the subject of testing. He is writing a book about testing Symfony2 applications: Testing para Aplicaciones Symfony2. Fernando will translate this interview to Spanish and and add it to his book, together with the articles in my A better PHP testing experience series.
Who is Matthias Noback?
I’m a PHP developer, writer and speaker. I live in Zeist, The Netherlands, with my girlfriend, a son of 9 and our newborn daughter. Currently I have my own business, called Noback’s Office. This really gives me a lot of freedom: I work as a developer on one project for about half of the week and in the remaining time I can either spend some time with my family or write blog posts, or finish my second book.
A better PHP testing experience Part I: Moving away from assertion-centric unit testing
In the introduction article of this series I quickly mentioned that I think unit testing often focuses too much on assertions. The historic reason for this is that in introductory articles and workshops it is often said that:
- You are supposed to pick the most specific assertion the testing framework offers.
- You are supposed to have only one assertion in each test method.
- You are supposed to write the assertion first, since that is the goal you are working towards.
I used to preach these things myself too (yes, “development with tests” often comes with a lot of preaching). But now I don’t follow these rules anymore. I will shortly explain my reasons. But before I do, let’s take a step back and consider something that is known as the Test framework in a tweet, by Mathias Verraes. It looks like this:
A better PHP testing experience: Introduction
This is the introduction to a series of articles related to what I call: the “PHP testing experience”. I must say I’m not really happy with it. And so are many others I think. In the last couple of years I’ve met many developers who experienced a lot of trouble while trying to make testing a serious part of their development workflow. It is, I admit, a hard thing to accomplish. I see many people fail at it. Either the learning curve is too steep for them or they are lacking some insight into the concepts and reasoning behind testing. This has unfortunately led many of them to stop trying.
Test Symfony2 commands using the Process component and asynchronous assertions
A couple of months ago I wrote about console commands that create a PID file containing the process id (PID) of the PHP process that runs the script. It is very usual to create such a PID file when the process forks itself and thereby creates a daemon which could in theory run forever in the background, with no access to terminal input or output. The process that started the command can take the PID from the PID file and use it to determine whether or not the daemon is still running.
PHPUnit & Pimple: Integration Tests with a Simple DI Container
Unit tests are tests on a micro-scale. When unit testing, you are testing little units of your code to make sure that, given a certain input, they produce the output you expected. When your unit of code makes calls to other objects, you can “mock” or “stub” these objects and verify that a method is called a specific number of times, or to make sure the unit of code you’re testing will receive the correct data from the other objects.
Experiences with PHP open source software in a Symfony-friendly environment
These days, good PHP object-oriented libraries are all around and easily available. To me, it is actually thrilling to be part of this flourishing community, while working with Symfony2 and blogging about the Framework, the Components and their neighbors (like Silex). It seems like everything is made for contributing to this nice and friendly environment, with tools like GitHub (online collaboration), Composer (dependency management), Packagist (package archive) and Travis CI (continuous integration).
Still, to me, contributing felt like too big a step to take right now. Until a few weeks ago, when I was looking for something I needed (a PHP client for the Microsoft Translator API) and could not find a decent solution. I decided to make it myself, and share it online. Below I’ve written down my steps. As you can see, they are very easy and would require just a bit of extra time. So, take from it what you need, and start contributing!
Symfony2: Testing Your Controllers
Apparently not everyone agrees on how to unit test their Symfony2 controllers. Some treat controller code as the application’s “glue”: a controller does the real job of transforming a request to a response. Thus it should be tested by making a request and check the received response for the right contents. Others treat controller code just like any other code - which means that every path the interpreter may take, should be tested.
PHPUnit: Writing a Custom Assertion
When you see yourself repeating a number of assertions in your unit tests, or you have to think hard each time you make some kind of assertion, it’s time to create your own assertions, which wraps these complicated assertions into one single method call on your TestCase
class. In the example below, I will create a custom assertion which would recognize the following JSON string as a “successful response”:
{"success":true}
Inside a TestCase
we could run the following lines of code to verify the successfulness of the given JSON response string:
Silex: set up your project for testing with PHPUnit
In my previous post I wrote down a set of requirements for Silex applications. There were a few things left for another post: first of all, I want to have unit tests, nicely organized in directories that correspond to the namespaces of my project’s classes. This means that the tests for Acme\SomeNamespace\SomeClass
should be found in Acme\Tests\SomeNamespace\SomeClass
.
Organizing your unit tests
I want to write my tests for the PHPUnit framework. This allows me to use some PHPUnit best practices: first of all we define our PHPUnit configuration file in /app/phpunit.xml
.
First of all we point PHPUnit to a bootstrap file (of which we will later define it’s contents). We also set an environment variable called “env” whose value is “test”. Finally we set the location of our app.php
file inside the server variable “env”.
PHPUnit: create a ResultPrinter for output in the browser
PHPUnit 3.6 allows us to create our own so-called ResultPrinter
s. Using such a printer is quite necessary in the case of running your unit tests from within the browser (see my previous post), since we don’t print to a console, but to a screen. You can make this all as nice as you like, but here is the basic version of it.
Create the HtmlResultPrinter
First create the file containing your (for example) HtmlResultPrinter
, for example in /src/Acme/DemoBundle/PHPUnit/HtmlResultPrinter
.
Symfony2: running PHPUnit from within a controller
When you don’t have access to the command-line of your webserver, it may be nice to still run all your unit tests; so you need a way to execute the phpunit
command from within a controller. This way, you can call your test suite by browsing to a URL of your site. To do things right, we start with a “test” controller /web/app_test.php
containing these lines of code:
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
))) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
use Symfony\Component\HttpFoundation\Request;
$kernel = new AppKernel('test', true);
$kernel->loadClassCache();
$kernel->handle(Request::createFromGlobals())->send();
In fact, just copy everything from /web/app_dev.php
but replace the string “dev” by “test”.
Symfony2: use a bootstrap file for your PHPUnit tests and run some console commands
One of the beautiful things about PHPUnit is the way it can be easily configured: for example you can alter the paths in which PHPUnit
will look for TestCase
classes. In your Symfony2 project this can be done in the file /app/phpunit.xml
(if it is called phpunit.xml.dist
, rename it to phpunit.xml
first!). This file contains a default configuration which suffices in most situations, but in case your TestCase classes are housed somewhere else than in your *Bundle/Test
, add an extra “directory” to the “testsuite” element in phpunit.xml
: