Composer
Setting up a new project almost always starts with dependency management and I used Composer to define my dependencies. Composer was configured by its
composer.json
,{ "name": "codecop/CodingDojo-PHP", "description": "Coding Dojo template", "license": "BSD", "require": { }, "require-dev": { "phpunit/phpunit": "4.5.*" } }After verifying my composer installation with
composer --version
I downloaded PHPUnit with composer install
. PHPUnit and its transitive dependencies were installed into the vendor
directory as expected.PHPUnit
Next I configured PHPUnit with its
phpunit.xml
,<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd" backupGlobals="false" colors="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" beStrictAboutTestSize="true" beStrictAboutTodoAnnotatedTests="true" verbose="true"> <testsuites> <testsuite name="All Tests"> <directory suffix="Test.php">test</directory> </testsuite> </testsuites> </phpunit>This told PHPUnit to load all the
*Test.php
files inside the test
directory for test classes. I especially like the beStrictAbout*
flags and enabled them all. These flags warn about smelly tests, e.g. test methods without any assertions. I ran PHPUnit with ./vendor/bin/phpunit
to verify my setup. It did not show any tests - after all this was a new and empty project. I have seen people creating an alias to run PHPUnit, but I created a (Windows) script phpunit.bat
in the local directory with the same effect,@call "%~dp0vendor\bin\phpunit" %*Now I was ready to go and wrote some unit tests, e.g.
<?php require 'Hello.php'; class HelloTest extends \PHPUnit_Framework_TestCase { /** @test */ function shouldReturnHelloName() { $greeter = new Greeter(); $this->assertEquals("Hello Peter", $greeter->greet("Peter")); } }Hamcrest Matchers
In the Java community Hamcrest Matchers are popular and they even ship with the core JUnit framework. I like Hamcrest because it allows me to write my own matchers, which make assertions much more expressive than plain
assertEquals
. Luckily there were some ports of it and I was happy to see a Hamcrest PHP port. I added it to composer.json
,"require-dev": { "phpunit/phpunit": "4.5.*", "hamcrest/hamcrest-php": "1.2.*" }and updated my installation with
composer install
. Hamcrest offers global functions for its matchers, which allow for shorter syntax, especially when matchers are chained together. To enable this global functions, Composer has to auto load the main Hamcrest file, which is configured using autoload-dev
in composer.json
,"autoload-dev": { "files": ["vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php"] }Using global functions has some drawbacks and is considered a bad practise in large scale projects. There are different ways to use Hamcrest PHP with Composer without loading the global functions, e.g. see Hamcrest PHP issues at GitHub. For a first time Coding Dojo I wanted to stay with the simplest way to use Hamcrest and kept the global functions.
So I was able to write my unit tests using Hamcrest matchers, e.g.
<?php require 'Hello.php'; class HelloTest extends \PHPUnit_Framework_TestCase { /** @test */ function shouldReturnHelloName() { $greeter = new Greeter(); assertThat($greeter->greet("Peter"), equalTo("Hello Peter")); } }While the test above succeeded, PHPUnit refused to show me a green bar. This was because Hamcrest's
assertThat
was not recognised as assertion and PHPUnit marked the test as erroneous. With a heavy heart I had to remove one of PHPUnit's beStrictAbout
flags,<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd" backupGlobals="false" colors="true" beStrictAboutTestsThatDoNotTestAnything="false" beStrictAboutOutputDuringTests="true" beStrictAboutTestSize="true" beStrictAboutTodoAnnotatedTests="true" verbose="true">That was it. Finally I was ready to rock, matchers included!
(The complete project as zip is here.)
No comments:
Post a Comment