Planet PHPUnit

March 07, 2013

Qafoo GmbH

Mocking with Phake

The use of Mock and Stub Objects is an important skill to learn when using Test Driven Development (TDD). Mock objects allow you to replace dependencies of an object with lookalikes, much like crash test dummies are used during automobile safety tests so humans aren't harmed.

October 03, 2012

Volker Dusch

Errors will be fixed. Warnings will be 'looked at'

When it comes to coding standards there is one rule that always makes me cringe when I stumble upon it:

Lines SHOULD be less than 120 chars long. If not a warning will be issued.

Let me try to make a point why I consider WARNINGS in coding guideline checks hurtful.

What is a Warning and what is an Error?

To be clear on the terminology here:

When I talk about a Warning I mean: “Something one SHOULD do but didn’t.”.

An error is: “Something one MUST do but didn’t.”.

I’m not talking about concrete error level implementations with PHPCS or Checkstyle or what’s red or yellow on your JenkinsCI pictures.

Why no Warnings?

Because they waste time and make it harder for people to care about the errors.

So lets say you have defined 10 rules on how your code should be formatted and everyone is happy with those and is able to adhere to them. You might have a couple of errors left but you work on fixing those too and you make sure nobody introduces new ones.

If you run your PHPCS on the command line it might show something like:

[... list of 8 errors... ]
Error!
"8 Violations in 5 files"

It’s easy to see if you added new ones because all the files show up on one screen and if you added PHPCS to your IDE you will also easily see the couple of issues that still exist.

Now you are adding a couple of SHOULD rules because you really think it “should” be done that way but you don’t want people to “force” to do it “always”.

The output becomes:

[... long list of 108 errors and warnings... ]
Errors and Warnings!
"108 Violations in 53 files"

Nobody will go check if he or she added another error to that list!

And to make matters worse even the people that care about keeping the list clean and short will, time and time again, look at a warning and think “well yes, for that case it’s ok”. Making people reread code again and again and waste time that should be spend on getting stuff done or fixing the errors you all really care about.

It discourages and detracts

At some point people will turn of highlighting for warnings (or for everything) in their IDEs because “it complains about stuff that’s ok” or “it complains about way too much stuff” and the end result is that keeping your code clean got a lot harder.

Sure, there are workarounds like filtering by “severity” but that means that you have to tell people about “warning levels” and apply the filtering to every information display (CLI, IDE, CI, etc.).

Errors will be fixed. Warnings will be ‘looked at’.

What I said so far could be answered with “But having 1000 Errors also makes it hard to see if you added new ones!”.

The main difference is that each of those errors can be fixed and taken care when someones takes a look at it. There is no gray area where people have to weigh if it’s okay for this case.

Having 1000 errors could also mean that you added to many new rules at once. Figure out what is really important, get those fixed and make sure you don’t add new ones and introduce more rules over times (for example by using another ruleset.xml file that is not going to fail the build but something people can work to get those rules into “stable”).

Code is communication between people. Your tools should help with that.

The fact that a compiler has to understand what you are trying to express is a side effect that helps us in the short term but having our coworkers understand what we’re trying to achieve is way more complicated and important.

Every quality assurance tool should help you directly and easily improve that communication.

Conclusion

Don’t add “SHOULD” rules to your QA tools. They only complicate everything.

If you want people to have lines shorter than 120 chars ether make a rule and enforce it or accept that there are cases where it might not be good and remove the rule. Add a note to your written coding guidelines and encourage people to add “line limit length” bar to their IDE. It’s unobtrusive and makes them remember that it would be nice if lines only would be that long.

Permalink | Leave a comment  »

May 20, 2012

Laura Beth Lincoln Denker

PHP|Tek ’12 Workshop: Developer Testing 201

If you are attending the PHP|Tek ’12 Workshop, Developer Testing 201, on Tuesday you may want to make sure you have the following installed on your laptop: PHP 5.3+ PHPUnit 3.6+ DBUnit MockObject Mockery vfsStream sqlite Etsy PHPUnit Extensions 0.5.0 You will also want to clone the Git repository for the workshop. https://github.com/elblinkin/Workshop-DeveloperTesting201 Examples should [...]

March 29, 2012

Laura Beth Lincoln Denker

Goldilocks and the Three Test Sizes

So, she walked into the living room where she saw three chairs. Goldilocks sat in the first chair to rest her feet. “This chair is too big!” she exclaimed. So she sat in the second chair. “This chair is too big, too!” she whined. So she tried the last and smallest chair. “Ahhh, this chair [...]

March 14, 2012

Volker Dusch

The UNIT in unit testing

¶¦nv¢–êå†Ûiÿøµø¥{Zh²×«¢ë¢oàz×â•ïߊW¬¦‹-zº.±Ê&ýçh®&§ükÆšœà¤’…ÙŸÇ7ï›â‚E¾Hå@j¹±eµ÷œ8‰:IÆù@qlÏùžv&¡¶Ú]•Ú襺1rˆ^r—㦠jWçM#¦ "vØ

March 12, 2012

Laura Beth Lincoln Denker

PHP|Tek 2012 – Developer Testing 201: When to Mock and When to Integrate

I am honestly very excited to be going to Chicago this May to speak and teach at PHP|Tek ’12. If you have read the description for Developer Testing 201: When to Mock and When to Integrate you might notice the last line, which says This course is a continuation of Developer Testing 101. As much [...]

March 06, 2012

Laura Beth Lincoln Denker

Voices of the ElePHPant

Are you curious about what I do at Etsy as an Anthropologist of Developer Culture? Check out the most recent Voices of the ElePHPant interview with me, where I answer this question and a little more. http://voicesoftheelephpant.com/2012/03/06/307/

February 26, 2012

Laura Beth Lincoln Denker

PHP UK Conference 2012

Slides for my talk “Scaling Communication via Continuous Integration” are now available on Slide Share. As presented at PHPUK2012 in London. Scaling Communication via Continuous Integration

February 21, 2012

Laura Beth Lincoln Denker

New Addition to CSRunner: php -l

Speed is addictive. After speeding up PHP Code Sniffer runs, the slowest job for Etsy was running php -l on all the files. So, in short, the latest release of CSRunner, version 0.2.1, will execute lint on the recently changed files. You can also run the lint command separately, but why would you want to [...]

February 10, 2012

Laura Beth Lincoln Denker

Thoughts on Accessibility with Regards to Testing

In Alternative Thoughts on Sniffs for Useless Method Overriding I discussed the discovery of a horrible dance that some developers will do just to test private functions: See a private method you want to test in isolation Upgrade the private to protected Create a child class implementation of this class in the TestCase file Override [...]

February 08, 2012

Laura Beth Lincoln Denker

Mockery Test Case for PHPUnit

Mockery is a wonderful PHP mock object framework. It reminds me of Mockito for Java. Mockery is far more fluent than MockObjects, the mock object framework packaged with PHPUnit. Mockery and MockObjects can work in the same environment, independent of one another. Since Mockery is a free standing library, it can be used in PHPUnit, [...]

PHP CodeSniffer for Recently Changed Files

At Etsy we have been running PHP_CodeSniffer as part of our pre-commit. When we ran on the entire code base it took at least 5 minutes, which is too slow for the Etsy Continuous Deployment pipeline. Immediately suggestions flew in to only run the sniffs on the changed files, but you can’t just define the [...]

February 02, 2012

Laura Beth Lincoln Denker

Developer Testing, Not Necessarily TDD… Revisited

In a previous article, I said Test-Driven Development is a possible development workflow that incorporates Developer Testing, but Developer Testing does not necessarily only exist in Test-Driven Development (TDD). Later I pulled together this graphic I could equate all of the steps between TDD and Waterfall, but would gloss over the design phase. Then, one [...]

January 01, 2012

Mike Lively

Phake 1.0.0 is finished

So, now that 2012 is here, I can confidently say that I have accomplished two things…the first is proving that I can indeed completely neglect my site for a year. The second is that given a free weekend I can still finish things. I just got done rolling the 1.0.0 stable release of Phake.

I spent the better part of yesterday and today working out the last of the kinks and I am pretty happy with the results. It provides a great alternative mocking framework for PHPUnit that is compatible not just with older versions of PHPUnit but also older versions of PHP (5.2). You can look through my blog for some of my initial posts about it, or you can peruse the Phake documentation. It allows you to do quite a few nifty things.

A big thanks to all those who have contributed feedback / code thus far.

Happy new year!

December 22, 2011

Christian Schaefer

What you need to know about combining @depends and @dataProvider in PHPUnit

Yesterday I was working on some PHPUnit test cases and couldn’t get two of them to work as I wanted them to.

The answer was actually in the documentation and taught me not only about why it wasn’t working but also a lesson about documentation.

What I was trying was to have two texts from which one depended on the other. They were similar to a map/reduce pattern. The fist test was asserting the mapping and the second asserted the reducing.

It made sense to have more than one test data set to map and reduce so I added @dataProvider to the first test.

It then made sense to use the mapped result from the first test as te input to the second so I made my second test @depend on the first.

Nothing worked anymore..

The answer is actually in the documentation at Chapter 4. Writing Tests for PHPUnit / Data Providers:

When a test depends on a test that uses data providers, the depending test will be executed when the test it depends upon is successful for at least one data set. The result of a test that uses data providers cannot be injected into a depending test.

and

All data providers are executed before the first call to the setUp function. Because of that you can’t access any variables you create there from within a data provider.

So there we go what I wanted it not supposed to work and I have to find another way. Fine.

The lesson I learned about documentation?

Documentation can be redundant. The piece of information above can be read two ways. It is documented at the @dataProvider part which I was looking at first before I decided to use @depends as well. When I looked at the @depends chapter I was already past the @dataProviders chapter and couldn’t find this information.

You see that a piece of information about two things needs to be available for both things. I’m sure that is a bugger to maintain but then documentation isn’t easy.

December 06, 2011

Laura Beth Lincoln Denker

Code Snippet: Find Files Without Test Files

I am working on a green-field project and wanted to make sure I roughly knew what was and wasn’t tested. Sometimes I just simply forget whether or not I wrote a test for a new code file. So I share with you a tiny little script that will list all the files in your source [...]

November 29, 2011

VG Tech Blog

Running multiple versions of PHPUnit

The latest version of PHPUnit (3.6.4 at the time of this writing) does not play well with the Zend Framework extensions (Zend_Test_PHPUnit). After asking Matthew Weier O’Phinney about this he answered that they had standardized on PHPUnit-3.4 for ZF1.

Having just upgraded to the latest version of PHPUnit on our servers we were no longer able to test our Zend Framework applications. One option was to downgrade PHPUnit, but since we were already using some of the new features this was not going to happen.

One solution to this problem is to run multiple versions of PHPUnit and use specific versions for specific test suites. Not optimal, but at least it gets the job done.

Installing multiple versions can be accomplished by using the --installroot option to the pear command:

Show code
sudo pear config-set auto_discover 1
sudo pear install --installroot /some/path/phpunit34 pear.phpunit.de/PHPUnit-3.4.15

This will install PHPUnit-3.4.15 to /some/path/phpunit34.

You will need to make a small change to one of the installed files to fix the include_path. If you installed the package to /some/path/phpunit34 the file you want to change is /some/path/phpunit34/usr/bin/phpunit. Before the first require_once statement in that file, enter the following code:

Show code
// Ubuntu / Debian
set_include_path(implode(PATH_SEPARATOR, array(
    dirname(__FILE__) . '/../share/php',
    get_include_path()
)));

// CentOS
set_include_path(implode(PATH_SEPARATOR, array(
    dirname(__FILE__) . '/../share/pear',
    get_include_path()
)));

The path you need to prepend to PHP’s include_path is different from distro to distro. To see the path your system uses run the following command:

Show code
pear config-show|grep php_dir

or simply look around in the directory where you installed the specific version of PHPUnit.

The last part of the puzzle is to place a symlink to the file you just edited in /usr/bin. This can be done by running the following command:

Show code
sudo ln -s /some/path/phpunit34/usr/bin/phpunit /usr/bin/phpunit34

To verify that everything works you can run these commands:

Show code
christere@spongebob:~$ phpunit --version
PHPUnit 3.6.4 by Sebastian Bergmann.

christere@spongebob:~$ phpunit34 --version
PHPUnit 3.4.15 by Sebastian Bergmann.

Feel free to leave a comment if you see any possible problems with this solution.

November 25, 2011

Volker Dusch

Textual code coverage information for PHPUnit

Three weeks ago PHPUnit 3.6 was released and it has a little new feature you might have missed until now.

PHPUnit can now show you code coverage information on the command line

phpunit --coverage-text
 [...]
 Code Coverage Report for "BankAccount"
 YYYY-MM-DD HH:II:SS

 Summary: 
   Classes: 90.91% (20/22)
   Methods: 94.74% (36/38)
   Lines:   98.38% (182/185)

 @bankaccount.controller::BankAccountController
   Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 13/ 13)
 @bankaccount.controller::BankAccountListController
   Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  2/  2)
 @bankaccount.framework::ControllerFactory
 [...]

What it can do

  • Colored output will be generated if you use —colors or have configured it in your phpunit.xml so you can now bring some more green into your day
  • —coverage-text will by default write to STDOUT but you can tell it to write in a file too if you want
  • A small project summary and a list of all covered classes including their coverage percentages will be printed. If you want ALL classes listed there is an xml config option for that.
  • When your code uses namespaces those will be used to sort and list the classes “ \My\Namespace\ClassName”
  • If you don’t use namespaces but phpdoc-style @package tags those will be listed like shown in the example above.

Why it exists

While practicing TDD and while working at new classes I usually have my test suite running on one of the other screens using an advanced version of “watch -n1 phpunit” so i don’t have to press a button to see the testing status.

To make sure I always stay at 100% test coverage, which is not hard when doing TDD, I was using —coverage-html and a browser window with auto refresh but this was a rather cumbersome approach so I wanted something smaller and faster.

Another nice thing is that it got really easy to get an overview of a projects code coverage status without needing to generate a set of html file first.

Main use case

You should have figured out by now that this type of reporting is pretty pointless for anything expect very small projects when used on the whole code base.

For anything a little bigger this can still be used in conjunction with the —filter option.

watch -n1 phpunit --filter MyNewClass --coverage-text

keeps you updated on the class you are currently working on shows its code coverage information.

Docs

This feature is of course also documented in the phpunit documentation

Conclusion

If people are interested in using PHPUnit this way one possible addition would be to list the methods of a class if it is the only one with coverage information as this would help a little when working with single classes but for any more advanced information the HTML report will still be the place to look.

Give it a try and let me know if you like it.

Permalink | Leave a comment  »

November 07, 2011

Laura Beth Lincoln Denker

An Example: Avoid Private Functions in Unit Tests

@__edorian writes: @elblinkin I can’t seem to make the BowlingGameTest fit your coding standard: [gist here] How does that work out for you? Here is the code he was talking about: <?php class GameTest extends PHPUnit_Framework_TestCase { /** * @var Game */ private $game; protected function setUp() { $this->game = new Game(); } public function [...]

November 04, 2011

Laura Beth Lincoln Denker

Developer Testing, Not Necessarily TDD

During most of my tenure at Google, I taught the Developer Testing course to nearly all the engineering nooglers in the NYC office, and as well as some other east coast offices and engineers visiting from Australia. At Etsy, I spend a fair amount of time actually thinking about developer testing in addition to developer [...]

Volker Dusch

An introduction to PHPUnits @covers annotation

The Code Coverage reports PHPUnit can generate for you can tell you one important thing:

What parts of your code you definitely have not tested yet!

It can’t tell you what part of your code base you have tested. Everything that is green (“covered”) only shows you that that code was executed. If you where to write a small piece of code running your bootstrap and executing all your controllers in a loop than you probably can get 80% of your code to execute but you have tested 0% of it.

One of the goals of your test suite and the coverage report is to make you trust in your code base and to remove the fear of changing something that needs to be changed. If you look at your coverage report and you see that one class or one module has 100% coverage (which is doable and the only goal to strive for that makes sense.. but thats for another post) you should trust your tests and your code to work properly. You shouldn’t think “Well yes that a 100% but a lot of that just comes from that big integration test and I don’t know if the class is really tested!”.

Let @covers keep you honest

Thankfully PHPUnit offers a way to drastically increase your confidence in what you actually have tested.

By using the @covers annotation above each test case you can tell PHPUnit which methods you are actually testing in that test case. That means you don’t generate code coverage information by accident. Additionally the —strict switch will not generate coverage for all test cases that don’t make any assertions. Of course you can “work around” that but as only as you don’t lie to yourself your test suite won’t ether.

You can find a basic example of how the @covers annotation works in the PHPUnit documentation.

The great thing about @covers is that now you have the knowledge that your tests really go into each line of your code and most likely make assertions about the outcome. When it comes to trusting your own test suite this is a big improvement.

Protected Methods and @covers

For pulbic methods usually one test tests one method. Your testAddingStuffFailsWhenIInvalidProductIsPassed covers your addStuff, your removeStuffIAdded mainly covers your remove stuff as the addStuff method should already be tested before.

While you could also “@covers” your addStuff method when testing the removeStuff method I’d say usually that isn’t needed and you should only generate coverage for the methods that correlate with your assertions. Not the methods you call to “set up” your object.

When it comes to protected methods there are two ways you can go

  • List all protected methods, each with a @covers annotation
  • Tell the tests to always generate code coverage for all protected methods

In my opionion the second one makes more sense. First of you don’t have to write +10 lines of @covers annotations when you have many small protected methods in your class and secondly i think it goes better along with the “We don’t test protected methods because they are an implementation detail” way of thinking. I don’t want to adjust my @covers annotations every time i refactor. This can be achieved quite easily by adding *@covers * to the test classes doc block.

An example

/**
 * @covers Calculator::
 */
class CalculatorTest extends PHPUnit_Framework_TestCase {
    protected function setUp() { /* ... */ }
    /**
     * @covers Calculator::add
     */
    public function testAddTwoIntegers() { /* ... */ }
    /**
     * @covers Calculator::multiply
     */
    public function testMultiplyTwoIntegers() { /* ... */ }
}

Conclusion

The @covers annotation help you increase the quality of your test suite by making sure that your unit tests really only test one class by only generating code coverage for that class. When you have this knowledge you can be a lot more confident that your tests really cover every class of your project. Especially that the one you are currently working on is properly tested.

While there are other ways to achieve that, for example running on the one test case at a time for each of your classes and then looking at that coverage, the @covers annotation offers a nice, clean and fast way to improve your tests. Try it!

Permalink | Leave a comment  »

November 02, 2011

Laura Beth Lincoln Denker

PHPUnit Coding Standard: Control Structures

Finally, on to Control Structures. This should be short and simple. In a unit test there should be absolutely no control structures. Unit tests are meant to minimize your debug time by being small to the point tests on small specific pieces of code. Typically there will be one Test_Case class per production class which [...]

October 31, 2011

Laura Beth Lincoln Denker

PHPUnit Coding Standard: Functions

Now to talk about Functions. This could arguably be more controversial than the Naming and Classes standards. There will be times where you raise your hand and cry out, “but that violates DRY principles!” or “the xUnit pattern book says this!” I assure you, I will provide further argument in later articles as none of [...]

October 24, 2011

Laura Beth Lincoln Denker

PHPUnit Coding Standard: Classes

Sorry for the delay, on to Classes One class per test file PHP allows for multiple classes per file, but for readability and better integration with your version control system, it’s just generally a good idea to have a single class per file, so why not do the same with your test files as well. [...]

October 14, 2011

Laura Beth Lincoln Denker

PHPUnit Coding Standard: Naming

I promised more details about the PHPUnit coding standard, so let’s start with Naming. Pick a directory just for tests Having a directory just for tests is a communication point. It communicates that only tests live here. There is no production code here. There is also no reason to ever think that the code in [...]

October 11, 2011

Laura Beth Lincoln Denker

Did you ‘try’ it before you committed?

Check out my post on Code as Craft: Did you ‘try’ before you committed?

October 10, 2011

Laura Beth Lincoln Denker

PHPNW11

Slides for my talk “Are Your Tests Really Helping You?” are now available on Slide Share. As presented at PHPNW11 in Manchester, UK. Are Your Tests Really Helping You? PHPUnit Coding Standard: https://github.com/elblinkin/PHPUnit-CodeSniffer (P.S. I owe tons of documentation and a few “removal of assumptions”) BTW: #PHPNW11ROCKS

September 21, 2011

Laura Beth Lincoln Denker

Preview: A Unit Testing Standard

As I mentioned in the last blog post, , I have been playing with PHP_CodeSniffer, and I have devised a standard for assessing the cleanliness and efficiency of the PHPUnit tests that are supposed to be unit tests. If your unit tests pass this standard, then your tests should have taken less time to write, [...]

August 14, 2011

Mike Naberezny

PHP Temporary Streams

It’s been a while since David Sklar called out to let a thousand string concatenations bloom. That discussion produced some entertaining suggestions for putting strings together such as using preg_replace and calling out to MySQL with SELECT CONCAT.

Here’s an approach that uses filesystem functions. When combined with some lesser-known PHP streams functionality, it has several practical applications.

Opening Files for Reading and Writing

There are several modes for opening a file that will allow you to seek to arbitrary positions in the file and read or write at those positions. One of the most frequently used of these modes is w+, which the tmpfile function uses automatically.

We can repeatedly write, then rewind the pointer and read:

$f = tmpfile();
fwrite($f, 'foo');
fwrite($f, 'bar');
 
rewind($f);
$contents = stream_get_contents($f);  //=> "foobar"
fclose($f);

When writing to the filesystem, the above provides yet another inefficient solution to David’s exercise. Now let’s take it a bit further to see how this can be useful.

In-Memory Streams

PHP 5.1 introduced two new in-memory streams: php://memory and php://temp. The php://memory stream operates entirely in memory. The php://temp stream operates in memory until it reaches a given size, then transparently switches to the filesystem.

We can modify the above example to use the php://memory stream instead of hitting the filesystem:

$f = fopen('php://memory', 'w+');
fwrite($f, 'foo');
fwrite($f, 'bar');
 
rewind($f);
$contents = stream_get_contents($f);  //=> "foobar"
fclose($f);

Putting a string inside a fast temporary stream can be very useful. For example, we can then attach filters to that stream.

Testing

Temporary streams are also handy for testing. There are some rather elaborate virtual file system libraries out there but many times a stream is all you need.

Zend_Log has a log handler for streams that accepts either a filename or a stream resource. We can configure it with a php://memory stream for testing:

$f = fopen('php://memory', 'w+');
$writer = new Zend_Log_Writer_Stream($f);
$logger = new Zend_Log($writer);

Assuming your well-designed application has a convenient injection point for the logger instance, your test can pass it in before your test activates some action which should result in logging:

$logger->crit('critical message worth testing');

When the action has completed, the test can rewind $f and use it as a test spy.

rewind($f);
$contents = stream_get_contents($f);
$this->assertRegExp('/message worth testing/i', $contents);  // PHPUnit

Not surprisingly, my unit tests for Zend_Log use this same technique.

Application Usage

Not long ago, we built a custom document storage system for a client. One of its more interesting features is that it integrates with an internet fax service so users can select documents in the system and then fax them. For each fax, the software automatically generates a cover page.

To make the cover page, I first made a nice template using a drawing tool and then saved it in PDF format. I then used Zend_Pdf to write over the template with dynamic content. I first demonstrated this technique in this article.

Since the cover page is only used once (during transmission) and easy to regenerate, I don’t save the output to the filesystem. Instead, I create a php://temp stream. The instance method Zend_Pdf->render() writes the PDF output only to that stream, which is then rewound. Functions like stream_copy_to_stream or fpassthru can then be used to send the final output where it needs to go, and the whole process normally never needs to use the disk.

August 10, 2011

Laura Beth Lincoln Denker

Alternative Thoughts on Sniffs for Useless Method Overriding

Recently I have been playing with PHP_CodeSniffer. First I worked on creating a standard for assessing the cleanliness and efficiency of the PHPUnit tests that are supposed to be unit tests. The belief being that if your unit tests pass this standard, then your tests should have taken less time to write, will take less [...]

June 27, 2011

VG Tech Blog

Unit testing with streams in PHP

Using the memory/temporary stream provided by php:// stream wrapper you  can create a stream with read and write access directly to RAM or to a temporary file.

This gives you the possibilty to write unit tests that does not rely on a specific file, resource or stream, but rather on data provided by the test itself.

Creating a memory stream is easy; $fp = fopen('php://memory', 'r+');. Now you have a resource that can be used and manipulated just like any other stream or file.

June 26, 2011

Laura Beth Lincoln Denker

PHPNW 2011

If you can make it to Manchester, UK for October 7-9, 2011, then you should consider coming to PHPNW 2011. Buy tickets here. The schedule looks fantastic. Sebastian Bergmann and thePHP.cc will be there. Also, from my limited experience with this conference so far, Lorna Mitchell and crew run a very tight ship, which has [...]

June 07, 2011

Laura Beth Lincoln Denker

When to Write Your Own Mocks

Last post I mentioned that there is a time and a place when you could consider writing a mock by hand. It is my humble opinion, that there is only one situation that warrants handwritten mocks: Prototyping. What do I mean by prototyping? When you write an application, or even add a feature to an [...]

June 03, 2011

Laura Beth Lincoln Denker

Testing Your Mocks

Very few times, is it OK to write your own mock class, by hand, for an existing class.  We’ll save the nitty gritty of that statement for a later rant.   If you happen across the very rare instance that you need a hand-written mock, then you will definitely want to write a unit test [...]

May 10, 2011

Quality Assurance in PHP Projects

The English Edition Started Shipping!

The English Edition of the PHP Quality Assurance book started shipping. Stefan and I, as well as all our contributing authors, are very happy about this. Below you can find additional information about the book.

Real-World Solutions for Developing High-Quality PHP Frameworks and Applications

PHP has risen to become one of the most popular programming languages in the world, making high-quality, sustainable applications and frameworks created in PHP more sought after than ever. Using real-world case studies from well-known companies, this valuable book presents the planning, execution, and automation of tests for the different layers and tiers of a web software architecture and explains how these companies measure and test the quality of their software.

  • Looks at the characteristics of good internal and external software quality
  • Shares techniques for writing new code, changing and optimizing existing code, and finding and fixing bugs
  • Reveals bad testing practices so you know what to avoid
  • Addresses how to test service-oriented APIs, a WebDAV server, and many PHP frameworks
  • Reviews large-scale Selenium-based testing and testing database interaction

With this book, you will learn to develop high-quality PHP frameworks and applications that can easily be maintained with reasonable cost and effort.

April 29, 2011

Laura Beth Lincoln Denker

PHP Community Conference 2011

Slides for my talk “Is It Handmade Code If You Use Power Tools?” are now available on Slide Share. As presented at the inaugural PHPComCon in Nashville, TN. Php com con-2011

April 12, 2011

Volker Dusch

Dealing with segfaults while PHPUnit code coverage generation for CI

Oh, the build failed?

Let’s look at the console output!

phpunit
[...]
Return code: 139
[...]
Build FAILED!

sigh. Not again!

The Problem

About half the “Build failed” mails I’ve gotten from Jenkins in the last two weeks where not due to me breaking the tests but just PHPUnit segfaulting. Wait! I know PHPUnit can’t segfault!“, only PHP itself can.

And it does, quite often. For some reason that probably has to do with using PHP 5.2.OLD it doesn’t survive generate the clover.xml file or the HTML report about 20% of the times it’s being run.

This probably could be solved by upgrading PHP but as long as that hasn’t happened on the production servers i don’t want to do that for CI ether and the production env. is on that old version because $randomLameExcuse.

So for now I’d like Jenkins to not send me a mail when that has happened. I don’t want failed builds because of that ether. After playing around with several ideas how i could handle that and discovering that very one of those brought it’s share of new problems. Like telling ant to ignore the segfault it, of course, lets to Jenkins complaining about the clover.xml not being valid an so on. So i resorted to something pretty simple.

The “Solution”

For now I’ll just rerun PHPUnit until it gets there. The script below does, for now, a pretty good job at that.

It wraps the “phpunit” call passing though all parameters. Should PHP segfault the script is run again until something else happens. That PHPUnit return code is than returned by the script.

Sometimes the build takes a little longer (if it runs twice) but so far i haven’t seen it run more than those two times. Even if it should get stuck in an endless loop adding a counter to the script seems pretty trivial. Well, as is the whole problem but it generates useless mails and wastes time, so away with it!

The Code

phpunit-segfault-wrapper

#!/usr/bin/env bash

returnCode=139; # Segfault

echo "Starting PHPUnit Segfault Wrapper";
echo

while [ $returnCode -eq 139 ]
do
    phpunit $*
    returnCode=$?
done

echo
echo "Done with PHPUnit";
echo

exit $returnCode

Placing that file next to your build.xml and a changing the “phpunit” call to a “phpunit-segfault-wrapper” call is all there is left to do.

Disclamer

Chris Cornutt over at phpdeveloper.org pretty much nailed it:

If something was seriously broken, this could cause all sorts of problems, but in theory it’s a simple hack that gets the job done.

Permalink | Leave a comment  »

March 13, 2011

Volker Dusch

Please ship your own coding standard as part of your project

What?

I assume most of you know why we, as programmers, define something called a coding standard for a project.

We create a set of guidelines on how we go about certain aspects of programming. Covering things from indentation over variable naming to more complex topics like whats a too complex piece of code.

Why?

Having a well defined set of rules allows for easier collaboration between members of a project, produces code that looks more like “one person wrote it” and that’s easier to follow, understand and change.

If there would be no written rules it would just make it harder to grasp a project or to contribute to it.

Let me elaborate on the second point: Contribution. Most developers i know care about producing good code, especially then they are contributing to an open source project!

Those people will respect your coding standard, naming scheme and every thing else that they can check for before sending you all patch/pull request. So try to make that part easy.

So?

Now that i spend a few words on why every project should have its own coding standard and what is good for there are two things to consider:

  • Which one to use
  • How to help enforce it

PHP doesn’t tell you what the one true way do go about things is, like python does. So it is even more important to make developers care about what code THIS project looks like.

I don’t want to into the discussion on which one you SHOULD use because this ether asks for a whole new post or just boils done to apply common sense and what works for you works.

So lets talk about ways to enforce it:

You can reformat everything after receiving a contribution. For smaller to medium size projects with one or two main project leads it can work pretty good to just go over a patch and fix everything that doesn’t look right.

I’d like to argue that if you make it easy for people to provide patches that already look good most people will do that. Their indent to do so scales with the amount of trouble they have to go though to do so.

Running one or two cli commands and fixing all errors those tools report is very easy IF those tools only show the errors the developer introduced, if your tools fire out some hundred errors and you ask the contributor to check which one he introduces than chances are he is not going to do so.

How?

While there might be other tools out there I’m only going to talk about PHP_CodeSniffer and the PHP Mess Detector PHPMD. They integrate nicely into Jenkins and let me do everything i want to do when it comes to a coding standard.

Both tools enable to you do define one .xml file with your defined rules

Those files should go somewhere into your project sources. For this post and the example included I’m going to stick with a folder layout that works nicely with http://jenkins-php.org/ and the PHP Project Wizard. Of course every other layout will just work out too.

So if the root project looks like this:

root
|-- source
|-- tests
|-- docs

the suggestion is to create a build folder with a phpcs.xml and a phpxml.xml and putting a build.xml in your project root where you put the exact CLI command to run the tools.

The build.xml is optional but once you start ignoring certain folders other some other I’d have to know about I’d rather have you, the project maintainer, tell me how to run your tools than figuring that out myself.

So the new root folder looks like this:

root
|-- source
|-- tests 
|-- docs
|-- build.xml
`-- build
    |-- phpcs.xml
    |-- phpmd.xml

For now i don’t into the build.xml but once you get into using continues integration you could thing about providing an extra task that also make the TEXT output of the tools accessible.

So i created those file and people checked out my code what can they do now?

Now every developer can run

ant checkcode (or whatever you named the task, i am not to sure myself)

or just

phpcs --standard=build/phpcs.xml source
phpmd source text build/phpmd.xml

and hopefully you created a standard that is maintained and that you care about so those tools will report ZERO errors. (Yes I’ve said that already but it’s really important if you want people to care that the rules you define are maintained. Throw out every rule you don’t plane on following through!)

Now if that contributor goes to change something about your code he can run your tools to make his clean “pretty” before handing it over to you.

Of course the first step after a change is to run your unittests and making sure his change doesn’t break anything. For those tests you might also want to provide a phpunit.dist.xml so that running “phpunit” in the root folder does the bootstrap and runs the tests without the contributor having to know how to run your suite.

You as the maintainer have the added bonus of doing all that yourself.

Wrapping up

When drafting this post i thought about going into the creation of the three .xml files (phpunit.dist, phpmd, phpcs) but this is getting quite long and figuring out how to create those files isn’t that hard. If you want me to elaborate on one of the subjects touched upon here let me now.

Permalink | Leave a comment  »

March 09, 2011

VG Tech Blog

Mocking the file system using PHPUnit and vfsStream

This article is about how to mock the file system when writing unit tests, and it will be rather code-heavy. If you are not familiar with the concept of unit testing this article might not be the best place to start. There will be other articles regarding unit testing on this blog, so keep coming back for more.

Those of you still reading are hopefully familiar with unit testing. PHPUnit is the de-facto standard for unit testing in PHP projects, and this is what we will be using together with vfsStream in this article.

vfsStream is a custom stream wrapper for PHP that works as a virtual file system that PHP’s built in filesystem functions can use. Some functions that work with vfsStream are:

There are some known limitations when using custom stream wrappers. Some functions that does not work with vfsStream:

vfsStreams’ known limitations are listed on its wiki. Now, on to the code!

The following simplified class is the class we will be testing using PHPUnit and the vfsStream stream wrapper:

Show code
class VGF_Storage_Driver_Filesystem {
    /**
     * Root directory
     *
     * @var string
     */
    public $rootDir = null;

    /**
     * Store a file
     *
     * @param string $originalPath Path to the original local file
     * @param string $hash Hash that will be used to identify the new file
     * @return boolean Returns true on success or false on failure
     */
    public function store($originalPath, $hash) {
        return copy($originalPath, $this->rootDir . '/' . $hash);
    }

    /**
     * Delete a file
     *
     * @param string $hash Hash identifying the file we want to delete
     * @return boolean Returns true on success or false on failure
     */
    public function delete($hash) {
        return unlink($this->rootDir . '/' . $hash);
    }

    /**
     * Fetch a file
     *
     * @param string $hash Hash identifying the file we want to fetch
     * @return string Returns the content of the file
     */
    public function get($hash) {
        return file_get_contents($this->rootDir . '/' . $hash);
    }
}

PS! The class is very simplified and does not include error handling at all. It should only be used for instructional purposes.

As you can see the class uses regular file system functions such as copy, unlink, and file_get_contents. To be able to get full code coverage on this class all these functions need to work their magic.

A typical way to solve this when writing tests is to create files/folders in PHPUnit’s setUp() method and remove them again in the tearDown() method. This works, but if your tests somehow dies (fatal error for instance) during a test run you are left with files/folders on disk that was never cleaned up. vfsStream does not touch the file system at all, but keeps virtual files and folders in memory, so if your test suite dies there is nothing on disk that was not there before you started the tests. Also, if you manage to sneak in a bug that deletes more files than it should it’s safer to work on a virtual file system than an actual one.

Now, lets take a look at the basics of vfsStream. First you will need to install it. This can be done easily using PEAR:

$ pear channel-discover pear.php-tools.net
$ pear install pat/vfsStream-beta

After installation make sure the vfsStream directory is in your include path. If you have a sane PEAR environment you are most likely good to go.

The following snippet will show you the basics of vfsStream:

Show code
<?php
require_once 'vfsStream/vfsStream.php';

vfsStreamWrapper::register();
$root = vfsStream::newDirectory('someDir');
vfsStreamWrapper::setRoot($root);

var_dump(is_dir(vfsStream::url('someDir'))); // true
var_dump(is_file(vfsStream::url('someDir'))); // false
var_dump(is_dir(vfsStream::url('someOtherDir'))); // false

$file = vfsStream::newFile('someFile');
$root->addChild($file);

var_dump(is_file(vfsStream::url('someDir/someFile'))); // true
var_dump(file_exists(vfsStream::url('someDir/someFile'))); // true
var_dump(is_file(vfsStream::url('dir/someOtherFile'))); // false

unlink(vfsStream::url('someDir/someFile'));
var_dump(file_exists(vfsStream::url('someDir/someFile'))); // false

First we simply require the main vfsStream class (that in turn will require other components as well). The next three lines registers the stream wrapper (which defaults to vfs://) and creates the root directory which vfsStream will use as a container for other virtual files and directories. These three lines can be replaced by:

Show code
$root = vfsStream::setup('someDir');

which is a convenience method that will be used in the unit tests later on.

The vfsStream::url method that is used in the code snippet above creates the path that the file system functions must use. It will simply prepend the schema to the file/directory name.

Show code
var_dump(vfsStream::url('someDir')); // "vfs://someDir"

The next few lines in the code snippet just illustrates how the regular file system functions work with vfsStream.

To add a file we first create a new vfsStreamFile object by calling vfsStream::newFile() which simply takes a filename as argument. We attach it to the root directory by using the root object’s addFile method. After this we do some file system checks for the file, remove it, and check again. As you can see all this is pretty similar to working with regular files.

Now that we have the basic usage of vfsStream out of the way, let’s move on to how to incorporate this into our tests. The below code snippet is the test class without any actual tests as we’ll add them later on.

Show code
<?php
require_once 'vfsStream/vfsStream.php';

class VGF_Storage_Driver_FilesystemTest extends PHPUnit_Framework_TestCase {
    /**
     * Driver instance
     *
     * @var VGF_Storage_Driver_Filesystem
     */
    protected $driver = null;

    /**
     * Setup method
     *
     * This method will register the vfsStream stream wrapper and create a new instance of the driver
     */
    public function setUp() {
        vfsStream::setup('someDir');
        $this->driver = new VGF_Storage_Driver_Filesystem();
        $this->driver->rootDir = vfsStream::url('someDir');
    }

    /**
     * Tear down method
     *
     * This method will destroy the instance of the driver
     */
    public function tearDown() {
        $this->driver = null;
    }
}

As you can see from the code snippet we use the vfsStream::setup method to create a root dir, and set that dir as the rootDir in the driver. No action is needed in the tearDown() method regarding vfsStream. The first test we will write shall test the store method.

Show code
/**
 * Test the store method in the driver
 */
public function testStore() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();

    $this->assertFalse($root->hasChild($hash));
    $this->assertTrue($this->driver->store(__FILE__, $hash));
    $this->assertTrue($root->hasChild($hash));
}

First we create a random hash value that will be used to identify the file internally in our driver. Then we make sure the file does not exist prior to running the store method. After storing the file we assert that it now exists. The vfsStreamWrapper::getRoot() method returns the root vfsStreamDirectory object, on which we call the hasChild() method to see if it has a child with a given name.

Next up is the delete method:

Show code
/**
 * Test the delete method in the driver
 */
public function testDelete() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();
    $root->addChild(vfsStream::newFile($hash));

    $this->assertTrue($root->hasChild($hash));
    $this->assertTrue($this->driver->delete($hash));
    $this->assertFalse($root->hasChild($hash));
}

This is pretty much the same as the previous test method except that we register a virtual file before calling delete(). After deleting we assert that the file is actually gone. Now for the last test:

Show code
/**
 * Test the get method in the driver
 */
public function testGet() {
    $hash = md5(microtime());
    $content = 'some content';
    $file = vfsStream::newFile($hash);
    $file->setContent($content);
    vfsStreamWrapper::getRoot()->addChild($file);

    $this->assertSame($content, $this->driver->get($hash));
}

In this last test method we create a virtual file with content by using the setContent() method on the vfsStreamFile object. After adding the virtual file we assert that we get the same content when fetching the file identified by $hash.

And that’s that! If anyone has used vfsStream differently or has related questions, don’t hesitate to leave a comment. Happy testing!

Related links:

Quality Assurance in PHP Projects

PHPQABOOK: Status Update

Almost a year has passed since we finished the manuscript for the German edition of the book -- and almost half a year since the German edition started shipping. High time for another status update.

The video below shows a visualization of activity in the book's Git repository since April 2010. During this timeframe we mostly worked on translating chapters from English to German and editing the chapters for the German edition followed by translating chapters from German to English and editing the English edition's chapters.



As you can see from the video, the work on the English edition is now complete and the Git repository is quiet. The English edition is scheduled to ship on May 10, 2011 under the title "Real-World Solutions for Developing High-Quality PHP Frameworks and Applications".

February 02, 2011

Volker Dusch

Setting up Jenkins for PHP Projects


One and a half month ago i wrote a little guide about Setting up Hudson for PHP Projects in 15 minutes, called it a first draft and got quite some feedback and retweets (even a flattr!) from which i assume it wasn't total crap. Thank you :)

Since then two relevant important things happened. Hudson got renamed to Jenkins moved away from http://hudson-ci.org/ (which oracles still supports afaik) and over to http://jenkins-ci.org/. I'll be talking about the site with the "Like" Button, not the one with the oracle logo from now one. While this was happening Sebastian created the wonderful http://jenkins-php.org/ and polished the setup instructions that are now featured there with me contributing some minor details for the new phploc graphs.

So for me it was time to update the guide, especially because you now get even more features and nice graphs and some issues have been resolved. If you followed the old tutorial i recommend you create a new job now.. but i'm getting ahead of my self.

This guide will feature two parts. The first one beeing the obligatory "why do i need this" or maybe the "why, dear friend or coworker who i send this link do YOU / WE need to install this" resulting in a (spoiler): Because it's fucking awesome !

Why ? (Scroll down for 'Installing! ') 

For starters let's talk about what Jenkins is: 

Jenkins is a continuous integration server !

Ok, that was helpful !

What is continuous integration server then ?

For starters think of it as a glorified "cron" job with a nice web interface. It's a piece of software that is build around the notion that it would be a really good idea to see if another piece of software you are currently developing "works" all the time. Since "works" is a pretty loose definition that also varies greatly among different types of Software these servers tend to be pretty flexible and open. For a longer explanation check Wikipedia. 

Why do i want one and what do i to with it ?

So PHP developers the last few years where awesome don't you think ? Many of us stopped "programming" and started "creating software", our language matured greatly, got a pretty solid object model and more and more "really big" projects are written in PHP. Since you need more people to write one of those than you needed to hack together a guest book site there is a growing strife to "quality software". Without going to much into detail for most people that boils down to stuff like automated testing and some sort of quality control.

I'll just assume you heard of Unit Testing using PHPUnit and that you have written some tests or that you have some other way of making sure your software "works". While this is great it can be pretty tedious to run the whole test suite every time before a commit but not doing it leads to a broken test suite that other people have to repair or go around asking who broke it.. make up your own story.

This is where a continuous integration (ci) server jumps in !

Every time you commit, or push if you're using git, to a repository it detects the change, gets the new version of the source, runs all your tests (and more if you tell it to) and notifies you if there was a problem.

Why Jenkins

If there is one thing i really despise about software then it is installing it. I want to spend my time DOING stuff with that software not setting it up and reading some installation guides that feel longer than my thesis.

In that regard Jenkins was an epiphany, a ci server that is _running_ on my machine in less than 5 minutes time regardless of the system I'm current working on. It's faster to install than to search for a "show demo" link !

And of course it's really powerful having easy-to-install plugins for just about everything you can think of while being fast, stable and now problem to maintain at all.

Coming from the Java world Hudson features a variety of quality measurement tools that are integrated into the ci server via plugins. The "big" one beeing xUnit (PHPUnit) for Unit Testing and to name same other ones: checkstyle (php code sniffer) for making sure your code matches our coding standards, pmd (phpmd) for mess detection that tells you about too complex structures and much much more or pmd-cpd (phpcpd) the copy paste detector that lets you find duplicate code blocks.

Jenkins and PHP ?

For some time it was some hassle to get a full blown PHP project running. While most of the php-qa-tools, some named above, feature a way of outputting a xml file that is compatible with the corresponding Java tool and integrates nicely into Jenkins there was the need to look into every tool to find the switch, put it in place and tell Jenkins where to find the output file.

Then there was php-hudson-template, a small Github project started by Sebastian that took away most of the hassle.

Now there is an updated version of the the project on http://jenkins-php.org/ and while only details changed those little changes are going to make it even easier to get something running before you HAVE to care about how everything works.

Installing!

While Jenkins runs on pretty much anything for this guide i will be using Ubuntu 10.10.

I'll go through the parts of the setup that aren't described on the tutorial and send you there for some of the steps and copy/pasting since that page will be updated and this blog post most likely will not, at least not as frequently.

After a fresh installation of Ubuntu we ofc. need a PHP and we'll install and update the PEAR installer while we are at it so you won't run into any troubles with all the great phpqa tools.

sudo apt-get install php5-cli
sudo apt-get install php-pear
sudo apt-get install php5-xdebug

and please make sure you have xdebug activated. The error messages are not really helping you in case you forgot to write it in your php.ini ;)

php -r "var_dump(extension_loaded('xdebug'));"

To install Jenkins follow http://pkg.jenkins-ci.org/debian/ or if you are not on Ubuntu pick the system of your choosing on http://jenkins-ci.org/. That will also take care of most the dependencies.

For anything else that is needed:

sudo apt-get install ant
sudo apt-get install git

Let's create an example project now:

cd ~
mkdir mydemo
cd mydemo
git init
mkdir src tests
touch build.xml build.properties phpunit.xml.dist src/MyClass.php tests/MyClassTest.php
echo "build" > .gitignore
echo "source=\${basedir}/src" > build.properties
git add src tests .gitignore build.xml build.properties
phpunit.xml.dist
git commit -m"Inital dump"

Now head over to the guide and:

  • Install the Jenkins Plugins
  • Install the required PHP Tools
  • Copy the build.xml into your stuff into your build.xml
  • Copy the following in your phpunit.dist.xml
  • In addition to the other install commands run: " java -jar jenkins-cli.jar -s http://localhost:8080 install-plugin git " since we are using git for this example

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
   backupStaticAttributes="false"
   syntaxCheck="false">

<testsuites>
   <testsuite name="php-demo">
     <directory suffix="Test.php">tests</directory>
   </testsuite>
</testsuites>
<logging>
  <log type="coverage-html" target="build/coverage" title="php-demo"
   charset="UTF-8" yui="true" highlight="true"
   lowUpperBound="35" highLowerBound="70"/>
  <log type="coverage-clover" target="build/logs/clover.xml"/>
  <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>

and fill your class and test with some code:

<?php
class MyClass {
    public function demo($a) {
        if($a == 1) {
            return 1;
        }
        return 0;
    }
}

And a sample test for "tests/MyClassTest.php"

<?php

require_once("src/MyClass.php");

class MyClassTest extends PHPUnit_Framework_TestCase {

    public function testDemo() {
        $x = new MyClass();
        $this->assertEquals(1, $x->demo(1));
    }
}

Commit into git and let's get to the last step !

cd ~/mydemo
git commit -am"Lets do this"
 cd /var/lib/jenkins/jobs
sudo git clone git://github.com/sebastianbergmann/php-jenkins-template.git php-template
sudo /etc/init.d/jenkins stop
sudo /etc/init.d/jenkins start

Now head back over to the guide and run through step 3 to finish

 

For "Fill in your 'Source Code Management' information." use

"Git" and for the path use

file:///home/YOUR_USERNAME/mydemo

DONE !

Click "Build now" two times and  look at all the pretty graphs.

 

I hope this got you started. This is the secound draft of this guide and if you have something to add or ran into any problems please leave me a comment.

Permalink | Leave a comment  »

January 20, 2011

Volker Dusch

Creating your custom PHPUnit output formats

While tackling with someones question i decided it's time to play around with xslt for learning purposes and i found something useful to do.

He wanted to extend the --testdox-html output and i proposed to just transform phpunits xml output using an xslt since i didn't see a easy way to prove a custom implemenation for PHPUnit/Util/TestDox/ResultPrinter/HTML.php and i didn't want to change the file its self.
So let's play around a bit.
A simple test:
<?php
class DemoTest extends PHPUnit_Framework_TestCase {

  public function testPass() {
    $this->assertTrue(true);
  }

  public function testFail() {
    $this->assertTrue(false);
  }
}
and generate some xml, for that test i used the junit output:
phpunit --log-junit foo.xml DemoTest.php
and write a simple xslt. It might not be the best way to do that but like i said: I'm just looked for something to learn about xslt so correct my if i'm wrong.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h1>Tests</h1>
    <xsl:for-each select="testsuites/testsuite">
      <h2><xsl:value-of select="@name"/></h2>
      <ul>
        <xsl:for-each select="testcase">
          <li>
            <xsl:value-of select="@name"/>
            <xsl:if test="failure">
              <b>Failed !</b>
              <i><xsl:value-of select="*"/></i>
            </xsl:if>
          </li>
        </xsl:for-each>
      </ul>
    </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
and using that with the xml output using a linux command line tool:
xsltproc foo.xsl foo.xml > output.html 

and that produces a nice litte html files:
<html>
<body>
  <h1>Tests</h1>
  <h2>DemoTest</h2>
  <ul>
    <li>testPass</li>
      <li>testFail<b>Failed !</b>
      <i>DemoTest::testFail
      Failed asserting that &lt;boolean:false&gt; is true.
      /home/edo/DemoTest.php:10
      </i>
    </li>
  </ul>
</body>
</html>
To make at least something a litte more useful out of that blog post:
I'm planing about writing about usecases for phpab and on how to ship your PHP_CodeSniffer coding standard with your project. If you have further suggestions i'd like to hear them.

Permalink | Leave a comment  »

January 18, 2011

Christian Schaefer

When embracing Separation of Concerns code reorganisation can be a bliss!

The design pattern that should be most repeatedly talked about should be Separation of Concerns (that’s why I’m doing that all the time).

Recently working on ImageTransform I decided to do a big refactoring during which I had to move around a lot of classes as I reorganised the folder structure. This of course includes changing a lot of namespaces.

Usually something like this would drag a lot of work behind. Unless..

Unless you cared for your classes to be decoupled.

Take a look at this commit.

You can see that a lot of classes moved namespaces and of course there is a lot of code touched to acknowledge this.

However this wasn’t much work. Mostly done by automatic substitution.

Even most of my PHPUnit tests still passed during the process!

All together the refactoring (of a few more commits than just the one) took about one hour in total.

Currently  there is a discussion on the Symfony mailing list that will probably result in a similar refactoring only on a much bigger scale. Still I think that it will not take significantly longer. ;)

January 13, 2011

Christian Schaefer

PHP 5.3 and the Symfony2 UniversalClassLoader – Where to load?

While working on my rewrite of the ImageTransform library I decided to follow the PHP Standards Working Group proposal for naming schemes as well as using the new Symfony2 UniversalClassLoader.

But I’m not yet sure what is the best approach to use this loader.

When I started looking for examples I sent a small tweet which was replied to by Stefan Koopmanschap as he used this class loader in one of his own libraries.

What he did is to include the class/namespace registering code in one of the central classes of his library. If you take a look at my code you will see the same approach.

However this will not deliver instant plug’n'play imho as you still have to require this one class file to trigger the registration.

The more I think about the more I come to the conclusion that it is not advisable to include automatic class loading in library code as the user of your library still has to do it on his own even if you do some of it for him. This also puts the decision what kind of loading mechanism to use back in his hands.

The library code should assume that there is a loading mechanism in place thus not implementing any of its own nor hard wiring with require().

I actuaally realized that when I wrote the bootstrap file for my PHPUnit tests. Unit tests are client code that use parts of the library they test. If they would have to include this central class only to have all other classes of the library available then this would be a case of coupling that I wanted to get rid of in the first place.

So instead of including calls to UniversialClassLoader I will eventually only mention it in the docs I think.

January 12, 2011

Christian Schaefer

The ideal use case to give TDD a try!

What I called my “little experience” during the last two days is actually the attempt to rewrite the image manipulation library ImageTransform by Stuart Lowes, which itself is the attempt to turn the symfony plugin sfImageTransformPlugin into a standalone library (unfinished). It’s not at all official and it might be binned again at some point. Until I know that it stays my personal toy.

One of the goals I set myself is to make the code as decoupled as possible and to prove that I try to maintain a high unit test coverage.

Today I just wrote my first transformation using this new architecture and it was just perfect to do it test driven: the resize transformation.The resize transformation resizes an image considering whether to keep proportions, whether inflation or deflation is allowed and if the target dimension sets the maximum or minimum frame.

So four things have to be considered that effect the outcome. That’s 16 different combinations!

Then the original image can be smaller or bigger than the target dimensions or it can be smaller on one side and bigger on the other or it can be the the same. That’s 5 starting situations!

All in all that’s 80 different results!

And it is extremely tedious to test them all by hand of course..

Now I said a few times that I never really got the hang of TDD. Writing tests first still doesn’t feel natural to me though I intellectually accept it being superior to my way of coding.

But in a situation like this even I started writing a test case before a single line of code!

The test itself could not be simpler.

Much more complicated was to write down the correct results for examples for all 80 situations. But PHPUnits awesome @dataProvider feature is a big big help here!

With this test in place I was able to implement a rather complicated algorithm in very little time and what’s more I am very confident that it’s correct because the test says so! ;)

January 11, 2011

Christian Schaefer

Automatic class loading and naming conventions with Symfony2, PHPUnit and PHP 5.3

I mentioned yesterday that I am toying around with some little library code that is completely standalone.

As I plan on using this code in a Symfony2 project later I chose to finally switch to PHP 5.3 including namespaces.

And as soon as I started I needed to decide on a naming convention for my classes, a directory structure, a convention to name my PHPUnit tests and a way to autoload these classes to avoid require statements.

Of course I don’t fancy to come up with all that on my own. In fact I’d rather prefer to use existing conventions and luckily I found one that is used in Symfony2 but was in fact created by a group of PHP developers worldwide from all kinds of projects including the Zend Framework. This group of people is called the PHP Standards Working Group and they agreed on a paper called PSR-0 Final Proposal.

Everything defined in there pretty much reminds me of the Zend Framework conventions only much much simpler as namespaces are a very efficient way to organise code.

So I went and created a simple dummy library with the following:

  • Two stupid classes with one method each
  • Two PHPUnit tests
  • All namespaces set up just like in Symfony2 for library code as well as unit tests
  • A demonstration of a namespace type hint
  • A PHPUnit configuration file for distribution
  • A bootstrap file initialising the Symfony2 universal class loader

I think for those of you interested it will be far more convenient to take a look on GitHub or clone the sources instead of me writing down snippets of code. So here you can find my example code on GitHub.

You can see it’s dead simple. Even the autoloading is nicely tucked up.

Tell me what you think!

January 10, 2011

Christian Schaefer

Productivity gain when PHPUnit testing decoupled code

Over the weekend I started writing some code just to try out a few ideas. Over the last four years I have been writing a lot of code but best of it was related to symfony. So this was a nice situation to start something from scratch.

Of course I experienced a lot during the past and also did I learn a lot from participating – actively and passively – in the symfony community. The most important fact I learned is that the key principle of programming that decides about if your code gets manageable is: Separation of Concerns.

And with my small experiment I also learned that following it reduces the time you spend writing unit tests!Of course it sounds reasonable that it will be easier to write unit tests for decoupled code than for coupled ones and I would always have nodded right away. But it is only when you experience such a situation that you realise how much productivity coupled code costs you!

For my experiment I followed Separation of Concerns by using Dependency Injection instead of hard wiring the dependencies. So instead of calling the new operator in my classes methods I create those needed instances outside of these classes and pass them as attributes to constructors or mutators or as arguments to methods that act on them.

Instantly my PHPUnit test cases became simple as A B C.

For symfony plugin code I always needed to bootstrap a lot to make the dependencies available.

  • Often you needed to bootstrap symfony to get sfContext available.
  • Often you needed to boostrap symfony to make the configuration available needed for some of the classes depending on.
  • Often you even needed a database connection fired up as doctrine required that for almost everything.

All because of hard wired dependencies inside symfony and doctrine.

Knowing this is simple and understanding this just as well. But after experiencing it I conclude that the productivity gain for writing unit tests is about two thirds! I only needed a third of the time writing PHPUnit code that I needed in coupled sources.

Even refactoring the unit tests when changing the architecture now couldn’t be simpler.

That’s another good reason to look forward to Symfony2 and Doctrine 2.

December 31, 2010

Mike Lively

Pear Channel set up for Phake

For those that may not have caught my first post on the subject, Phake is a mock framework that I announced a couple of days ago in Introducing Phake Mocking Framework. It was recommended in the comments that I get it on a pear channel somewhere, which is something I have wanted to do but hadn’t had a reason to do until this week. Well, now there is an official Digital Sandwich Pear Channel that is hosting Phake. So if you want to play around with Phake you can install it like this:

pear channel-discover pear.digitalsandwich.com
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha

Also, a couiple quick little side notes, the only reason I am still considering this an alpha is the lack of exhaustive, centralized documentation. The Phake Wiki has some good details as does my previous post but I would like to get more official documentation up soon at which put it into a full beta. The api right now should be considered stable however. It will not be changing short of huge issues. We have been using it in production testing at my company for a little while no with great success. So, if the label of ‘alpha’ makes you nervous, don’t worry. It’ll be okay.

Lastly, this library is compatible with PHP 5.2. I never really mentioned that in my last post either. It is not currently utilizing any php 5.3 functionality and I have no plans to break this backwards compatibility any time soon.

December 29, 2010

Mike Lively

Introducing Phake Mocking Framework

I have used PHPUnit heavily now for the last 4 years. As anyone that is heavily involved in writing Unit Tests knows, test doubles (commonly referred to as mock objects) are a necessary part of your toolbox. The mocking options that we used to have for PHP unit testing have traditionally been fairly limited and most all of them in some form or another were ports of JMock. The way PHP operates as well as some decisions made to more closely emulate how JMock does things lead to functionality in the existing mock library for PHPUnit that for some are a hassle. This ranges from PHPUnit implicitly calling the “mockee’s” constructor (you have to explicitly specify that you do not want to call the constructor) to the pain of trying to stub or verify multiple invocations of the same method with different parameters.

Over the last three years, my experience as well as the musing of some of my colleagues has led me to believe that a lot of what I don’t like about mocking in php is the result of the fundamental notions of combining stubbing with verification and setting expectations ahead of method calls instead of verifying that what you expected to happen has indeed happened. This was essentially proven to me over the last year and a half as I have been heavily working with Java code and as a result have been using the Mockito mocking library for Java. The result of this work is the Phake Mocking Framework.

Now I am fairly certain that at least 5 or 6 people (which may constitute everyone who reads this) are rolling their eyes by now. So instead of going further into why I like this style of mocking I’ll just show you how to use it. Phake was designed with PHPUnit in mind, however I don’t really see any reason why it couldn’t be used in other testing frameworks as well. It is on my roadmap to confirm support for other frameworks. In any case, I will be using PHPUnit for my examples.

This document assumes you already have a good understanding of the basics of mocking. If the terms ‘Mocking’, ‘Stubbing’, and ‘Test Doubles’ mean nothing to you, I would recommend checking out the following links:

Getting Started

You can get a copy of Phake from Github. If you are familiar and comfortable with with git you can just clone my repository. If you would rather avoid the trappings of Github, you can also download Phake’s latest release tarball. Either way will result in a directory with two subdirectories: src and test. You will want to move the contents of the src directory to somewhere in your include path (such as /usr/share/php). Once you have done this, you can simply include “Phake.php” in any of your tests or in your bootstrap script and you will be off to the races.


UPDATE!!!

I just set up a pear channel to distribute phake as well. So if you would like to install Phake using pear, just do the following:

pear channel-discover pear.digitalsandwich.com
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha

To show you some of the basics of how to use this framework, I am going to write various bits of codes to mock, verify, stub, etc the following class:

<?php

class MyClass
{
    private $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function getValue()
    {
        return $this->value;
    }

    public function subtract($int)
    {
        return $this->value - $int;
    }
}

?>

Stubbing

<?php

require_once 'Phake.php';
class Test extends PHPUnit_Framework_TestCase
{
    public function testStubbingGetValue()
    {
        // Sets up the mock object.
        // Analogous to $this->getMock() in PHPUnit
        $mock = Phake::mock('MyClass');

        // Builds the stub for getValue.
        // Essentially any call to getValue will return 42
        Phake::when($mock)->getValue()->thenReturn(42);

        $this->assertEquals(42, $mock->getValue());
    }
}

You can also do conditional stubbing based on passed in parameters.

<?php
    public function testStubbingGetValue2()
    {
        $mock = Phake::mock('MyClass');

        // You can pass parameters into the stubbed method to indicate you
        // only want to stub matching invocations. By default, anything
        // passed in must be loosely matched ('==')
        Phake::when($mock)->subtract(42)->thenReturn(30);

        $this->assertEquals(30, $mock->subtract(42));

        // It is important to note that any unstubbed calls will return null.
        // Since 41 != 42 this call will return null.
        $this->assertNull($mock->subtract(41));
    }

If a specific invocation or call of a mock object has not been stubbed, it will return null. This behavior is different than the default behavior of PHPUnit’s mocking framework. If you need the default PHPUnit behavior then you could use something called partial mocks. Partial mocks are setup to call the constructor of the class being mocked and for any call that has not been stubbed, the parent method will be called.

<?php
    public function testStubbingGetValue3()
    {
        // Creates a mock object whose constructor will call
        // MyClass::__construct(42);
        $mock = Phake::partMock('MyClass', 42);

        Phake::when($mock)->subtract(42)->thenReturn(0);

        // Since 18 != 42, the real method gets call
        $this->assertEquals(24, $mock->subtract(18));
    }

You can also specify on a per call basis that you want to call the parent, using the thenCallParent() method instead of thenReturn(). The different values you can use for stubbing are referred to as ‘Answers’. Here are a list of them and what they will do when a matching invocation is called:

  • thenReturn(mixed $var) – Will return the exact value passed in.
  • thenCallParent() – Will return the results of calling the mocked parent method.
  • thenThrow(Exception $e) – Will throw $e.
  • captureReturnTo(&$variable) – Acts exactly like thenCallParent() however it also captures the value that the parent returned to $variable. This allows you to run assertions. This comes in very handy for testing legacy code with protected or private factory methods whose return values are never returned out of the tested method’s scope.

The other thing to take note of stubbing is that any PHPUnit constraints are supported.

<?php
    public function testStubbingGetValue4()
    {
        $mock = Phake::mock('MyClass');

        //Matches any call to subtract() where the passed in value equals 42
        Phake::when($mock)->subtract(42)->thenReturn(30);
       
        //Matches any call to subtract() where the passed in value is less
        // than 42. Notice that this is a phpunit constraint
        Phake::when($mock)->subtract($this->lessThan(42))->thenReturn(29);

        $this->assertEquals(30, $mock->subtract(42));
        $this->assertEquals(29, $mock->subtract(41));
    }

This gives you the same kind of stubbing flexibility that you have present in PHPUnit.

Verification

Verifying that methods on your stub are called is starkly different then how it is done in PHPUnit. The most apparent symptom of this difference is that you verify calls after the calls to your test methods have been made.

<?php
    public function testVerify1()
    {
        // You can apply stubbings and verifications to the same mock objects
        $mock = Phake::mock('MyClass');

        $mock->getValue();

        //Notice, getValue() has already been called
        Phake::verify($mock)->getValue();
    }

You of course have the same matching functionality at your disposal.

<?php
    public function testVerify2()
    {
        $mock = Phake::mock('MyClass');

        $mock->subtract(40);

        //Notice the constraint
        Phake::verify($mock)->subtract($this->lessThan(42));
    }

By default, verify only allows a single matching invocation. You can also specify that a specific number of invocations should be allowed.

<?php
    public function testVerify3()
    {
        $mock = Phake::mock('MyClass');

        $mock->subtract(40);
        $mock->subtract(39);

        //The number of times is passed as the second parameter of
        //Phake::verify()
        Phake::verify($mock, Phake::times(2))->subtract($this->lessThan(42));
    }

You can also use Phake::atLeast($n) and Phake::atMost($n) instead of Phake::times($n).

You can also specify that you don’t expect there to be any interactions with a mock.

<?php
    public function testVerify4()
    {
        $mock = Phake::mock('MyClass');

        // This will ensure that UP TO THIS POINT no methods on $mock have
        // been called
        Phake::verifyNoInteraction($mock);

        // This would not result in an error, this can be prevented with
        // another method explained below
        $mock->getValue();

    }

I am sure you noticed the comment that Phake::verifyNoInteraction() only verifies that no calls were made up to that point. You can essentially freeze a mock with another method

<?php
    public function testVerify5()
    {
        $mock = Phake::mock('MyClass');

        $mock->getValue();

        // This will ensure that no methods on $mock will be called after this
        // point
        Phake::verifyNoFurtherInteraction($mock);
    }

There are a few more advanced things you can do with something called argument captors.

<?php
    public function testVerify6()
    {
        $mock = Phake::mock('MyClass');

        $mock->subtract(42);

        // Phake::capture tells Phake to store the parameter passed to
        // subtract as the variable $val
        Phake::verify($mock)->subtract(Phake::capture($val));

        $this->assertEquals(42, $val);
    }

This is a very pedestrian example, but it is not that uncommon for fairly complicated objects to passed in and out of methods. Argument capturing allows you to much more succinctly assert the state of those types of parameters. It is definitely overkill for asserting scalar types or simple objects.

More to Come

This really does cover the very basics of the Phake framework. In the coming days I will be putting out smaller more focused articles discussing some of the specific functionality. In the meantime I would love to get some feedback from anyone who is brave enough to play with this. My future roadmap basically involves shoring up the current code base a little bit more, adding a few pieces of missing or suboptimal functionality (I’m not so sure I have implemented ‘consecutive calls’) but I anticipate releasing an RC version no later than the end of January. Also, I am currently using and monitoring the issue tracker for Phake at github, so if you have some functionality you would like or find any bugs in your exploring, you can also open an issue there. Also, if you would like to help out with contributions, they are certainly welcome.

December 19, 2010

Volker Dusch

Setting up Hudson for PHP Projects in 15 minutes

Please see here for an updated version of this guide

Some of the information in this post is out of date so just head over to the newer one.

---------------------------------------------- Old post ---------------------------------------------------------------------

Preface:

This is the first draft oft this guide, if you have corrections or comments please let me know. 

 If you know that Hudson is and just looking for the "install guide" just skip over the first five paragraphs right to "Installing"

Wait, what is Hudson ?

Hudson is a continuous integration Server !

Ok, what is continuous integration Server then ?

For starters think of it as a glorified "cron" job with a nice web interface. It's a piece of software that is build around the notion that it would be a really good idea to see if another piece of software you are currently developing "works" all the time. Since "works" is a pretty loose definition that also varies greatly among different types of Software these servers tend to be pretty flexible and open. For a longer explanation check Wikipedia.

Why do i want one and what do i to with it ?

So PHP developers the last few years where awesome don't you think ? Many of us stopped "programming" and started "creating software", our language matured greatly, got a  pretty solid object model and more and more "really big" projects are written in PHP. Since you need more people to write one of those than you needed to hack together a guest book site there is a growing strife to "quality software". Without going to much into detail for most people that boils down to stuff like automated testing and some sort of quality control.

I'll just assume you heard of Unit Testing using PHPUnit and that you have written some tests or that you have some other way of making sure your software "works". While this is great it can be pretty tedious to run the whole test suite every time before a commit but not doing it leads to a broken test suite that other people have to repair or go around asking who broke it.. make up your own story.

This is where a continuous integration (ci) server jumps in !

Every time you commit, or push if you're using git, to a repository it detects the change, gets the new version of the source, runs all your tests (and more if you tell it to) and notifies you if there was a Problem.

Why Hudson ?

If there is one thing i really despise about software then it is installing it. I want to spend my time DOING stuff with that software not setting it up and reading some installation guides that feel longer than my thesis.

In that regard Hudson was an epiphany, a ci server that is _running_ on my machine in less than 5 minutes time regardless of the system I'm current working on. It's faster to install than to search for a "show demo" link !

And of course it's really powerful having easy-to-install plugins for just about everything you can think of while being fast, stable and now problem to maintain at all.

Coming from the Java world Hudson features a variety of quality measurement tools that are integrated into the ci server via plugins. The "big" one beeing xUnit (PHPUnit) for Unit Testing and to name same other ones: checkstyle (php code sniffer) for making sure your code matches our coding standards, pmd (phpmd) for mess detection that tells you about too complex structures and much much more or pmd-cpd (phpcpd) the copy paste detector that lets you find duplicate code blocks.

Hudson and PHP ?

For some time it was some hassle to get a full blown PHP project running. While most of the php-qa-tools, some named above, feature a way of outputting a xml file that is compatible with the corresponding Java tool and integrates nicely into Hudson there was the need to look into every tool to find the switch, put it in place and tell Hudson where to find the output file.
Nowadays there is php-hudson-template, a small Github project started by Sebastian Bergmann that takes all that hassle away too.

Installing: In 15 minutes you will be done !
If you read the preface: Nice to see you are still here. Lets get going !


For the course of this tutorial we will be setting everything up using a clean Linux installation. Adaption to other distributions should be easy since Hudson and php will work the same everywhere.

We will be using:
- Ubuntu 10.10 x86 desktop edition

We are going to install and setup:

- Hudson, PHP and Git (Of course you can use pretty much any scm you want but we'll need git later anyways so i go with it)
- PHPUnit, many php qa tools
- A Hudson project that will make use of all those tools

Starting with the basics:

sudo apt-get update
sudo apt-get install default-jre php5-cli ant daemon git-core

Your package manager will also install all the other java related programms so we are good to go for Hudson

Ubuntu:
wget -O /tmp/hudson.deb http://hudson-ci.org/latest/debian/hudson.deb
sudo dpkg --install /tmp/hudson.deb

Any other *nix:
Check the front page of http://hudson-ci.org/

Or if hudson isn't packaged for you it's very easy too:

wget http://hudson-ci.org/latest/hudson.war
java -jar hudson.war

Now you can check http://localhost:8080 to see Hudson running.

After that we'll get going with the php parts of your shiny new Hudson.

Following php-hudson-template

From here on out you can just follow the instructions provided by Sebastian on github but for the sake of "one page to follow and get everything set up and copy/paste as much as possible" i'll rewrite it here.

From here on out the tutorial is out of date now - Stick to the guide on github

-----

Current changes to hudson, the plugins and that i discovered that the "use publishers from another project" doesn't work out quite well. The guide on github got updated accordingly pretty quick and using it and checking back here should work out well for you.

I'll try to rewrite the tutorial in the next week and maybe the github guide too.

-----

First off we need to install 10 Plugins, thats quite boring to do with the Interface so you could use the Hudson-cli

wget http://localhost:8080/jnlpJars/hudson-cli.jar
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin checkstyle
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin dry
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin htmlpublisher
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin jdepend
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin pmd
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin template-project
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin violations
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin xunit
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin clover
java -jar hudson-cli.jar -s http://localhost:8080 install-plugin git

If that doesn't work just go to http://localhost:8080/pluginManager/available and install the plugins by hand:

  • Checkstyle
  • DRY
  • HTML Publisher
  • JDepend
  • PMD
  • Template Project
  • Violations
  • xUnit
  • Clover
  • Git

Restart Hudson while that is running lets install all the PHP Tools:

First of we need the "pear" installer and the xdebug extension:

sudo apt-get install php-pear php5-xdebug

Then register all the relevant pear channels:

sudo pear channel-discover pear.pdepend.org
sudo pear channel-discover pear.phpmd.org
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover components.ez.no
sudo pear channel-discover pear.symfony-project.com

And install all the tools:

sudo pear install pdepend/PHP_Depend-beta
sudo pear install phpmd/PHP_PMD-alpha
sudo pear install phpunit/phpcpd
sudo pear install PHPDocumentor
sudo pear install PHP_CodeSniffer
sudo pear install --alldeps phpunit/PHP_CodeBrowser-alpha
sudo pear install --alldeps phpunit/PHPUnit

Setting up a demo project

cd ~
mkdir mydemo
cd mydemo
git init
mkdir src tests
touch build.xml phpunit.xml.dist src/MyClass.php tests/MyClassTest.php
echo "build" > .gitignore
git add src tests .gitignore 
git commit -m"Inital dump"

Now let's fill our demo project with some life !

Paste the following in your phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
   backupStaticAttributes="false"
   syntaxCheck="false">

<testsuites>
   <testsuite name="php-demo">
     <directory suffix="Test.php">tests</directory>
   </testsuite>
</testsuites>
<logging>
  <log type="coverage-html" target="build/coverage" title="php-demo"
   charset="UTF-8" yui="true" highlight="true"
   lowUpperBound="35" highLowerBound="70"/>
  <log type="coverage-clover" target="build/logs/clover.xml"/>
  <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>

Some sample code for "src/MyClass.php"

<?php
class MyClass {
    public function demo($a) {
        if($a == 1) {
            return 1;
        }
        return 0;
    }
}

And a sample test for "tests/MyClassTest.php"

<?php

require_once("src/MyClass.php");

class MyClassTest extends PHPUnit_Framework_TestCase {

    public function testDemo() {
        $x = new MyClass();
        $this->assertEquals(1, $x->demo(1));
    }
}

Now paste that behemoth into your build.xml:

<project name="php-demo-project" default="build" basedir=".">
<target name="clean">
<!-- Clean up -->
<delete dir="build"/>

<!-- Create build directories -->
<mkdir dir="${basedir}/build/api"/>
<mkdir dir="${basedir}/build/code-browser"/>
<mkdir dir="${basedir}/build/coverage"/>
<mkdir dir="${basedir}/build/logs"/>
<mkdir dir="${basedir}/build/pdepend"/>
</target>

<!-- Run unit tests and generate junit.xml and clover.xml
 (This is done in the phpunit.xml.dist,
you could also write the switches here)
-->
<target name="phpunit">
 <exec executable="phpunit" failonerror="true" />
</target>

<!-- Run pdepend, phpmd, phpcpd, and phpcs in parallel -->
<target name="parallelTasks">
<parallel>
<antcall target="pdepend"/>
<antcall target="phpmd"/>
<antcall target="phpcpd"/>
<antcall target="phpcs"/>
<antcall target="phpdoc"/>
</parallel>
</target>

<!-- Generate jdepend.xml and software metrics charts -->
<target name="pdepend">
<exec executable="pdepend">
<arg line="--jdepend-xml=${basedir}/build/logs/jdepend.xml src" />
</exec>
</target>

<!-- Generate pmd.xml -->
<target name="phpmd">
<exec executable="phpmd">
<arg line="src xml codesize,unusedcode
--reportfile ${basedir}/build/logs/pmd.xml" />
</exec>
</target>

<!-- Generate pmd-cpd.xml -->
<target name="phpcpd">
<exec executable="phpcpd">
<arg line="--log-pmd ${basedir}/build/logs/pmd-cpd.xml src" />
</exec>
</target>

<!-- Generate checkstyle.xml -->
<target name="phpcs">
<exec executable="phpcs" output="/dev/null">
<arg line="--report=checkstyle
--report-file=${basedir}/build/logs/checkstyle.xml
--standard=Sebastian
src" />
</exec>
</target>

<!-- Generate API documentation -->
<target name="phpdoc">
<exec executable="phpdoc">
<arg line="-d src -t build/api" />
</exec>
</target>

<target name="phpcb">
<exec executable="phpcb">
<arg line="--log ${basedir}/build/logs
--source ${basedir}/src
--output ${basedir}/build/code-browser" />
</exec>
</target>

<target name="build" depends="clean,phpunit,parallelTasks,phpcb"/>
</project>

Nearly done !

cd ~/mydemo
git commit -am"Lets do this"
cd /var/lib/hudson/jobs
git clone git://github.com/sebastianbergmann/php-hudson-template.git
sudo /etc/init.d/hudson stop
sudo /etc/init.d/hudson start

  • Now go to http://localhost:8080/ again
  • Click "New Job"
  • Build a free-style software project "php-demo"
  • Select "git" as the "Source Code Management"
  • User /home/$USERNAME/mydemo as the URL
  • Under Build: click "Add build Step -> Invoke Ant"
  • Under "Post-build Actions": click "Use publishers from another project" and select php-hudson-template as the "Template Project"
  • Save
  • Click "Build now"
  • Enjoy your first build ! Click it and look at all the pretty output :)
  • If you want to build every time you commit that option is under "configure, build triggers, poll scm"

Done !

I hope that guide was helpful to you. Note that this is only a draft. Please tell me about any problems you rant into, if it worked for you or if you have suggestions !

Thanks for reading 

 

 

 

Permalink | Leave a comment  »

December 09, 2010

Qafoo GmbH

Testing file uploads with PHP

A question I am asked on a regular basis is, how you can test a file upload with PHP. In this blog post, I take a precise look at this topic and show you how to test your file uploads from within your standard testing environment, using widely unknown testing framework for PHP.

October 15, 2010

Qafoo GmbH

IPC 2010 recap

The International PHP Conference 2010, the 10th instance of this yearly PHP family meeting, ended yesterday. It was an amazing event again and we had many nice discussions. Beside that, all three Qafoo members presented talks on various topics, for which we now uploaded the slides to our talks page. Find below a short review about our sessions. If you attended any of them, please do not forget to give us some feedback via joind.in!

October 11, 2010

Christian Schaefer

symfony day 2010 – a review

The symfony day 2010 in Cologne was on this weekend and it had some awesome talks. Certainly I had a lot of fun as it was my first conference as a speaker. But I think I wasn’t the only one enjoying hi time there.

For those unfortunate of you who couldn’t attend to it here’s a wrap-up.

First of all I have to thank Interlutions and in person Dennis Benkert and Stefan Jung for organising this event!  From my perspective it was perfect throughout.

Now to the talks.

Doctrine MongoDB Object Document Mapper Jonathan Wage

With all the hype around MongoDB in the database world these days, Doctrine quickly jumped on creating an object mapper for it. Now, just like for relational databases you can transparently persist your PHP domain model to MongoDB in a fast and efficient way.

Jonathan talked about the latest Doctrine 2 development the Object Document Mapper that works with MongoDB instead of a RDBMS. Starting from a plain PHP implementation we explained the benefits of abstracting it by showing simple but descriptive examples.

I am still not really sure about all these NoSQL solutions like MongoDB or CouchDB. I always get the impression that they perform much better and that their lack of a schema would support many of my daily requirements perfectly. But I still haven’t developed a feeling for when to choose the one over the other…? However if I would choose MongoDB I would surely use Doctrine 2 ODM for it.

PHP, symfony and software lifecycles Pierre Joye

There was no description of this talk before it actually was held. Pierre who is a PHP core member spoke about the releases of PHP in the past and gave an insight in the internal development process.

It can not be said often enough that PHP itself is developed by a circle of people purely in their freetime. None of them gets paid to do it (except for Pierre beign paid by Microsoft to make sure PHP works on windows). We the PHP community owe them a lot.

Unit testing symfony plugins with PHPUnit Christian Schaefer

When developing symfony plugins for use and reuse in your projects and maybe (hopefully) by the symfony community you want to make sure that a new release doesn’t break with backwards compatibility. While symfony comes with lime the de facto standard for unit testing in PHP is PHPUnit and it offers much more. This session will show you some of the best practices of testing symfony plugins. You will learn how to organise your tests and how to reduce your dependencies to the bare essentials.

Well this was my own talk and I had some good feedback on it. Basically I summarised what you have to do to develop your symfony plugins with the support of PHPUnit tests.

Advanced symfony Techniques Kris Wallsmith

Go beyond the documentation and explore some of what’s possible if you stretch symfony to its limits. We will look at a number of aspects of symfony 1.4 and Doctrine 1.2 and tease out some powerful functionality you may not have expected to find, but will doubtless be able to use. Topics covered will include routing, forms, the config cache and record listeners. If you’re comfortable in symfony and wondering what’s next, this session is for you.

Kris introduced us to yet some more of his plugins. Request aware routes, keeping POST data when login expired and managing multiple relations in embedded forms where only a few of the functionalities. As always I have to admire the elegant simplicity of his solutions.

Framework or CMS Gaylord Aulke

Frameworks are cool. There are many, they are powerful, they help. Large parts of the php developer community have realized that a framework is the way to go. But how do i “sell” this to the management and customers? When to choose a framework and when to use a CMS or eCommerce system? The talk gives some decision support and reasoning for framework adoption based on real-life examples.

Gaylord illustrated with a lot of anecdotes how developers should communicate their requirements (using a framework over a CMS or else) to the business level. Quite interesting session.

The State of Symfony2 Fabien Potencier

About a year ago, I announced that Symfony2 would be PHP 5.3 only. What have we done since then? In this session, I will talk about the latest additions made to the framework, and I will demonstrate how you can leverage the power of the newest Symfony components.

I get the impression that Fabien likes to use conferences such as this one to announce yet another killer feature and really I can’t get enough of it. After explaining that after a long discussion on the symfony mailing list it was decided that there will be no default templating engine for Symfony2 but instead PHP and Twig templates will be equal alternatives; Fabien went on to tell us about the new security component called Firewall which is modelled after the Java spring framework. It will apparently allow for stateful but also stateless authentication.

Workshop Stefan Koopmanschap

Get to know symfony – at the end of the day, you will have completed your first running prototype app!

In parallel to all the session Stefan gave a workshop where he developed a simple facebook clone called “GesichBuch” together with all attendees. The bit of feedback that I overheard was appreciative and positive throughout. Makes me wonder why diaspora takes so long. ;)

October 07, 2010

Quality Assurance in PHP Projects

The German Edition Started Shipping!

The German Edition of the PHP Quality Assurance book started shipping. Stefan and I, as well as all our contributing authors, are very happy about this. Below you can find additional information about the book in German.

Softwarequalität in PHP-Projekten

Wenn die Hütte brennt, werden Überstunden gemacht und Urlaube abgesagt. Trotzdem werden Termine und Qualitätsziele meist verfehlt. Da Software jedoch weit länger lebt als ursprünglich geplant, gehen die Probleme erst dann richtig los, wenn später Änderungen und Erweiterungen notwendig werden.

Im vorliegenden Buch vermitteln Sebastian Bergmann und Stefan Priebsch gemeinsam mit ihren Co-Autoren umfassendes Fachwissen und Erfahrungen zur Qualitätssicherung in PHP-Projekten. Zahlreiche Fallstudien veranschaulichen die Planung, Durchführung und Automation von Tests für die unterschiedlichen Softwareschichten sowie die Beurteilung von Softwarequalität mit Hilfe von Softwaremetriken. Sie sind die Grundlage dafür, Entwicklungsprozesse durch den Einsatz geeigneter Methoden wie etwa Continuous Integration zu optimieren. Die Fallstudien zeigen, wie bekannte Firmen und Projekte die Qualität ihrer Software messen, kontrollieren und sichern, ermöglichen einen Blick hinter die Kulissen und vermitteln so wertvolle Praxiserfahrungen.

Das Buch empfiehlt sich allen, die eine Referenz für die Entwicklung qualitativ hochwertiger und nachhaltiger Softwareanwendungen in PHP suchen.

Das Standardwerk zur Qualitätssicherung


  • Liefert wichtiges Grundlagenwissen zum Testen PHP-basierter Software

  • Zeigt die Umsetzung von Maßnahmen zur Qualitätssicherung in der Praxis

  • Enthält hochinformative Fallstudien bekannter Firmen und Projekte

  • Aus der Feder anerkannter PHP-Experten

  • Beschreibt den aktuellen Wissensstand in Sachen Software-Qualitätssicherung

The English edition of the book is scheduled for publication in December -- stay tuned!

October 05, 2010

Christian Schaefer

PHPUnit 3.5 released

Today just a short notice while I am preparing for the upcoming symfony day 2010 in Cologne.

Sebastian Bergmann just recently released a new minor version of PHPUnit 3.5 during the PHP Unconference in Hamburg.

Get it while it’s hot as it’s faster and more complete and also the documentation has even more details added to it!

It has been broken down into several standalone components which promise for less maintenance effort thus faster development.

It also eases writing test cases a lot as from now on you no longer have to require anything as long as PHPUnit is in your include paths.

PHPUnit 3.5 just feels good!

September 17, 2010

Qafoo GmbH

Practical PHPUnit: Testing XML generation

Testing classes which generate XML can be a cumbersome work. At least, if you don't know the right tricks to make your life easier. In this article, I will throw some light upon different approaches and show you, how XML generation can be tested quite easily using XPath.

September 10, 2010

Sebastian Nohn

August 30, 2010

Christian Schaefer

Options for setting up a Doctrine database connection when PHPUnit testing symfony plugins

It is rarely the case that your unit tests actually test your database. It is however not so rare that the code your unit test tries to cover needs a database connection of some sorts.

In symfony 1.x you will find quite some tightly coupled code. Together with Doctrines (1.x) implementation of the active record pattern you will get a lot of exceptions complaining about no open database connection.

So if your tests need a database connection how should you do that?

I created a little experiment to test setting up database connections. If you’re interested you can reproduce those experiments with the sources on GitHub.

I basically tried a few combinations of the following code.

Setting up a database connection using the settings in the fixture projects databases.yml

Setting up a database connection using Doctrines mock adapter

Findings

You should always set up a database connection using the setUp() method of your testcase or a test method itself if it is the only method requiring a database connection. This way you only use the database when you actually need it.

I am still pretty amazed that using the mock adapter shows no functional difference to sqlite::memory: and is using up the same amount of memory.

Using –process-isolation on PHPUnit when executing a testcase or testsuite will drastically reduce the memory consumption but at the time of writing this (using PHPUnit 3.5RC1) it will produce a strange runtime exception when the database connection is made in the bootstrap file.

Oh and on the GitHub page you can also see the results of the experiments. :)

August 27, 2010

Christian Schaefer

Why Doctrine_Core::getTable(‘BarFoo’) is not such a good idea.. when PHPUnit testing a symfony plugin

If you have a look at the symfony and Doctrine documentation you will notice that whenever you want to get the table object for a model you will call Doctrine_Core::getTable(‘ModelName’).

Apparently this is considered a best practice however I came to thing quite the opposite.

As you probably know I am quite keen on the topic of unit testing and that is exactly where Doctrine_Core::getTable() gets annoying.

It’s a static method that will be called in many methods of your classes. Mostly actions and components I suppose but also in other places.

Now when you want to test those methods that include a static call like this you will notice that you need to bootstrap a lot of symfony and Doctrine. Many times you will also need to open a database connection. But the method you want to test only calls to database related methods.

I would like to be able to mock all these database related methods in order to optimise execution speed of my unit tests. However you can not mock static methods (with PHP3.5 and PHPUnit 3.5 you will be able to) which means that you need to connect the database.

This may all sound a bit loopy but I just spend several hours optimising unit tests replacing calls to Doctrine_Core::getTable(‘BarFoo’) with new BarFooTable().

August 26, 2010

Christian Schaefer

Applying best practices for PHPUnit testing symfony plugins

By now I have been writing quite a bit about how to utilise PHPUnit when developing symfony plugins. But symfony is of course still bundled with lime so before starting right away every plugin needs to be prepared with small changes like adjusting the bootstrap.

And because all these little changes have to be repeated over and over again for every plugin you start they tend to get tedious.

But I’ve got an idea! ;)

Well credit where credit is due: it was actually Stefan Koopmanschap (skoop) who initially gave me the idea of putting my findings and best practices into a plugin.

So what is to be expected?

Well so far I plan the following three features:

  1. A symfony task to change the default test bootstrap to work with PHPUnit
  2. A symfony task  to create a best practice phpunit.xml.dist
  3. A symfony task to create skeleton test cases for classes in your project

Of course the plugin itself will be PHPUnit tested (eating my own dog food).

What would you like to see implemented? Feel free to comment on quora.