<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>Planet PHPUnit</title>
	<link>http://planet.phpunit.de/</link>
	<language>en</language>
	<description>Planet PHPUnit - http://planet.phpunit.de/</description>

<item>
	<title>Laura Beth Lincoln Denker: Goldilocks and the Three Test Sizes</title>
	<guid>http://elblinkin.info/?p=266</guid>
	<link>http://elblinkin.info/2012/03/goldilocks-on-test-sizes/</link>
	<description>So, she walked into the living room where she saw three chairs. Goldilocks sat in the first chair to rest her feet. &amp;#8220;This chair is too big!&amp;#8221; she exclaimed. So she sat in the second chair. &amp;#8220;This chair is too big, too!&amp;#8221; she whined. So she tried the last and smallest chair. &amp;#8220;Ahhh, this chair [...]</description>
	<pubDate>Thu, 29 Mar 2012 15:41:18 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: The UNIT in unit testing</title>
	<guid>http://edorian.posterous.com/the-unit-in-unit-testing</guid>
	<link>http://edorian.posterous.com/the-unit-in-unit-testing</link>
	<description>&#182;&#166;nv&#162;&#150;&#234;&#229;&#134;&#219;i&#255;&#248;&#181;&#248;&#165;{Zh&#178;&#215;&#171;&#162;&#235;&#162;o&#224;z&#215;&#226;&#149;&#239;&#223;&#138;W&#172;&#166;&#139;-z&#186;.&#177;&#202;&amp;&#253;&#231;h&#174;&amp;&#167;&#252;k&#198;&#154;&#156;&#224;&#164;&#146;&#133;&#217;&#159;&#199;7&#239;&#155;&#226;&#130;E&#190;H&#229;@j&#185;&#177;e&#181;&#247;&#156;8&#137;:I&#198;&#249;@ql&#207;&#249;&#158;v&amp;&#161;&#182;&#218;]&#149;&#218;&#232;&#165;&#186;1r&#136;^r&#151;&#227;&#166;jW&#157;&#231;M#&#166;&quot;v&#216;</description>
	<pubDate>Wed, 14 Mar 2012 10:14:00 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHP|Tek 2012 &#8211; Developer Testing 201:  When to Mock and When to Integrate</title>
	<guid>http://elblinkin.info/?p=264</guid>
	<link>http://elblinkin.info/2012/03/phptek-2012-developer-testing-201-when-to-mock-and-when-to-integrate/</link>
	<description>I am honestly very excited to be going to Chicago this May to speak and teach at PHP&amp;#124;Tek &amp;#8217;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 [...]</description>
	<pubDate>Mon, 12 Mar 2012 18:54:21 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Voices of the ElePHPant</title>
	<guid>http://elblinkin.info/?p=261</guid>
	<link>http://elblinkin.info/2012/03/voices-of-the-elephpant/</link>
	<description>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/</description>
	<pubDate>Tue, 06 Mar 2012 15:45:28 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHP UK Conference 2012</title>
	<guid>http://elblinkin.info/?p=258</guid>
	<link>http://elblinkin.info/2012/02/php-uk-conference-2012/</link>
	<description>Slides for my talk &amp;#8220;Scaling Communication via Continuous Integration&amp;#8221; are now available on Slide Share. As presented at PHPUK2012 in London. Scaling Communication via Continuous Integration</description>
	<pubDate>Sun, 26 Feb 2012 15:59:31 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: New Addition to CSRunner: php -l</title>
	<guid>http://elblinkin.info/?p=254</guid>
	<link>http://elblinkin.info/2012/02/new-addition-to-csrunner-php-l/</link>
	<description>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 [...]</description>
	<pubDate>Tue, 21 Feb 2012 17:47:49 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Thoughts on Accessibility with Regards to Testing</title>
	<guid>http://elblinkin.info/?p=247</guid>
	<link>http://elblinkin.info/2012/02/thoughts-on-accessibility-with-regards-to-testing/</link>
	<description>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 [...]</description>
	<pubDate>Fri, 10 Feb 2012 19:36:16 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Mockery Test Case for PHPUnit</title>
	<guid>http://elblinkin.info/?p=242</guid>
	<link>http://elblinkin.info/2012/02/mockery-test-case-for-phpunit/</link>
	<description>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, [...]</description>
	<pubDate>Wed, 08 Feb 2012 21:00:29 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHP CodeSniffer for Recently Changed Files</title>
	<guid>http://elblinkin.info/?p=238</guid>
	<link>http://elblinkin.info/2012/02/php-codesniffer-for-recently-changed-files/</link>
	<description>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&amp;#8217;t just define the [...]</description>
	<pubDate>Wed, 08 Feb 2012 16:15:48 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Developer Testing, Not Necessarily TDD&#8230; Revisited</title>
	<guid>http://elblinkin.info/?p=228</guid>
	<link>http://elblinkin.info/2012/02/developer-testing-not-necessarily-tdd-revisited/</link>
	<description>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 [...]</description>
	<pubDate>Thu, 02 Feb 2012 01:11:32 +0000</pubDate>
</item>
<item>
	<title>Sebastian Bergmann: A Tool's Tale</title>
	<guid>http://sebastian-bergmann.de/archives/919-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/919-A-Tools-Tale.html</link>
	<description>&lt;p&gt;When &lt;a href=&quot;http://twitter.com/noahsussman&quot;&gt;Noah Sussman&lt;/a&gt; asked me to give a &lt;a href=&quot;http://codeascraft.etsy.com/etsy-speaker-series/&quot;&gt;Code as Craft Technology Talk&lt;/a&gt; last week when I was consulting for Etsy I immediately said yes. However, I was a bit surprised when the talk was announced under the title &quot;An Evening with Sebastian Bergmann&quot;. When I read that title the first time, it was just minutes after Arne, Stefan and I had talked about one of our favourite scenes from &quot;&lt;a href=&quot;http://www.imdb.com/title/tt0183790/&quot;&gt;A Knight's Tale&lt;/a&gt;&quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Chaucer:&lt;/strong&gt; I'm a writer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wat:&lt;/strong&gt; A what?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chaucer:&lt;/strong&gt; A wha- a what? A writer. You know, I write, with ink, and parchment. Geoffrey Chaucer's the name, writing's the game. You've probably read my book? The Book of the Duchess? No? Well, it was allegorical.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Roland:&lt;/strong&gt; Well, we won't hold that against you, that's for every man to decide for himself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just like with &lt;a href=&quot;http://sebastian-bergmann.de/archives/915-Testable-Code-Rockstar-Edition.html&quot;&gt;a talk that I gave last year&lt;/a&gt;, I suddenly had a chain of associations in my head that I just had to follow. And down the rabbit hole I went once more ...&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_1.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_1.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;Hi! I have no idea why this talk is titled &quot;An Evening with Sebastian Bergmann&quot;. I hope that this evening will turn into an interesting discussion about PHPUnit and all things testing. To break the ice, and to not appear completely unprepared, I came up with the following slides ...&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_2.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_2.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;So I recently talked with my friends Arne and Stefan about the movie &quot;A Knight's Tale&quot;. Somehow the idea stuck in my head that a variation of that title might be a good idea for a talk of mine. After dismissing &quot;A Fool's Tale&quot; I arrived at &quot;A Tool's Tale&quot;. So that's what we're stuck with and what I am going to try right now ...&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_3.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_3.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_4.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_4.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_5.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_5.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_6.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_6.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;What I just did was a variation on how Geoffrey Chaucer introduces himself in the movie.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_7.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_7.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;Some time in 2001 I started to work on PHPUnit because I wanted to have something like JUnit for PHP. The initial &quot;port&quot; was completed within one weekend. The code was ugly because I had to emulate exceptions which PHP 4 did not have. On November 27th 2001 I checked the code into &lt;code&gt;cvs.php.net&lt;/code&gt;.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_8.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_8.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;A lot has changed since 2001. Hopefully not very many developers are still stuck with PHP 4. As of PHPUnit 2.0, which was released on &lt;a href=&quot;http://sebastian-bergmann.de/feeds/categories/sebastian-bergmann.de/archives/378-PHPUnit2-2.0.0-Released.html&quot;&gt;July 14 2004&lt;/a&gt;, the day after PHP 5.0.0 was released, PHP 5 is required to run PHPUnit. &lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_9.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_9.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;PHPUnit is neither the only testing framework nor the only quality assurance tool for PHP. Over the last years a nice ecosystem of static analysis tools started to grow.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_10.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_10.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;I get this question a lot: why do only Germans work on tools that tell me that my code is bad? I do not have an answer for this, sorry. But the statement is also not true: PHP_CodeSniffer is not developed by a German.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_11.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_11.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;PHP has changed and so the have the tools we use to write and maintain code. In 2006 the PHPUnit code was migrated from CVS to Subversion ...&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_12.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_12.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;... and in &lt;a href=&quot;http://sebastian-bergmann.de/archives/876-PHPUnit-Development-Moved-to-GitHub.html&quot;&gt;December 2009 from Subversion to Git and GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_13.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_13.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;PHPUnit is no longer one big monolithic package. It has been &lt;a href=&quot;http://sebastian-bergmann.de/archives/892-PHPUnit-3.5-Refactoring-to-Components.html&quot;&gt;refactored to components&lt;/a&gt; that are being reused by other testing frameworks, for instance. Unfortunately, &lt;a href=&quot;http://sebastian-bergmann.de/archives/899-PHPUnit-3.5-Upgrading-Woes.html&quot;&gt;this refactoring was not without problems&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_14.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_14.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;PHPUnit gets more and more convenience functionality. Here are a couple of examples:&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_15.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_15.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_16.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_16.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_17.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_17.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_18.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_18.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;Tests can be written, both unintentionally and intentionally, in bad ways. Bad tests can lie. They can give you a false sense of security by reporting that something is tested when it really is not.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_19.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_19.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;This is why I started iplementing coutermeasures against bad tests such as the (ultimately useless but still interesting) assertion counting ...&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_20.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_20.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;... as well as the strict execution mode.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_21.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_21.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;There is code in PHPUnit that I am not proud of. I am trying to make the world a better place by eliminating one singleton at a time, for instance. Unfortunately, cleaning up code sometimes breaks things. Contrary to what a popular opinion on Twitter is, I do not like breaking backwards compatibility in PHPUnit and try really hard to avoid it.&lt;/p&gt;
&lt;a href=&quot;http://sebastian-bergmann.de/images/a_tools_tale_22.png&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;http://sebastian-bergmann.de/images/a_tools_tale_22.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;p&gt;This is a &quot;good&quot; example of such a backwards compatibility breakage. It happened in PHPUnit 3.6 because I eliminated a Singleton. Had I known that many developers used this API (instead of the XML configuration file) to set up a code coverage blacklist or whitelist I would probably not have done the change. If more people would have tested the release candidates leading up to PHPUnit 3.6 they could have told me ... oh well.&lt;/p&gt;
&lt;p&gt;At this point the &quot;Evening with Sebastian Bergmann&quot; turned into the interesting discussion I had hoped for.&lt;/p&gt;</description>
	<pubDate>Wed, 01 Feb 2012 06:30:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Mike Lively: Phake 1.0.0 is finished</title>
	<guid>http://digitalsandwich.com/?p=100</guid>
	<link>http://digitalsandwich.com/archives/100-phake-1-0-0-is-finished.html</link>
	<description>&lt;p&gt;So, now that 2012 is here, I can confidently say that I have accomplished two things&amp;#8230;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 &lt;a href=&quot;http://phake.digitalsandwich.com/?p=59&quot; title=&quot;Phake&quot;&gt;Phake&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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&lt;a href=&quot;http://phake.digitalsandwich.com/docs/html/&quot;&gt; Phake documentation&lt;/a&gt;. It allows you to do quite a few nifty things.&lt;/p&gt;
&lt;p&gt;A big thanks to all those who have contributed feedback / code thus far.&lt;/p&gt;
&lt;p&gt;Happy new year!&lt;/p&gt;
&lt;div class=&quot;topsy_widget_data topsy_theme_blue&quot;&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 01 Jan 2012 23:57:27 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: What you need to know about combining @depends and @dataProvider in PHPUnit</title>
	<guid>http://www.testically.org/?p=3376</guid>
	<link>http://www.testically.org/2011/12/22/what-you-need-to-know-about-combining-depends-and-dataprovider-in-phpunit/</link>
	<description>&lt;p&gt;&lt;img class=&quot;alignleft size-medium wp-image-3377&quot; title=&quot;what-you-need-to-know&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/12/what-you-need-to-know-300x225.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;225&quot; /&gt;Yesterday I was working on some PHPUnit test cases and couldn&amp;#8217;t get two of them to work as I wanted them to.&lt;/p&gt;
&lt;p&gt;The answer was actually in the documentation and taught me not only about why it wasn&amp;#8217;t working but also a lesson about documentation.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-3376&quot;&gt;&lt;/span&gt;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.&lt;/p&gt;
&lt;p&gt;It made sense to have more than one test data set to map and reduce so I added @dataProvider to the first test.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Nothing worked anymore..&lt;/p&gt;
&lt;p&gt;The answer is actually in the documentation at &lt;a title=&quot;Chapter 4. Writing Tests for PHPUnit / Data Providers&quot; href=&quot;http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers&quot; target=&quot;_blank&quot;&gt;Chapter 4. Writing Tests for PHPUnit / Data Providers&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;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.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All data providers are executed before the first call to the setUp function. Because of that you can&amp;#8217;t access any variables you create there from within a data provider.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So there we go what I wanted it not supposed to work and I have to find another way. Fine.&lt;/p&gt;
&lt;p&gt;The lesson I learned about documentation?&lt;/p&gt;
&lt;p&gt;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&amp;#8217;t find this information.&lt;/p&gt;
&lt;p&gt;You see that a piece of information about two things needs to be available for both things. I&amp;#8217;m sure that is a bugger to maintain but then documentation isn&amp;#8217;t easy.&lt;/p&gt;</description>
	<pubDate>Thu, 22 Dec 2011 08:28:20 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Code Snippet:  Find Files Without Test Files</title>
	<guid>http://elblinkin.info/?p=222</guid>
	<link>http://elblinkin.info/2011/12/code-snippet-find-files-without-test-files/</link>
	<description>I am working on a green-field project and wanted to make sure I roughly knew what was and wasn&amp;#8217;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 [...]</description>
	<pubDate>Tue, 06 Dec 2011 20:53:27 +0000</pubDate>
</item>
<item>
	<title>VG Tech Blog: Running multiple versions of PHPUnit</title>
	<guid>http://tech.vg.no/?p=266</guid>
	<link>http://tech.vg.no/2011/11/29/running-multiple-versions-of-phpunit/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=running-multiple-versions-of-phpunit</link>
	<description>&lt;p&gt;The latest version of &lt;a href=&quot;https://github.com/sebastianbergmann/phpunit/&quot;&gt;PHPUnit&lt;/a&gt; (3.6.4 at the time of this writing) does not play well with the &lt;a href=&quot;http://framework.zend.com&quot;&gt;Zend Framework&lt;/a&gt; extensions (&lt;a href=&quot;http://framework.zend.com/manual/en/zend.test.phpunit.html&quot;&gt;Zend_Test_PHPUnit&lt;/a&gt;). After asking &lt;a href=&quot;http://mwop.net/blog&quot;&gt;Matthew Weier O&amp;#8217;Phinney&lt;/a&gt; about this he answered that they had &lt;a href=&quot;https://twitter.com/#!/weierophinney/status/141141184411209729&quot;&gt;standardized on PHPUnit-3.4 for ZF1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;span id=&quot;more-266&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Installing multiple versions can be accomplished by using the &lt;code&gt;--installroot&lt;/code&gt; option to the &lt;code&gt;pear&lt;/code&gt; command:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: bash&quot;&gt;sudo pear config-set auto_discover 1
sudo pear install --installroot /some/path/phpunit34 pear.phpunit.de/PHPUnit-3.4.15&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will install PHPUnit-3.4.15 to &lt;code&gt;/some/path/phpunit34&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You will need to make a small change to one of the installed files to fix the &lt;code&gt;include_path&lt;/code&gt;. If you installed the package to &lt;code&gt;/some/path/phpunit34&lt;/code&gt; the file you want to change is &lt;code&gt;/some/path/phpunit34/usr/bin/phpunit&lt;/code&gt;. Before the first &lt;code&gt;require_once&lt;/code&gt; statement in that file, enter the following code:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;
// 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()
)));

&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The path you need to prepend to PHP&amp;#8217;s &lt;code&gt;include_path&lt;/code&gt; is different from distro to distro. To see the path your system uses run the following command:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: bash&quot;&gt;pear config-show|grep php_dir&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or simply look around in the directory where you installed the specific version of PHPUnit.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: bash&quot;&gt;sudo ln -s /some/path/phpunit34/usr/bin/phpunit /usr/bin/phpunit34&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To verify that everything works you can run these commands:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: bash&quot;&gt;christere@spongebob:~$ phpunit --version
PHPUnit 3.6.4 by Sebastian Bergmann.

christere@spongebob:~$ phpunit34 --version
PHPUnit 3.4.15 by Sebastian Bergmann.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Feel free to leave a comment if you see any possible problems with this solution.&lt;/p&gt;</description>
	<pubDate>Tue, 29 Nov 2011 11:43:51 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: Textual code coverage information for PHPUnit</title>
	<guid>http://edorian.posterous.com/textual-code-coverage-information-for-phpunit</guid>
	<link>http://edorian.posterous.com/textual-code-coverage-information-for-phpunit</link>
	<description>&lt;p&gt;
	&lt;p&gt;Three weeks ago PHPUnit 3.6 was released and it has a little new feature you might have missed until now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHPUnit can now show you code coverage information on the command line&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;phpunit --coverage-text
 [...]
 Code Coverage Report for &amp;quot;BankAccount&amp;quot;
 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
 [...]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;What it can do&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Colored output will be generated if you use &amp;mdash;colors or have configured it in your phpunit.xml so you can now bring some more green into your day&lt;/li&gt;
&lt;li&gt;&amp;mdash;coverage-text will by default write to STDOUT but you can tell it to write in a file too if you want&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;When your code uses namespaces those will be used to sort and list the classes &amp;ldquo; \My\Namespace\ClassName&amp;rdquo;&lt;/li&gt;
&lt;li&gt;If you don&amp;rsquo;t use namespaces but phpdoc-style @package tags those will be listed like shown in the example above.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;Why it exists&lt;/h1&gt;

&lt;p&gt;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 &amp;ldquo;watch -n1 phpunit&amp;rdquo; so i don&amp;rsquo;t have to press a button to see the testing status.&lt;/p&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;Main use case&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;For anything a little bigger this can still be &lt;strong&gt;used in conjunction with the &amp;mdash;filter option&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;watch -n1 phpunit --filter MyNewClass --coverage-text&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;keeps you updated on the class you are currently working on shows its code coverage information.&lt;/p&gt;

&lt;h1&gt;Docs&lt;/h1&gt;

&lt;p&gt;This feature is of course also documented in the &lt;a href=&quot;http://www.phpunit.de/manual/3.6/en/logging.html#logging.codecoverage.text&quot;&gt;phpunit documentation&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Give it a try and let me know if you like it.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/textual-code-coverage-information-for-phpunit&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/textual-code-coverage-information-for-phpunit#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Fri, 25 Nov 2011 15:41:00 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: An Example: Avoid Private Functions in Unit Tests</title>
	<guid>http://elblinkin.info/?p=202</guid>
	<link>http://elblinkin.info/2011/11/an-example-avoid-private-functions-in-unit-tests/</link>
	<description>@__edorian writes: @elblinkin I can&amp;#8217;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: &amp;#60;?php class GameTest extends PHPUnit_Framework_TestCase { /** * @var Game */ private $game; protected function setUp() { $this-&amp;#62;game = new Game(); } public function [...]</description>
	<pubDate>Mon, 07 Nov 2011 20:57:53 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Developer Testing, Not Necessarily TDD</title>
	<guid>http://elblinkin.info/?p=200</guid>
	<link>http://elblinkin.info/2011/11/developer-testing-not-necessarily-tdd/</link>
	<description>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 [...]</description>
	<pubDate>Fri, 04 Nov 2011 23:58:35 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: An introduction to PHPUnits @covers annotation</title>
	<guid>http://edorian.posterous.com/an-introduction-to-phpunits-covers-annotation</guid>
	<link>http://edorian.posterous.com/an-introduction-to-phpunits-covers-annotation</link>
	<description>&lt;p&gt;
	&lt;p&gt;The Code Coverage reports PHPUnit can generate for you can tell you one important thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What parts of your code you definitely have not tested yet!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It can&amp;rsquo;t tell you what part of your code base you have tested. Everything that is green (&amp;ldquo;covered&amp;rdquo;) only shows you that that code was &lt;strong&gt;&lt;em&gt;executed&lt;/em&gt;&lt;/strong&gt;. 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 &lt;strong&gt;&lt;em&gt;execute&lt;/em&gt;&lt;/strong&gt; but you have &lt;strong&gt;&lt;em&gt;tested&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;0% of it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;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 (&lt;em&gt;which is doable and the only goal to strive for that makes sense.. but thats for another post)&lt;/em&gt; you should trust your tests and your code to work properly. You shouldn&amp;rsquo;t think &amp;ldquo;Well yes that a 100% but a lot of that just comes from that big integration test and I don&amp;rsquo;t know if the class is really tested!&amp;rdquo;.&lt;/p&gt;

&lt;h1&gt;Let @covers keep you honest&lt;/h1&gt;

&lt;p&gt;Thankfully PHPUnit offers a way to drastically increase your confidence in what you actually have &lt;strong&gt;&lt;em&gt;tested&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;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&amp;rsquo;t generate code coverage information by accident. Additionally the &amp;mdash;strict switch will not generate coverage for all test cases that don&amp;rsquo;t make any assertions. Of course you can &amp;ldquo;work around&amp;rdquo; that but as only as you don&amp;rsquo;t lie to yourself your test suite won&amp;rsquo;t ether.&lt;/p&gt;

&lt;p&gt;You can find a &lt;a href=&quot;http://www.phpunit.de/manual/3.6/en/code-coverage-analysis.html#code-coverage-analysis.specifying-covered-methods&quot;&gt;basic example of how the @covers annotation works&lt;/a&gt; in the PHPUnit documentation.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;Protected Methods and @covers&lt;/h1&gt;

&lt;p&gt;For pulbic methods usually one test tests one method. Your &lt;strong&gt;testAddingStuffFailsWhenIInvalidProductIsPassed&lt;/strong&gt; covers your addStuff, your removeStuffIAdded mainly covers your remove stuff as the addStuff method should already be tested before.&lt;/p&gt;

&lt;p&gt;While you could also &amp;ldquo;@covers&amp;rdquo; your addStuff method when testing the removeStuff method I&amp;rsquo;d say usually that isn&amp;rsquo;t needed and you should &lt;strong&gt;only generate coverage for the methods that correlate with your assertions&lt;/strong&gt;. Not the methods you call to &amp;ldquo;set up&amp;rdquo; your object.&lt;/p&gt;

&lt;p&gt;When it comes to protected methods there are two ways you can go&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all protected methods, each with a @covers annotation&lt;/li&gt;
&lt;li&gt;Tell the tests to always generate code coverage for all protected methods&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In my opionion the second one makes more sense. First of you don&amp;rsquo;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 &lt;em&gt;&amp;ldquo;We don&amp;rsquo;t test protected methods because they are an implementation detail&amp;rdquo;&lt;/em&gt; way of thinking. I don&amp;rsquo;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.&lt;/p&gt;

&lt;h1&gt;An example&lt;/h1&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;/**
 * @covers Calculator::
 */&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;class&quot;&gt;CalculatorTest&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;PHPUnit_Framework_TestCase&lt;/span&gt; {
    &lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;setUp&lt;/span&gt;() { &lt;span class=&quot;comment&quot;&gt;/* ... */&lt;/span&gt; }
    &lt;span class=&quot;comment&quot;&gt;/**
     * @covers Calculator::add
     */&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;testAddTwoIntegers&lt;/span&gt;() { &lt;span class=&quot;comment&quot;&gt;/* ... */&lt;/span&gt; }
    &lt;span class=&quot;comment&quot;&gt;/**
     * @covers Calculator::multiply
     */&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;testMultiplyTwoIntegers&lt;/span&gt;() { &lt;span class=&quot;comment&quot;&gt;/* ... */&lt;/span&gt; }
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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!&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/an-introduction-to-phpunits-covers-annotation&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/an-introduction-to-phpunits-covers-annotation#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Fri, 04 Nov 2011 10:53:00 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPUnit Coding Standard: Control Structures</title>
	<guid>http://elblinkin.info/?p=194</guid>
	<link>http://elblinkin.info/2011/11/phpunit-coding-standard-control-structures/</link>
	<description>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 [...]</description>
	<pubDate>Wed, 02 Nov 2011 16:38:17 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPUnit Coding Standard: Functions</title>
	<guid>http://elblinkin.info/?p=183</guid>
	<link>http://elblinkin.info/2011/10/phpunit-coding-standard-functions/</link>
	<description>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, &amp;#8220;but that violates DRY principles!&amp;#8221; or &amp;#8220;the xUnit pattern book says this!&amp;#8221; I assure you, I will provide further argument in later articles as none of [...]</description>
	<pubDate>Mon, 31 Oct 2011 14:48:09 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPUnit Coding Standard: Classes</title>
	<guid>http://elblinkin.info/?p=173</guid>
	<link>http://elblinkin.info/2011/10/phpunit-coding-standard-classes/</link>
	<description>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&amp;#8217;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. [...]</description>
	<pubDate>Mon, 24 Oct 2011 00:55:29 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPUnit Coding Standard: Naming</title>
	<guid>http://elblinkin.info/?p=161</guid>
	<link>http://elblinkin.info/2011/10/phpunit-coding-standard-naming/</link>
	<description>I promised more details about the PHPUnit coding standard, so let&amp;#8217;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 [...]</description>
	<pubDate>Fri, 14 Oct 2011 19:05:19 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Did you &#8216;try&#8217; it before you committed?</title>
	<guid>http://elblinkin.info/?p=155</guid>
	<link>http://elblinkin.info/2011/10/did-you-try-it-before-you-committed/</link>
	<description>Check out my post on Code as Craft: Did you &amp;#8216;try&amp;#8217; before you committed?</description>
	<pubDate>Tue, 11 Oct 2011 21:16:14 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPNW11</title>
	<guid>http://elblinkin.info/?p=149</guid>
	<link>http://elblinkin.info/2011/10/phpnw11/</link>
	<description>Slides for my talk &amp;#8220;Are Your Tests Really Helping You?&amp;#8221; 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 &amp;#8220;removal of assumptions&amp;#8221;) BTW: #PHPNW11ROCKS</description>
	<pubDate>Mon, 10 Oct 2011 07:58:03 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Preview: A Unit Testing Standard</title>
	<guid>http://elblinkin.info/?p=145</guid>
	<link>http://elblinkin.info/2011/09/preview-a-unit-testing-standard/</link>
	<description>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, [...]</description>
	<pubDate>Wed, 21 Sep 2011 19:28:29 +0000</pubDate>
</item>
<item>
	<title>Mike Naberezny: PHP Temporary Streams</title>
	<guid>http://mikenaberezny.com/?p=156</guid>
	<link>http://mikenaberezny.com/2008/10/17/php-temporary-streams/</link>
	<description>&lt;p&gt;It&amp;#8217;s been a while since David Sklar &lt;a href=&quot;http://www.sklar.com/blog/archives/116-Let-a-thousand-string-concatenations-bloom.html&quot;&gt;called out&lt;/a&gt; to &lt;i&gt;let a thousand string concatenations bloom&lt;/i&gt;.  That discussion produced some entertaining suggestions for putting strings together such as using &lt;code&gt;preg_replace&lt;/code&gt; and calling out to MySQL with &lt;code&gt;SELECT CONCAT&lt;/code&gt;.  &lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an approach that uses filesystem functions.  When combined with some lesser-known PHP streams functionality, it has several practical applications.&lt;/p&gt;
&lt;h4&gt;Opening Files for Reading and Writing&lt;/h4&gt;
&lt;p&gt;There are several modes for &lt;a href=&quot;http://www.php.net/fopen&quot;&gt;opening&lt;/a&gt; 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 &lt;code&gt;w+&lt;/code&gt;, which the &lt;code&gt;tmpfile&lt;/code&gt; function uses automatically.&lt;/p&gt;
&lt;p&gt;We can repeatedly write, then rewind the pointer and read:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;php&quot;&gt;&lt;span&gt;$f&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;tmpfile&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;fwrite&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'foo'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;fwrite&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'bar'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;rewind&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$contents&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;stream_get_contents&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;  &lt;span&gt;//=&amp;gt; &amp;quot;foobar&amp;quot;&lt;/span&gt;
&lt;span&gt;fclose&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When writing to the filesystem, the above provides yet another inefficient solution to David&amp;#8217;s exercise.  Now let&amp;#8217;s take it a bit further to see how this can be useful.&lt;/p&gt;
&lt;h4&gt;In-Memory Streams&lt;/h4&gt;
&lt;p&gt;PHP 5.1 introduced two new in-memory streams: &lt;code&gt;php://memory&lt;/code&gt; and &lt;code&gt;php://temp&lt;/code&gt;.  The &lt;code&gt;php://memory&lt;/code&gt; stream operates entirely in memory.  The &lt;code&gt;php://temp&lt;/code&gt; stream operates in memory until it reaches a given size, then transparently switches to the filesystem.  &lt;/p&gt;
&lt;p&gt;We can modify the above example to use the &lt;code&gt;php://memory&lt;/code&gt; stream instead of hitting the filesystem:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;php&quot;&gt;&lt;span&gt;$f&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;fopen&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'php://memory'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'w+'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;fwrite&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'foo'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;fwrite&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'bar'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;rewind&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$contents&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;stream_get_contents&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;  &lt;span&gt;//=&amp;gt; &amp;quot;foobar&amp;quot;&lt;/span&gt;
&lt;span&gt;fclose&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Putting a string inside a fast temporary stream can be very useful.  For example, we can then &lt;a href=&quot;http://us2.php.net/manual/en/function.stream-filter-append.php&quot;&gt;attach filters&lt;/a&gt; to that stream.  &lt;/p&gt;
&lt;h4&gt;Testing&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://framework.zend.com/manual/en/zend.log.html&quot;&gt;Zend_Log&lt;/a&gt; has a log handler for streams that accepts either a filename or a stream resource.  We can configure it with a &lt;code&gt;php://memory&lt;/code&gt; stream for testing:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;php&quot;&gt;&lt;span&gt;$f&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;fopen&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'php://memory'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'w+'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$writer&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;new&lt;/span&gt; Zend_Log_Writer_Stream&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$logger&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;new&lt;/span&gt; Zend_Log&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$writer&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;php&quot;&gt;&lt;span&gt;$logger&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;crit&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'critical message worth testing'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the action has completed, the test can rewind &lt;code&gt;$f&lt;/code&gt; and use it as a test spy.&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;php&quot;&gt;&lt;span&gt;rewind&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$contents&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;stream_get_contents&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$f&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertRegExp&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'/message worth testing/i'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$contents&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;  &lt;span&gt;// PHPUnit&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not surprisingly, my &lt;a href=&quot;http://framework.zend.com/svn/framework/standard/trunk/tests/Zend/Log/Writer/StreamTest.php&quot;&gt;unit tests&lt;/a&gt; for Zend_Log use this same technique.  &lt;/p&gt;
&lt;h4&gt;Application Usage&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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 &lt;a href=&quot;http://framework.zend.com/manual/en/zend.pdf.html&quot;&gt;Zend_Pdf&lt;/a&gt; to write over the template with dynamic content.  I first demonstrated this technique in &lt;a href=&quot;http://mikenaberezny.com/2006/05/02/zend-framework-tutorial-published/&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since the cover page is only used once (during transmission) and easy to regenerate, I don&amp;#8217;t save the output to the filesystem.  Instead, I create a &lt;code&gt;php://temp&lt;/code&gt; stream.  The instance method &lt;code&gt;Zend_Pdf-&amp;gt;render()&lt;/code&gt; writes the PDF output only to that stream, which is then rewound.  Functions like &lt;code&gt;stream_copy_to_stream&lt;/code&gt; or &lt;code&gt;fpassthru&lt;/code&gt; 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.&lt;/p&gt;</description>
	<pubDate>Sun, 14 Aug 2011 22:43:55 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Alternative Thoughts on Sniffs for Useless Method Overriding</title>
	<guid>http://elblinkin.info/?p=110</guid>
	<link>http://elblinkin.info/2011/08/alternative-thoughts-on-sniffs-for-useless-method-overriding/</link>
	<description>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 [...]</description>
	<pubDate>Wed, 10 Aug 2011 20:51:08 +0000</pubDate>
</item>
<item>
	<title>VG Tech Blog: Unit testing with streams in PHP</title>
	<guid>http://tech.vg.no/?p=110</guid>
	<link>http://tech.vg.no/2011/06/27/unit-testing-with-streams-in-php/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=unit-testing-with-streams-in-php</link>
	<description>&lt;p&gt;Using the memory/temporary stream provided by &lt;a title=&quot;php:// &#8212; Accessing various I/O streams&quot; href=&quot;http://no2.php.net/manual/en/wrappers.php.php&quot;&gt;php:// stream wrapper&lt;/a&gt; you&#160; can create a stream with read and write access directly to RAM or to a temporary file.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Creating a memory stream is easy; &lt;code&gt;$fp = fopen('php://memory', 'r+');&lt;/code&gt;. Now you have a &lt;a title=&quot;PHP: Resources - Manual&quot; href=&quot;http://no2.php.net/manual/en/language.types.resource.php&quot;&gt;resource &lt;/a&gt;that can be &lt;a title=&quot;PHP: Streams - Manual&quot; href=&quot;http://no.php.net/manual/en/book.stream.php&quot;&gt;used and manipulated&lt;/a&gt; just like any other stream or file.&lt;/p&gt;</description>
	<pubDate>Mon, 27 Jun 2011 20:22:21 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHPNW 2011</title>
	<guid>http://elblinkin.info/?p=97</guid>
	<link>http://elblinkin.info/2011/06/phpnw-2011/</link>
	<description>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 [...]</description>
	<pubDate>Sun, 26 Jun 2011 23:01:38 +0000</pubDate>
</item>
<item>
	<title>Sebastian Bergmann: Towards Better Code Coverage Metrics in the PHP World</title>
	<guid>http://sebastian-bergmann.de/archives/913-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/913-Towards-Better-Code-Coverage-Metrics-in-the-PHP-World.html</link>
	<description>&lt;p&gt;Remember that I &lt;a href=&quot;http://sebastian-bergmann.de/archives/909-On-Sponsored-Open-Source-Development.html&quot;&gt;promised to blog&lt;/a&gt; about the requirements planning for more sophisticated support of code coverage metrics in PHP tools that I did with &lt;a href=&quot;http://derickrethans.nl/&quot;&gt;Derick&lt;/a&gt; earlier this year? While we met in London in February and Montreal in March to discuss this, both of us were too busy to communicate what we want to do yet.&lt;/p&gt;&lt;p&gt;This blog posting will hopefully shine a light on what it is we are planning.&lt;/p&gt;
&lt;h3&gt;Current Situation&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Code_coverage&quot;&gt;Code Coverage&lt;/a&gt; is a common metric used in software testing. &lt;a href=&quot;http://phpunit.de/&quot;&gt;PHPUnit&lt;/a&gt; supports this valuable software metric by leveraging the &lt;a href=&quot;https://github.com/sebastianbergmann/php-code-coverage&quot;&gt;PHP_CodeCoverage&lt;/a&gt; component which in turn makes use of &lt;a href=&quot;http://xdebug.org/&quot;&gt;Xdebug&lt;/a&gt;, an extension to the PHP interpreter. The support for code coverage could, however, be improved even further.&lt;/p&gt;
&lt;p&gt;Xdebug currently only supports what is usually referred to as &lt;strong&gt;Line Coverage&lt;/strong&gt;. This software metric measures whether each executable line was executed.&lt;/p&gt;
&lt;p&gt;Based on the line coverage information provided by Xdebug, PHP_CodeCoverage also calculates the &lt;strong&gt;Function / Method Coverage&lt;/strong&gt; software metric that measures whether each function or method has been invoked. This software metric is actually implemented in a much stricter way in PHP_CodeCoverage because it only considers a function or method as covered when all of its executable lines are executed at least once during test execution.&lt;/p&gt;
&lt;h3&gt;The Future&lt;/h3&gt;
&lt;p&gt;In the future it would be nice to make available more sophisticated code coverage metrics such as Statement Coverage, Branch Coverage, Call Coverage, and Path Coverage to the users of PHPUnit, PHP_CodeCoverage, and Xdebug.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Statement Coverage&lt;/strong&gt; measures whether each statement is executed (a line of code can contain more than one statement). A mapping from statement to the start and end column in the corresponding line of code is desirable but would require changing PHP's compiler. It is, however, possible to extend Xdebug to report the number executable and executed statements for a line of code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Branch Coverage&lt;/strong&gt; measures whether the boolean expression of each control structure evaluated to both TRUE and FALSE during the execution of the test suite. This should be relatively easy to implement based on the information provided by Statement Coverage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Call Coverage&lt;/strong&gt; measures whether each function or method call is executed and should be possible to implement in userland (in PHP_CodeCoverage) based on static code analysis and statement coverage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Path Coverage&lt;/strong&gt; measures whether each of the possible paths in each function or method has been followed. A path is a unique sequence of branches from the entry of the function or methods to its exit. It should be possible to implement this in userland (in PHP_CodeCoverage) based on static code analysis and branch coverage.&lt;/p&gt;
&lt;p&gt;As an alternative to Path Coverage it might make sense to implement &lt;strong&gt;Linear Code Sequence and Jump (LCSAJ) Coverage&lt;/strong&gt; instead. This variation of Path Coverage does not require a flow graph and also avoids its exponential difficulty. It should be possible to implement in userland (in PHP_CodeCoverage) based on static code analysis and branch coverage.&lt;/p&gt;&lt;p&gt;The development of these features will take a lot of effort. It will be a challenge to find time in our schedules to work to tackle these features. But I felt like sharing what we are thinking about with you, the users of our tools, as soon as possible.&lt;/p&gt;</description>
	<pubDate>Fri, 17 Jun 2011 18:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Laura Beth Lincoln Denker: When to Write Your Own Mocks</title>
	<guid>http://elblinkin.info/?p=80</guid>
	<link>http://elblinkin.info/2011/06/when-to-write-your-own-mocks/</link>
	<description>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 [...]</description>
	<pubDate>Tue, 07 Jun 2011 02:33:37 +0000</pubDate>
</item>
<item>
	<title>Laura Beth Lincoln Denker: Testing Your Mocks</title>
	<guid>http://elblinkin.info/?p=43</guid>
	<link>http://elblinkin.info/2011/06/testing-your-mocks/</link>
	<description>Very few times, is it OK to write your own mock class, by hand, for an existing class. &#160;We&amp;#8217;ll save the nitty gritty of that statement for a later rant. &#160; 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 [...]</description>
	<pubDate>Fri, 03 Jun 2011 00:19:57 +0000</pubDate>
</item>
<item>
	<title>Quality Assurance in PHP Projects: The English Edition Started Shipping!</title>
	<guid>http://qualityassuranceinphpprojects.com/archives/20-guid.html</guid>
	<link>http://qualityassuranceinphpprojects.com/archives/20-The-English-Edition-Started-Shipping!.html</link>
	<description>&lt;p&gt;The &lt;a href=&quot;http://qualityassuranceinphpprojects.com/pages/english_edition.html&quot;&gt;English Edition&lt;/a&gt; of the PHP Quality Assurance book started shipping. &lt;a href=&quot;http://priebsch.de/&quot;&gt;Stefan&lt;/a&gt; and I, as well as all our &lt;a href=&quot;http://qualityassuranceinphpprojects.com/categories/Case-Studies&quot;&gt;contributing authors&lt;/a&gt;, are very happy about this. Below you can find additional information about the book.&lt;/p&gt;&lt;a href=&quot;http://www.amazon.com/Real-World-Developing-High-Quality-Frameworks-Applications/dp/0470872497/&quot;&gt;&lt;img src=&quot;http://qualityassuranceinphpprojects.com/uploads/cover_en.jpg&quot; alt=&quot;Real-World Solutions for Developing High-Quality PHP Frameworks and Applications&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;p&gt;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.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Looks at the characteristics of good internal and external software quality&lt;/li&gt;&lt;li&gt;Shares techniques for writing new code, changing and optimizing existing code, and finding and fixing bugs&lt;/li&gt;&lt;li&gt;Reveals bad testing practices so you know what to avoid&lt;/li&gt;&lt;li&gt;Addresses how to test service-oriented APIs, a WebDAV server, and many PHP frameworks&lt;/li&gt;&lt;li&gt;Reviews large-scale Selenium-based testing and testing database interaction&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With this book, you will learn to develop high-quality PHP frameworks and applications that can easily be maintained with reasonable cost and effort.&lt;/p&gt;</description>
	<pubDate>Tue, 10 May 2011 10:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Laura Beth Lincoln Denker: PHP Community Conference 2011</title>
	<guid>http://elblinkin.info/?p=8</guid>
	<link>http://elblinkin.info/2011/04/php-community-conference/</link>
	<description>Slides for my talk &amp;#8220;Is It Handmade Code If You Use Power Tools?&amp;#8221; are now available on Slide Share. As presented at the inaugural PHPComCon in Nashville, TN. Php com con-2011</description>
	<pubDate>Fri, 29 Apr 2011 17:47:21 +0000</pubDate>
</item>
<item>
	<title>Lars Jankowfsky: Still alive!</title>
	<guid>http://www.frontalaufprall.com/?p=199</guid>
	<link>http://www.frontalaufprall.com/2011/04/28/still-alive/</link>
	<description>&lt;p&gt;Wow&amp;#8230; more than one year since my last post. Time flies, especially if your company got aquired and you experience suddenly very exciting adventures. What a year!&lt;/p&gt;
&lt;p&gt;Anyway, back to business - I&amp;#8217;ll increase slowly my public appearance and therefore I am happy to announce these two upcoming events:&lt;/p&gt;
&lt;p&gt;1. I am attending next week a &lt;a href=&quot;http://www.eventbrite.com/event/1438094379&quot;&gt;MASS Technology Leadership Council Breakfast Seminar&lt;/a&gt; in Cambridge, MA where I&amp;#8217;ll speak about &amp;#8220;the Secrets to Achieving Unprecedented Rates of Growth and Innovation&amp;#8221; at KAYAK &lt;img src=&quot;http://www.frontalaufprall.com/wp-includes/images/smilies/icon_wink.gif&quot; alt=&quot;;)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;2. I got another chance to visit beautiful Hamburg - always worth a visit where I&amp;#8217;ll run two Sessions (in German) at the &lt;a href=&quot;http://www.devcon-hamburg.de/&quot;&gt;Devcon Hamburg&lt;/a&gt;.&lt;br /&gt;
Once again - Agile Development with PHP and an interesting session about our Caching/Sharding/Distributing Strategies @ swoodoo.com when getting hammered by TV traffic.&lt;/p&gt;
&lt;p&gt;Your choice - Boston or Hamburg &lt;img src=&quot;http://www.frontalaufprall.com/wp-includes/images/smilies/icon_wink.gif&quot; alt=&quot;;)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;</description>
	<pubDate>Thu, 28 Apr 2011 09:20:49 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: Dealing with segfaults while PHPUnit code coverage generation for CI</title>
	<guid>http://edorian.posterous.com/dealing-with-segfaults-while-phpunit-code-cov</guid>
	<link>http://edorian.posterous.com/dealing-with-segfaults-while-phpunit-code-cov</link>
	<description>&lt;p&gt;
	&lt;h1&gt;Oh, the build failed?&lt;/h1&gt;

&lt;p&gt;Let&amp;rsquo;s look at the console output!&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;phpunit
[...]
Return code: 139
[...]
Build FAILED!&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;sigh&lt;/em&gt;. Not again!&lt;/p&gt;

&lt;h1&gt;The Problem&lt;/h1&gt;

&lt;p&gt;About half the &amp;ldquo;Build failed&amp;rdquo; mails I&amp;rsquo;ve gotten from &lt;a href=&quot;http://jenkins-ci.org&quot;&gt;Jenkins&lt;/a&gt; in the last two weeks where not due to me breaking the tests but just &lt;a href=&quot;http://phpunit.de&quot;&gt;PHPUnit&lt;/a&gt; segfaulting. Wait! I know &lt;strong&gt;PHPUnit can&amp;rsquo;t segfault!&lt;/strong&gt;&amp;ldquo;, only PHP itself can.&lt;/p&gt;

&lt;p&gt;And it does, quite often. For some reason that probably has to do with using &lt;strong&gt;PHP 5.2.OLD&lt;/strong&gt; it doesn&amp;rsquo;t survive generate the clover.xml file or the HTML report about 20% of the times it&amp;rsquo;s being run.&lt;/p&gt;

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

&lt;p&gt;So for now I&amp;rsquo;d like Jenkins to not send me a mail when that has happened. I don&amp;rsquo;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&amp;rsquo;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.&lt;/p&gt;

&lt;h1&gt;The &amp;ldquo;Solution&amp;rdquo;&lt;/h1&gt;

&lt;p&gt;For now I&amp;rsquo;ll just rerun PHPUnit until it gets there. The script below does, for now, a pretty good job at that.&lt;/p&gt;

&lt;p&gt;It wraps the &amp;ldquo;phpunit&amp;rdquo; 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.&lt;/p&gt;

&lt;p&gt;Sometimes the build takes a little longer (if it runs twice) but so far i haven&amp;rsquo;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!&lt;/p&gt;

&lt;h1&gt;The Code&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;phpunit-segfault-wrapper&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;#!/usr/bin/env bash

returnCode=139; # Segfault

echo &amp;quot;Starting PHPUnit Segfault Wrapper&amp;quot;;
echo

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

echo
echo &amp;quot;Done with PHPUnit&amp;quot;;
echo

exit $returnCode&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;hr /&gt;

&lt;p&gt;Placing that file next to your build.xml and a changing the &amp;ldquo;phpunit&amp;rdquo; call to a &amp;ldquo;phpunit-segfault-wrapper&amp;rdquo; call is all there is left to do.&lt;/p&gt;

&lt;h1&gt;Disclamer&lt;/h1&gt;

&lt;p&gt;Chris Cornutt over at &lt;a href=&quot;http://phpdeveloper.org/news/16197&quot;&gt;phpdeveloper.org&lt;/a&gt; pretty much nailed it:&lt;/p&gt;

&lt;blockquote class=&quot;posterous_short_quote&quot;&gt;&lt;p&gt;If something was seriously broken, this could cause all sorts of problems, but in theory it&amp;rsquo;s a simple hack that gets the job done.&lt;/p&gt;&lt;/blockquote&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/dealing-with-segfaults-while-phpunit-code-cov&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/dealing-with-segfaults-while-phpunit-code-cov#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Tue, 12 Apr 2011 22:41:00 +0000</pubDate>
</item>
<item>
	<title>Sebastian Bergmann: Debugging with Git and PHPUnit</title>
	<guid>http://sebastian-bergmann.de/archives/911-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/911-Debugging-with-Git-and-PHPUnit.html</link>
	<description>&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; can be used to find the change that introduced a bug. It does so by performing a binary search on the list of commits between a known &lt;em&gt;good&lt;/em&gt; and a known &lt;em&gt;bad&lt;/em&gt; state of the repository. A tool such as &lt;a href=&quot;http://phpunit.de/&quot;&gt;PHPUnit&lt;/a&gt; can be invoked at each step of the binary search to check whether or not the current state is broken.&lt;/p&gt;
&lt;p&gt;Let us assume that the unit tests for our project fail at the current &lt;code&gt;HEAD&lt;/code&gt; of the &lt;code&gt;master&lt;/code&gt; branch:&lt;/p&gt;
&lt;dl&gt;&lt;dd&gt;&lt;pre&gt;sb@ubuntu bankaccount % ant
Buildfile: /home/sb/bankaccount/build.xml

phpunit:
     [exec] PHPUnit 3.5.13 by Sebastian Bergmann.
     [exec] 
     [exec] FSSSS
     [exec] 
     [exec] Time: 0 seconds, Memory: 4.50Mb
     [exec] 
     [exec] There was 1 failure:
     [exec] 
     [exec] 1) BankAccountTest::testBalanceIsInitiallyZero
     [exec] Failed asserting that &amp;lt;integer:1&amp;gt; matches expected &amp;lt;integer:0&amp;gt;.
     [exec] 
     [exec] /home/sb/bankaccount/tests/BankAccountTest.php:7
     [exec] 
     [exec] FAILURES!
     [exec] Tests: 1, Assertions: 1, Failures: 1, Skipped: 4.

BUILD FAILED&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;We know that the code worked when we initially imported it. So we need to look up the hash of the initial commit:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;pre&gt;sb@ubuntu bankaccount % git log --pretty=oneline
3e83825c0695bcfc1ea38880352b3449f578e4f0 Do not run PHPUnit in verbose mode by default.
48b683a02c54e732a8c3045b21c4f9183343dea8 Remove @covers annotations.
d54ba9eb910ce9fe9feafa6b9dbd2675ce43227a Break something.
e0c72d7409e461833ce1842e994de4148aa68da4 Remove comment.
75c5d82a31c768d28847d1908cfaa7d15fece4f7 Initial import.&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;Now we can tell Git that the initial commit was &lt;em&gt;good&lt;/em&gt; and that the current state is &lt;em&gt;bad&lt;/em&gt;:


&lt;dl&gt;&lt;dd&gt;&lt;pre&gt;sb@ubuntu bankaccount % git bisect start
sb@ubuntu bankaccount % git bisect bad
sb@ubuntu bankaccount % git bisect good 75c5d82a31c768d28847d1908cfaa7d15fece4f7
Bisecting: 1 revision left to test after this (roughly 1 step)
[d54ba9eb910ce9fe9feafa6b9dbd2675ce43227a] Break something.&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;Next up is actually performing the binary search operation. At each step we use Apache Ant to invoke PHPUnit. The commit will be considered &lt;em&gt;good&lt;/em&gt; when all tests pass and &lt;em&gt;bad&lt;/em&gt; otherwise.&lt;/p&gt;
&lt;dl&gt;&lt;dd&gt;&lt;pre&gt;sb@ubuntu bankaccount % git bisect run ant -q
running ant -q
BUILD FAILED

Bisecting: 0 revisions left to test after this (roughly 0 steps)
[e0c72d7409e461833ce1842e994de4148aa68da4] Remove comment.

running ant -q
BUILD SUCCESSFUL

d54ba9eb910ce9fe9feafa6b9dbd2675ce43227a is the first bad commit

commit d54ba9eb910ce9fe9feafa6b9dbd2675ce43227a
Author: Sebastian Bergmann 
Date:   Thu Mar 17 10:26:56 2011 +0100

    Break something.

bisect run success&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;And this is how you debug using Git and PHPUnit&lt;/p&gt;&lt;/p&gt;</description>
	<pubDate>Fri, 18 Mar 2011 11:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Sebastian Bergmann: Visualization of PHPUnit Development</title>
	<guid>http://sebastian-bergmann.de/archives/910-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/910-Visualization-of-PHPUnit-Development.html</link>
	<description>&lt;p&gt;According to &lt;code&gt;svn.php.net&lt;/code&gt;, I committed the first PHPUnit code to &lt;code&gt;cvs.php.net&lt;/code&gt; on November 27th 2001 and the first release, PHPUnit 0.1, was made on December 1st 2001.&lt;/p&gt;
&lt;p&gt;I started using &lt;code&gt;svn.phpunit.de&lt;/code&gt; for the development of PHPUnit on &lt;a href=&quot;http://sebastian-bergmann.de/archives/610-So-Long,-and-Thanks-for-All-the-PEARs.html&quot;&gt;June 29th 2006&lt;/a&gt;. I did not import any history from CVS into Subversion.&lt;/p&gt;
&lt;p&gt;On &lt;a href=&quot;http://sebastian-bergmann.de/archives/876-PHPUnit-Development-Moved-to-GitHub.html&quot;&gt;December 26th 2009&lt;/a&gt;, I moved the development of PHPUnit from &lt;code&gt;svn.phpunit.de&lt;/code&gt; to &lt;a href=&quot;http://github.com/sebastianbergmann/phpunit&quot;&gt;GitHub&lt;/a&gt;. I imported the history from Subversion into Git. As you can see in the video, moving to GitHub lead to an increased number of contributions to PHPUnit.&lt;/p&gt;</description>
	<pubDate>Wed, 16 Mar 2011 06:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Volker Dusch: Please ship your own coding standard as part of your project</title>
	<guid>http://edorian.posterous.com/please-ship-your-own-coding-standard-as-part</guid>
	<link>http://edorian.posterous.com/please-ship-your-own-coding-standard-as-part</link>
	<description>&lt;p&gt;
	&lt;h1&gt;What?&lt;/h1&gt;

&lt;p&gt;I assume most of you know why we, as programmers, define something called a &lt;a href=&quot;http://en.wikipedia.org/wiki/Coding_conventions&quot;&gt;coding standard&lt;/a&gt; for a project.&lt;/p&gt;

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

&lt;h1&gt;Why?&lt;/h1&gt;

&lt;p&gt;Having a well defined set of rules allows for easier collaboration between members of a project, produces code that looks more like &amp;ldquo;one person wrote it&amp;rdquo; and that&amp;rsquo;s easier to follow, understand and change.&lt;/p&gt;

&lt;p&gt;If there would be no written rules it would just make it harder to grasp a project or to contribute to it.&lt;/p&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;So?&lt;/h1&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which one to use&lt;/li&gt;
&lt;li&gt;How to help enforce it&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;PHP doesn&amp;rsquo;t tell you what &lt;a href=&quot;http://www.python.org/dev/peps/pep-0008/&quot;&gt;the one true way do go about things&lt;/a&gt; is, like python does. So it is even more important to make developers care about what code THIS project looks like.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;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 &lt;em&gt;apply common sense&lt;/em&gt; and &lt;em&gt;what works for you works&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So lets talk about ways to enforce it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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&amp;rsquo;t look right.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;How?&lt;/h1&gt;

&lt;p&gt;While there might be other tools out there I&amp;rsquo;m only going to talk about &lt;a href=&quot;http://pear.php.net/manual/en/package.php.php-codesniffer.intro.php&quot;&gt;PHP_CodeSniffer&lt;/a&gt; and the PHP Mess Detector &lt;a href=&quot;http://phpmd.org/&quot;&gt;PHPMD&lt;/a&gt;. They integrate nicely into Jenkins and let me do everything i want to do when it comes to a coding standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Both tools enable to you do define one .xml file with your defined rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Those files should go somewhere into your project sources. For this post and the example included I&amp;rsquo;m going to stick with a folder layout that works nicely with &lt;a href=&quot;http://jenkins-php.org/&quot;&gt;http://jenkins-php.org/&lt;/a&gt; and the &lt;a href=&quot;https://github.com/sebastianbergmann/php-project-wizard&quot;&gt;PHP Project Wizard&lt;/a&gt;. Of course every other layout will just work out too.&lt;/p&gt;

&lt;p&gt;So if the root project looks like this:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;root
|-- source
|-- tests
|-- docs&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;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.&lt;/p&gt;

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

&lt;p&gt;So the new root folder looks like this:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;root
|-- source
|-- tests 
|-- docs
|-- build.xml
`-- build
    |-- phpcs.xml
    |-- phpmd.xml&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;For now i don&amp;rsquo;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So i created those file and people checked out my code what can they do now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now every developer can run&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;ant checkcode (or whatever you named the task, i am not to sure myself)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;or just&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;phpcs --standard=build/phpcs.xml source
phpmd source text build/phpmd.xml&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;Now if that contributor goes to change something about your code he can run your tools to make his clean &amp;ldquo;pretty&amp;rdquo; before handing it over to you.&lt;/p&gt;

&lt;p&gt;Of course the first step after a change is to run your unittests and making sure his change doesn&amp;rsquo;t break anything. For those tests you might also want to provide a phpunit.dist.xml so that running &amp;ldquo;phpunit&amp;rdquo; in the root folder does the bootstrap and runs the tests without the contributor having to know how to run your suite.&lt;/p&gt;

&lt;p&gt;You as the maintainer have the added bonus of doing all that yourself.&lt;/p&gt;

&lt;h1&gt;Wrapping up&lt;/h1&gt;

&lt;p&gt;When drafting this post i thought about going into the creation of the three .xml files (&lt;a href=&quot;http://www.phpunit.de/manual/current/en/appendixes.configuration.html&quot;&gt;phpunit.dist&lt;/a&gt;, &lt;a href=&quot;http://phpmd.org/documentation/creating-a-ruleset.html&quot;&gt;phpmd&lt;/a&gt;, &lt;a href=&quot;http://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php&quot;&gt;phpcs&lt;/a&gt;) but this is getting quite long and figuring out how to create those files isn&amp;rsquo;t that hard. If you want me to elaborate on one of the subjects touched upon here let me now.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/please-ship-your-own-coding-standard-as-part&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/please-ship-your-own-coding-standard-as-part#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Sun, 13 Mar 2011 17:58:17 +0000</pubDate>
</item>
<item>
	<title>VG Tech Blog: Mocking the file system using PHPUnit and vfsStream</title>
	<guid>http://tech.vg.no/?p=9</guid>
	<link>http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=mocking-the-file-system-using-phpunit-and-vfsstream</link>
	<description>&lt;p&gt;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.&lt;span id=&quot;more-9&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Those of you still reading are hopefully familiar with unit testing. &lt;a href=&quot;http://phpunit.de&quot; target=&quot;_blank&quot;&gt;PHPUnit&lt;/a&gt; is the de-facto standard for unit testing in PHP projects, and this is what we will be using together with &lt;a href=&quot;http://code.google.com/p/bovigo/wiki/vfsStream&quot; target=&quot;_blank&quot;&gt;vfsStream&lt;/a&gt; in this article.&lt;/p&gt;
&lt;p&gt;vfsStream is a &lt;a href=&quot;http://no2.php.net/streams&quot; target=&quot;_blank&quot;&gt;custom stream wrapper&lt;/a&gt; for PHP that works as a virtual file system that PHP&amp;#8217;s built in filesystem functions can use. Some functions that work with vfsStream are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/file_exists&quot; target=&quot;_blank&quot;&gt;file_exists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/copy&quot; target=&quot;_blank&quot;&gt;copy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/mkdir&quot; target=&quot;_blank&quot;&gt;mkdir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/unlink&quot; target=&quot;_blank&quot;&gt;unlink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/is_file&quot; target=&quot;_blank&quot;&gt;is_file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/is_dir&quot; target=&quot;_blank&quot;&gt;is_dir&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some known limitations when using custom stream wrappers. Some functions that does not work with vfsStream:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/realpath&quot; target=&quot;_blank&quot;&gt;realpath&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/chmod&quot; target=&quot;_blank&quot;&gt;chmod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/chown&quot; target=&quot;_blank&quot;&gt;chown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/chgrp&quot; target=&quot;_blank&quot;&gt;chgrp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/touch&quot; target=&quot;_blank&quot;&gt;touch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://no2.php.net/move_uploaded_file&quot; target=&quot;_blank&quot;&gt;move_uploaded_file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;vfsStreams&amp;#8217; known limitations are &lt;a href=&quot;http://code.google.com/p/bovigo/wiki/vfsStreamDocsKnownIssues&quot; target=&quot;_blank&quot;&gt;listed on its wiki&lt;/a&gt;. Now, on to the code!&lt;/p&gt;
&lt;p&gt;The following simplified class is the class we will be testing using PHPUnit and the vfsStream stream wrapper:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;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-&amp;gt;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-&amp;gt;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-&amp;gt;rootDir . '/' . $hash);
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;PS!&lt;/strong&gt; The class is very simplified and does not include error handling at all. It should only be used for instructional purposes.&lt;/p&gt;
&lt;p&gt;As you can see the class uses regular file system functions such as &lt;code&gt;copy&lt;/code&gt;, &lt;code&gt;unlink&lt;/code&gt;, and &lt;code&gt;file_get_contents&lt;/code&gt;. To be able to get full code coverage on this class all these functions need to work their magic.&lt;/p&gt;
&lt;p&gt;A typical way to solve this when writing tests is to create files/folders in PHPUnit&amp;#8217;s &lt;code&gt;setUp()&lt;/code&gt; method and remove them again in the &lt;code&gt;tearDown()&lt;/code&gt; 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&amp;#8217;s safer to work on a virtual file system than an actual one.&lt;/p&gt;
&lt;p&gt;Now, lets take a look at the basics of vfsStream. First you will need to install it. This can be done easily using &lt;a href=&quot;http://pear.php.net/&quot; target=&quot;_blank&quot;&gt;PEAR&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;$ pear channel-discover pear.php-tools.net
$ pear install pat/vfsStream-beta&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The following snippet will show you the basics of vfsStream:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;&amp;lt;?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-&amp;gt;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&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First we simply require the main &lt;code&gt;vfsStream&lt;/code&gt; class (that in turn will require other components as well). The next three lines registers the stream wrapper (which defaults to &lt;strong&gt;vfs://&lt;/strong&gt;) and creates the root directory which &lt;code&gt;vfsStream&lt;/code&gt; will use as a container for other virtual files and directories. These three lines can be replaced by:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;$root = vfsStream::setup('someDir');&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which is a convenience method that will be used in the unit tests later on.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;vfsStream::url&lt;/code&gt; 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.&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;var_dump(vfsStream::url('someDir')); // &quot;vfs://someDir&quot;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next few lines in the code snippet just illustrates how the regular file system functions work with &lt;code&gt;vfsStream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To add a file we first create a new &lt;code&gt;vfsStreamFile&lt;/code&gt; object by calling &lt;code&gt;vfsStream::newFile()&lt;/code&gt; which simply takes a filename as argument. We attach it to the root directory by using the root object&amp;#8217;s &lt;code&gt;addFile&lt;/code&gt; 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.&lt;/p&gt;
&lt;p&gt;Now that we have the basic usage of vfsStream out of the way, let&amp;#8217;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&amp;#8217;ll add them later on.&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;&amp;lt;?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-&amp;gt;driver = new VGF_Storage_Driver_Filesystem();
        $this-&amp;gt;driver-&amp;gt;rootDir = vfsStream::url('someDir');
    }

    /**
     * Tear down method
     *
     * This method will destroy the instance of the driver
     */
    public function tearDown() {
        $this-&amp;gt;driver = null;
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see from the code snippet we use the &lt;code&gt;vfsStream::setup&lt;/code&gt; method to create a root dir, and set that dir as the &lt;code&gt;rootDir&lt;/code&gt; in the driver. No action is needed in the &lt;code&gt;tearDown()&lt;/code&gt; method regarding &lt;code&gt;vfsStream&lt;/code&gt;. The first test we will write shall test the &lt;code&gt;store&lt;/code&gt; method.&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;/**
 * Test the store method in the driver
 */
public function testStore() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();

    $this-&amp;gt;assertFalse($root-&amp;gt;hasChild($hash));
    $this-&amp;gt;assertTrue($this-&amp;gt;driver-&amp;gt;store(__FILE__, $hash));
    $this-&amp;gt;assertTrue($root-&amp;gt;hasChild($hash));
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;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 &lt;code&gt;store&lt;/code&gt; method. After storing the file we assert that it now exists. The &lt;code&gt;vfsStreamWrapper::getRoot()&lt;/code&gt; method returns the root &lt;code&gt;vfsStreamDirectory&lt;/code&gt; object, on which we call the &lt;code&gt;hasChild()&lt;/code&gt; method to see if it has a child with a given name.&lt;/p&gt;
&lt;p&gt;Next up is the &lt;code&gt;delete&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;/**
 * Test the delete method in the driver
 */
public function testDelete() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();
    $root-&amp;gt;addChild(vfsStream::newFile($hash));

    $this-&amp;gt;assertTrue($root-&amp;gt;hasChild($hash));
    $this-&amp;gt;assertTrue($this-&amp;gt;driver-&amp;gt;delete($hash));
    $this-&amp;gt;assertFalse($root-&amp;gt;hasChild($hash));
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is pretty much the same as the previous test method except that we register a virtual file before calling &lt;code&gt;delete()&lt;/code&gt;. After deleting we assert that the file is actually gone. Now for the last test:&lt;/p&gt;
&lt;div class=&quot;code_wrap&quot;&gt;&lt;a href=&quot;http://tech.vg.no/category/qa/unit-testing/feed/&quot; class=&quot;code_opener&quot;&gt;Show code&lt;/a&gt;&lt;pre class=&quot;brush: php&quot;&gt;/**
 * Test the get method in the driver
 */
public function testGet() {
    $hash = md5(microtime());
    $content = 'some content';
    $file = vfsStream::newFile($hash);
    $file-&amp;gt;setContent($content);
    vfsStreamWrapper::getRoot()-&amp;gt;addChild($file);

    $this-&amp;gt;assertSame($content, $this-&amp;gt;driver-&amp;gt;get($hash));
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this last test method we create a virtual file with content by using the &lt;code&gt;setContent()&lt;/code&gt; method on the &lt;code&gt;vfsStreamFile&lt;/code&gt; object. After adding the virtual file we assert that we get the same content when fetching the file identified by &lt;code&gt;$hash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s that! If anyone has used vfsStream differently or has related questions, don&amp;#8217;t hesitate to leave a comment. Happy testing!&lt;/p&gt;
&lt;p&gt;Related links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Unit_testing&quot; target=&quot;_blank&quot;&gt;Unit testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://phpunit.de&quot; target=&quot;_blank&quot;&gt;PHPUnit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/bovigo/wiki/vfsStream&quot; target=&quot;_blank&quot;&gt;vfsStream&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Wed, 09 Mar 2011 14:47:07 +0000</pubDate>
</item>
<item>
	<title>Quality Assurance in PHP Projects: PHPQABOOK: Status Update</title>
	<guid>http://qualityassuranceinphpprojects.com/archives/19-guid.html</guid>
	<link>http://qualityassuranceinphpprojects.com/archives/19-PHPQABOOK-Status-Update.html</link>
	<description>Almost a year has passed since we &lt;a href=&quot;http://qualityassuranceinphpprojects.com/archives/17-Almost-Done.html&quot;&gt;finished the manuscript&lt;/a&gt; for the German edition of the book -- and almost half a year since the German edition &lt;a href=&quot;http://qualityassuranceinphpprojects.com/archives/18-The-German-Edition-Started-Shipping!.html&quot;&gt;started shipping&lt;/a&gt;. High time for another status update.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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 &quot;&lt;a href=&quot;http://qualityassuranceinphpprojects.com/pages/english_edition.html&quot;&gt;Real-World Solutions for Developing High-Quality PHP Frameworks and Applications&lt;/a&gt;&quot;.</description>
	<pubDate>Wed, 09 Mar 2011 12:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Volker Dusch: Setting up Jenkins for PHP Projects</title>
	<guid>http://edorian.posterous.com/setting-up-jenkins-for-php-projects</guid>
	<link>http://edorian.posterous.com/setting-up-jenkins-for-php-projects</link>
	<description>&lt;p&gt;
	&lt;div&gt;&lt;br /&gt;One and a half month ago i wrote &lt;a href=&quot;http://edorian.posterous.com/setting-up-hudson-for-php-projects&quot;&gt;a little guide about Setting up Hudson for PHP Projects in 15 minutes&lt;/a&gt;, 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 :)&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div&gt;Since then two relevant important things happened. &lt;a href=&quot;http://www.infoq.com/news/2011/01/jenkins&quot;&gt;Hudson got renamed to Jenkins&lt;/a&gt; moved away from &lt;a href=&quot;http://hudson-ci.org/&quot;&gt;http://hudson-ci.org/&lt;/a&gt; (which oracles still supports afaik) and over to &lt;a href=&quot;http://jenkins-ci.org/&quot;&gt;http://jenkins-ci.org/&lt;/a&gt;. I'll be talking about the site with the &quot;Like&quot; Button, not the one with the oracle logo from now one. While this was happening &lt;a href=&quot;http://sebastian-bergmann.de/&quot;&gt;Sebastian&lt;/a&gt; created the wonderful &lt;a href=&quot;http://jenkins-php.org/&quot;&gt;&lt;strong&gt;http://jenkins-php.org/&lt;/strong&gt;&lt;/a&gt; and polished the setup instructions that are now featured there with me contributing some minor details for the new phploc graphs.&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div&gt;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.&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div&gt;This guide will feature two parts. The first one beeing the obligatory &quot;why do i need this&quot; or maybe the &quot;why, dear friend or coworker who i send this link do YOU / WE need to install this&quot; resulting in a (spoiler): Because it's fucking awesome !&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div&gt;
&lt;h1&gt;Why ? (Scroll down for 'Installing! ')&amp;nbsp;&lt;/h1&gt;
&lt;h2&gt;For starters let's talk about what Jenkins is:&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Jenkins is a continuous integration server !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ok, that was helpful !&lt;/p&gt;
&lt;h2&gt;What is continuous integration server then ?&lt;/h2&gt;
For starters think of it as a glorified &quot;cron&quot; 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 &quot;works&quot; all the time. Since &quot;works&quot; is a pretty loose definition that also varies greatly among different types of Software these servers tend to be pretty flexible and open. &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot;&gt;For a longer explanation check Wikipedia.&lt;/a&gt;&amp;nbsp;
&lt;h2&gt;Why do i want one and what do i to with it ?&lt;/h2&gt;
&lt;p&gt;So PHP developers the last few years where awesome don't you think ? Many of us stopped &quot;programming&quot; and started &quot;creating software&quot;, our language matured greatly, got a pretty solid object model and more and more &quot;really big&quot; 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 &quot;quality software&quot;. Without going to much into detail for most people that boils down to stuff like automated testing and some sort of quality control.&lt;p&gt;&lt;/p&gt;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 &quot;works&quot;. 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.&lt;p&gt;&lt;/p&gt;This is where a continuous integration (ci) server jumps in !&lt;p&gt;&lt;/p&gt;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.&lt;/p&gt;
&lt;h2&gt;Why Jenkins&lt;/h2&gt;
&lt;p&gt;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.&lt;p&gt;&lt;/p&gt;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 &quot;show demo&quot; link !&lt;p&gt;&lt;/p&gt;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.&lt;p&gt;&lt;/p&gt;Coming from the Java world Hudson features a variety of quality measurement tools that are integrated into the ci server via plugins. The &quot;big&quot; 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.&lt;/p&gt;
&lt;h2&gt;Jenkins and PHP ?&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Then there was &lt;a href=&quot;https://github.com/sebastianbergmann/php-hudson-template/&quot;&gt;php-hudson-template&lt;/a&gt;, a small Github project started by Sebastian that took away most of the hassle.&lt;/p&gt;
&lt;p&gt;Now there is an updated version of the the project on&amp;nbsp;&lt;a href=&quot;http://jenkins-php.org/&quot;&gt;http://jenkins-php.org/&lt;/a&gt; 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.&lt;/p&gt;
&lt;h1&gt;Installing!&lt;/h1&gt;
&lt;p&gt;While Jenkins runs on pretty much anything for this guide i will be using &lt;strong&gt;Ubuntu 10.10.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install php5-cli&lt;br /&gt;sudo apt-get install php-pear&lt;br /&gt;sudo apt-get install php5-xdebug&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;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 ;)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;php -r 'var_dump(extension_loaded(&quot;xdebug&quot;));'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To install Jenkins follow &lt;a href=&quot;http://pkg.jenkins-ci.org/debian/&quot;&gt;http://pkg.jenkins-ci.org/debian/&lt;/a&gt; or if you are not on Ubuntu pick the system of your choosing on &lt;a href=&quot;http://jenkins-ci.org/&quot;&gt;http://jenkins-ci.org/&lt;/a&gt;. That will also take care of most the dependencies.&lt;/p&gt;
&lt;p&gt;For anything else that is needed:&lt;/p&gt;
&lt;p&gt;&lt;code&gt; sudo apt-get install ant&lt;br /&gt; sudo apt-get install git &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let's create an example project now:&lt;/p&gt;
&lt;p&gt;&lt;code&gt; cd ~&lt;br /&gt; mkdir mydemo&lt;br /&gt; cd mydemo&lt;br /&gt; git init&lt;br /&gt; mkdir src tests&lt;br /&gt; touch build.xml build.properties phpunit.xml.dist src/MyClass.php tests/MyClassTest.php&lt;br /&gt; echo &quot;build&quot; &amp;gt; .gitignore&lt;br /&gt; echo &quot;source=\${basedir}/src&quot; &amp;gt; build.properties&lt;br /&gt;git add src tests .gitignore build.xml build.properties&lt;/code&gt; &lt;code&gt;phpunit.xml.dist&lt;/code&gt; &lt;code&gt;&lt;br /&gt; git commit -m&quot;Inital dump&quot;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now &lt;a href=&quot;http://jenkins-php.org/&quot;&gt;head over to the guide&lt;/a&gt; and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install the Jenkins Plugins&lt;/li&gt;
&lt;li&gt;Install the required PHP Tools&lt;/li&gt;
&lt;li&gt;Copy the build.xml into your stuff into your build.xml&lt;/li&gt;
&lt;li&gt;Copy the following in your phpunit.dist.xml&lt;/li&gt;
&lt;li&gt;In addition to the other install commands run: &quot; &lt;strong&gt;java -jar jenkins-cli.jar -s &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; install-plugin git &lt;/strong&gt;&quot; since we are using git for this example&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;phpunit backupGlobals=&quot;false&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; backupStaticAttributes=&quot;false&quot;&lt;br /&gt;&amp;nbsp;        &amp;nbsp;syntaxCheck=&quot;false&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;testsuites&amp;gt;&lt;br /&gt;&amp;nbsp;   &amp;nbsp;&amp;lt;testsuite name=&quot;php-demo&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;     &amp;nbsp; &amp;nbsp;&amp;lt;directory suffix=&quot;Test.php&quot;&amp;gt;tests&amp;lt;/directory&amp;gt;&lt;br /&gt;&amp;nbsp;   &amp;nbsp;&amp;lt;/testsuite&amp;gt;&lt;br /&gt; &amp;lt;/testsuites&amp;gt;&lt;br /&gt;&amp;lt;logging&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;coverage-html&quot; target=&quot;build/coverage&quot; title=&quot;php-demo&quot;&lt;br /&gt;&amp;nbsp;     &amp;nbsp;charset=&quot;UTF-8&quot; yui=&quot;true&quot; highlight=&quot;true&quot;&lt;br /&gt;&amp;nbsp;     &amp;nbsp;lowUpperBound=&quot;35&quot; highLowerBound=&quot;70&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;coverage-clover&quot; target=&quot;build/logs/clover.xml&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;junit&quot; target=&quot;build/logs/junit.xml&quot; logIncompleteSkipped=&quot;false&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/logging&amp;gt;&lt;br /&gt;&amp;lt;/phpunit&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and fill your class and test with some code:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class MyClass {&lt;br /&gt;&amp;nbsp; &amp;nbsp; public function demo($a) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if($a == 1) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And a sample test for &quot;tests/MyClassTest.php&quot;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;require_once(&quot;src/MyClass.php&quot;);&lt;br /&gt;&lt;br /&gt;class MyClassTest extends PHPUnit_Framework_TestCase {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public function testDemo() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $x = new MyClass();&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;assertEquals(1, $x-&amp;gt;demo(1));&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Commit into git and let's get to the last step !&lt;/strong&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; cd ~/mydemo&lt;br /&gt; git commit -am&quot;Lets do this&quot;&lt;br /&gt;&amp;nbsp;cd /var/lib/jenkins/jobs&lt;br /&gt;sudo git clone git://github.com/sebastianbergmann/php-jenkins-template.git php-template&lt;br /&gt;sudo /etc/init.d/jenkins stop&lt;br /&gt;sudo /etc/init.d/jenkins start&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://jenkins-php.org/&quot;&gt;Now head back over to the guide&lt;/a&gt; and run through step 3 to finish&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For &quot;Fill in your 'Source Code Management' information.&quot; use&lt;/p&gt;
&lt;p&gt;&quot;Git&quot; and for the path use&lt;/p&gt;
&lt;p&gt;&lt;code&gt;file:///home/YOUR_USERNAME/mydemo&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DONE !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Click &quot;Build now&quot; two times and &amp;nbsp;look at all the pretty graphs.&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;/div&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/setting-up-jenkins-for-php-projects&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/setting-up-jenkins-for-php-projects#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Wed, 02 Feb 2011 00:02:00 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: Creating your custom PHPUnit output formats</title>
	<guid>http://edorian.posterous.com/creating-your-custom-phpunit-output-formats</guid>
	<link>http://edorian.posterous.com/creating-your-custom-phpunit-output-formats</link>
	<description>&lt;p&gt;
	
&lt;div&gt;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.&lt;p&gt;&lt;/p&gt;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.&lt;/div&gt;
&lt;div&gt;So let's play around a bit.&lt;/div&gt;
&lt;div&gt;A simple test:&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class DemoTest extends PHPUnit_Framework_TestCase {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; public function testPass() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; $this-&amp;gt;assertTrue(true);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; public function testFail() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; $this-&amp;gt;assertTrue(false);&lt;br /&gt;&amp;nbsp; } &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;and generate some xml, for that test i used the junit output:&lt;/div&gt;
&lt;div&gt;&lt;code&gt;phpunit --log-junit foo.xml DemoTest.php&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;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.&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&lt;br /&gt;&amp;lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&amp;gt;&lt;br /&gt;&amp;lt;xsl:template match=&quot;/&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;html&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;h1&amp;gt;Tests&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;xsl:for-each select=&quot;testsuites/testsuite&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h2&amp;gt;&amp;lt;xsl:value-of select=&quot;@name&quot;/&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;xsl:for-each select=&quot;testcase&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;li&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;xsl:value-of select=&quot;@name&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;xsl:if test=&quot;failure&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;b&amp;gt;Failed !&amp;lt;/b&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;i&amp;gt;&amp;lt;xsl:value-of select=&quot;*&quot;/&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/xsl:if&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/html&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;and using that with the xml output using a linux command line tool:&lt;/div&gt;
&lt;div&gt;&lt;code&gt;xsltproc foo.xsl foo.xml &amp;gt; output.html&amp;nbsp;&lt;/code&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div&gt;and that produces a nice litte html files:&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;h1&amp;gt;Tests&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;h2&amp;gt;DemoTest&amp;lt;/h2&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;li&amp;gt;testPass&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;li&amp;gt;testFail&amp;lt;b&amp;gt;Failed !&amp;lt;/b&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;i&amp;gt;DemoTest::testFail&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Failed asserting that &amp;amp;lt;boolean:false&amp;amp;gt; is true.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /home/edo/DemoTest.php:10&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/i&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;To make at least something a litte more useful out of that blog post:&lt;/div&gt;
&lt;div&gt;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.&lt;/div&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/creating-your-custom-phpunit-output-formats&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/creating-your-custom-phpunit-output-formats#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Thu, 20 Jan 2011 00:07:00 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: When embracing Separation of Concerns code reorganisation can be a bliss!</title>
	<guid>http://www.testically.org/?p=1940</guid>
	<link>http://www.testically.org/2011/01/18/when-embracing-separation-of-concerns-code-reorganisation-can-be-a-bliss/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.testically.org/wp-content/uploads/2011/01/reorganisation.png&quot;&gt;&lt;img class=&quot;alignleft size-medium wp-image-1941&quot; title=&quot;reorganisation&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/01/reorganisation-300x217.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;217&quot; /&gt;&lt;/a&gt;The design pattern that should be most repeatedly talked about should be Separation of Concerns (that&amp;#8217;s why I&amp;#8217;m doing that all the time).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Usually something like this would drag a lot of work behind. Unless..&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-1940&quot;&gt;&lt;/span&gt;Unless you cared for your classes to be decoupled.&lt;/p&gt;
&lt;p&gt;Take a look at &lt;a href=&quot;https://github.com/caefer/ImageTransform/commit/77aea541994b73297541b974a6918b417c579595&quot; target=&quot;_blank&quot;&gt;this commit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can see that a lot of classes moved namespaces and of course there is a lot of code touched to acknowledge this.&lt;/p&gt;
&lt;p&gt;However this wasn&amp;#8217;t much work. Mostly done by automatic substitution.&lt;/p&gt;
&lt;p&gt;Even most of my PHPUnit tests still passed during the process!&lt;/p&gt;
&lt;p&gt;All together the refactoring (of a few more commits than just the one) took about one hour in total.&lt;/p&gt;
&lt;p&gt;Currently &#160;there is a &lt;a title=&quot;Directory structure, third-party code, and more&quot; href=&quot;http://groups.google.com/group/symfony-devs/browse_thread/thread/72e740c8ec205811/f8683e29bc3cb784&quot; target=&quot;_blank&quot;&gt;discussion on the Symfony mailing&lt;/a&gt; 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. &lt;img src=&quot;http://www.testically.org/wp-includes/images/smilies/icon_wink.gif&quot; alt=&quot;;)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;</description>
	<pubDate>Tue, 18 Jan 2011 03:51:57 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: PHP 5.3 and the Symfony2 UniversalClassLoader &#8211; Where to load?</title>
	<guid>http://www.testically.org/?p=1924</guid>
	<link>http://www.testically.org/2011/01/13/php-5-3-and-the-symfony2-universalclassloader-where-to-load/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.testically.org/wp-content/uploads/2011/01/loading1.gif&quot;&gt;&lt;img class=&quot;alignleft size-full wp-image-1927&quot; title=&quot;loading&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/01/loading1.gif&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;While working on my rewrite of the &lt;a title=&quot;ImageTransform&quot; href=&quot;https://github.com/caefer/ImageTransform&quot; target=&quot;_blank&quot;&gt;ImageTransform&lt;/a&gt; library I decided to follow the PHP Standards Working Group proposal for naming schemes as well as using the new &lt;a href=&quot;http://docs.symfony-reloaded.org/guides/tools/autoloader.html&quot; target=&quot;_blank&quot;&gt;Symfony2 UniversalClassLoader&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But I&amp;#8217;m not yet sure what is the best approach to use this loader.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-1924&quot;&gt;&lt;/span&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;However this will not deliver instant plug&amp;#8217;n'play imho as you still have to require this one class file to trigger the registration.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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().&lt;/p&gt;
&lt;p&gt;I actuaally realized that when I wrote the &lt;a href=&quot;https://github.com/caefer/ImageTransform/blob/rewrite/tests/bootstrap.php&quot; target=&quot;_blank&quot;&gt;bootstrap file&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;So instead of including calls to UniversialClassLoader I will eventually only mention it in the docs I think.&lt;/p&gt;</description>
	<pubDate>Thu, 13 Jan 2011 03:35:37 +0000</pubDate>
</item>
<item>
	<title>Sebastian Bergmann: Testing Traits</title>
	<guid>http://sebastian-bergmann.de/archives/906-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/906-Testing-Traits.html</link>
	<description>&lt;p&gt;The other day I was using the &lt;a href=&quot;https://github.com/thePHPcc/bankaccount&quot;&gt;BankAccount&lt;/a&gt; sample application during a &lt;a href=&quot;http://www.phpunit.de/&quot;&gt;PHPUnit&lt;/a&gt; training. When I showed this code ...&lt;/p&gt;&lt;dl&gt;&lt;dd&gt;&lt;pre class=&quot;programlisting&quot;&gt;&lt;code&gt;&lt;span class=&quot;default&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;HashMap&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;//&amp;#160;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;... one of the developers said: &quot;That is wrong! A &lt;code&gt;Response&lt;/code&gt; is not a &lt;code&gt;HashMap&lt;/code&gt;. You should use delegation instead.&quot; And, of course, he was right. I replied with &quot;Actually, what we want to do here (once we have PHP 5.4) is to use &lt;a href=&quot;http://wiki.php.net/rfc/horizontalreuse&quot;&gt;traits&lt;/a&gt;.&quot;&lt;/p&gt;&lt;p&gt;I went ahead and refactored the code:&lt;/p&gt;&lt;dl&gt;&lt;dd&gt;&lt;pre class=&quot;programlisting&quot;&gt;&lt;code&gt;&lt;span class=&quot;default&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;HashMap&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$values&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;Response&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;//&amp;#160;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;To make sure that I did not break anything, I ran the test suite for the &lt;a href=&quot;https://github.com/thePHPcc/bankaccount&quot;&gt;BankAccount&lt;/a&gt; sample application. The tests for classes that previously extended &lt;code&gt;HashMap&lt;/code&gt; (&lt;code&gt;Response&lt;/code&gt;, for instance) still passed. Of course, the tests for &lt;code&gt;HashMap&lt;/code&gt; were now broken because trait cannot be instantiated.&lt;/p&gt;&lt;p&gt;Suddenly I had to think about making traits testable. This is what I came up with:&lt;/p&gt;&lt;dl&gt;&lt;dd&gt;&lt;pre class=&quot;programlisting&quot;&gt;&lt;code&gt;&lt;span class=&quot;default&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;HashMapTest&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;PHPUnit_Framework_TestCase&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;/**&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*&amp;#160;@covers&amp;#160;HashMap::get&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*/&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;testIsInitiallyEmpty&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;getObjectForTrait&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'HashMap'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;assertAttributeEmpty&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'values'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;/**&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*&amp;#160;@covers&amp;#160;&amp;#160;HashMap::set&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*&amp;#160;@covers&amp;#160;&amp;#160;HashMap::get&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*&amp;#160;@depends&amp;#160;testIsInitiallyEmpty&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;comment&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;*/&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;testSettingDataWorks&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&amp;#160;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;$hashMap&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;default&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;keyword&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;default&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;PHPUnit 3.6 (the current &lt;code&gt;master&lt;/code&gt; branch) supports the testing of traits through the new &lt;code&gt;getObjectForTrait()&lt;/code&gt; method. This method reuses the mock object code generator and returns an object of a class that &lt;code&gt;use&lt;/code&gt;s the trait-under-test.&lt;/p&gt;&lt;p&gt;Along the way, &lt;a href=&quot;https://github.com/sebastianbergmann/php-code-coverage&quot;&gt;PHP_CodeCoverage&lt;/a&gt; and &lt;a href=&quot;https://github.com/sebastianbergmann/php-token-stream&quot;&gt;PHP_TokenStream&lt;/a&gt; as well as &lt;a href=&quot;http://github.com/sebastianbergmann/phpunit-mock-objects&quot;&gt;PHPUnit_MockObject&lt;/a&gt; needed to be updated for traits, too.&lt;/p&gt;</description>
	<pubDate>Wed, 12 Jan 2011 08:45:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Christian Schaefer: The ideal use case to give TDD a try!</title>
	<guid>http://www.testically.org/?p=1920</guid>
	<link>http://www.testically.org/2011/01/12/the-ideal-use-case-to-give-tdd-a-try/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.testically.org/wp-content/uploads/2011/01/TestDrivenGameDevelopment.png&quot;&gt;&lt;img class=&quot;alignleft size-medium wp-image-1921&quot; title=&quot;TestDrivenGameDevelopment&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/01/TestDrivenGameDevelopment-300x186.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;186&quot; /&gt;&lt;/a&gt;What I called my &amp;#8220;little experience&amp;#8221; during the last two days is actually the attempt to rewrite the image manipulation library &lt;a href=&quot;https://github.com/stunami/ImageTransform&quot; target=&quot;_blank&quot;&gt;ImageTransform by Stuart Lowes&lt;/a&gt;, which itself is the attempt to turn the symfony plugin sfImageTransformPlugin into a standalone library (unfinished). It&amp;#8217;s not at all official and it might be binned again at some point. Until I know that it stays &lt;a href=&quot;https://github.com/caefer/ImageTransform/tree/rewrite&quot; target=&quot;_blank&quot;&gt;my personal toy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Today I just wrote &lt;a href=&quot;https://github.com/caefer/ImageTransform/commit/886d3efa255622814952566e3c4184c2ee9cb46a&quot; target=&quot;_blank&quot;&gt;my first transformation&lt;/a&gt; using this new architecture and it was just perfect to do it test driven: the resize transformation.&lt;span id=&quot;more-1920&quot;&gt;&lt;/span&gt;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.&lt;/p&gt;
&lt;p&gt;So four things have to be considered that effect the outcome. That&amp;#8217;s 16 different combinations!&lt;/p&gt;
&lt;p&gt;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&amp;#8217;s 5 starting situations!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All in all that&amp;#8217;s 80 different results!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And it is extremely tedious to test them all by hand of course..&lt;/p&gt;
&lt;p&gt;Now I said a few times that I never really got the hang of TDD. Writing tests first still doesn&amp;#8217;t feel natural to me though I intellectually accept it being superior to my way of coding.&lt;/p&gt;
&lt;p&gt;But in a situation like this even I started writing a test case before a single line of code!&lt;/p&gt;
&lt;p&gt;The test itself could not be simpler.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;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!&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;With this test in place I was able to implement a rather complicated algorithm in very little time and what&amp;#8217;s more I am very confident that it&amp;#8217;s correct because the test says so! &lt;img src=&quot;http://www.testically.org/wp-includes/images/smilies/icon_wink.gif&quot; alt=&quot;;)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;</description>
	<pubDate>Wed, 12 Jan 2011 03:13:37 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: Automatic class loading and naming conventions with Symfony2, PHPUnit and PHP 5.3</title>
	<guid>http://www.testically.org/?p=1914</guid>
	<link>http://www.testically.org/2011/01/11/automatic-class-loading-and-naming-conventions-with-symfony2-phpunit-and-php-5-3/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.testically.org/wp-content/uploads/2011/01/class-loader.jpg&quot;&gt;&lt;img class=&quot;alignleft size-medium wp-image-1915&quot; title=&quot;class-loader&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/01/class-loader-300x199.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;199&quot; /&gt;&lt;/a&gt;&lt;a title=&quot;Productivity gain when PHPUnit testing decoupled code&quot; href=&quot;http://bit.ly/dRDWu8&quot; target=&quot;_blank&quot;&gt;I mentioned yesterday&lt;/a&gt; that I am toying around with some little library code that is completely standalone.&lt;/p&gt;
&lt;p&gt;As I plan on using this code in a Symfony2 project later I chose to finally switch to PHP 5.3 including namespaces.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-1914&quot;&gt;&lt;/span&gt;Of course I don&amp;#8217;t fancy to come up with all that on my own. In fact I&amp;#8217;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 &lt;a href=&quot;http://groups.google.com/group/php-standards&quot; target=&quot;_blank&quot;&gt;PHP Standards Working Group&lt;/a&gt; and they agreed on a paper called &lt;a href=&quot;http://groups.google.com/group/php-standards/web/psr-0-final-proposal&quot; target=&quot;_blank&quot;&gt;PSR-0 Final Proposal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;So I went and created a simple dummy library with the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two stupid classes with one method each&lt;/li&gt;
&lt;li&gt;Two PHPUnit tests&lt;/li&gt;
&lt;li&gt;All namespaces set up just like in Symfony2 for library code as well as unit tests&lt;/li&gt;
&lt;li&gt;A demonstration of a namespace type hint&lt;/li&gt;
&lt;li&gt;A PHPUnit configuration file for distribution&lt;/li&gt;
&lt;li&gt;A bootstrap file initialising the &lt;a href=&quot;https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/UniversalClassLoader.php&quot; target=&quot;_blank&quot;&gt;Symfony2 universal class loader&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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 &lt;a href=&quot;https://github.com/caefer/Example-Code-Structure-for-PHP-5.3&quot; target=&quot;_blank&quot;&gt;example code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can see it&amp;#8217;s dead simple. Even the autoloading is nicely tucked up.&lt;/p&gt;
&lt;p&gt;Tell me what you think!&lt;/p&gt;</description>
	<pubDate>Tue, 11 Jan 2011 03:18:08 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: Productivity gain when PHPUnit testing decoupled code</title>
	<guid>http://www.testically.org/?p=1908</guid>
	<link>http://www.testically.org/2011/01/10/productivity-gain-when-phpunit-testing-decouple-code/</link>
	<description>&lt;p&gt;&lt;img class=&quot;alignleft size-medium wp-image-1909&quot; title=&quot;decoupled&quot; src=&quot;http://www.testically.org/wp-content/uploads/2011/01/decoupled-225x300.jpg&quot; alt=&quot;&quot; width=&quot;225&quot; height=&quot;300&quot; /&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Of course I experienced a lot during the past and also did I learn a lot from participating &amp;#8211; actively and passively &amp;#8211; 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.&lt;/p&gt;
&lt;p&gt;And with my small experiment I also learned that following it reduces the time you spend writing unit tests!&lt;span id=&quot;more-1908&quot;&gt;&lt;/span&gt;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!&lt;/p&gt;
&lt;p&gt;For my experiment I followed &lt;em&gt;Separation of Concerns&lt;/em&gt; by using &lt;em&gt;Dependency Injection&lt;/em&gt; 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.&lt;/p&gt;
&lt;p&gt;Instantly my PHPUnit test cases became simple as A B C.&lt;/p&gt;
&lt;p&gt;For symfony plugin code I always needed to bootstrap a lot to make the dependencies available.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Often you needed to bootstrap symfony to get &lt;em&gt;sfContext&lt;/em&gt; available.&lt;/li&gt;
&lt;li&gt;Often you needed to boostrap symfony to make the configuration available needed for some of the classes depending on.&lt;/li&gt;
&lt;li&gt;Often you even needed a database connection fired up as doctrine required that for almost everything.&lt;/li&gt;
&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All because of hard wired dependencies inside symfony and doctrine.&lt;/p&gt;
&lt;p&gt;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 &lt;strong&gt;about two thirds&lt;/strong&gt;! I only needed a third of the time writing PHPUnit code that I needed in coupled sources.&lt;/p&gt;
&lt;p&gt;Even refactoring the unit tests when changing the architecture now couldn&amp;#8217;t be simpler.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s another good reason to look forward to Symfony2 and Doctrine 2.&lt;/p&gt;</description>
	<pubDate>Mon, 10 Jan 2011 05:49:47 +0000</pubDate>
</item>
<item>
	<title>Mike Lively: Pear Channel set up for Phake</title>
	<guid>http://digitalsandwich.com/?p=93</guid>
	<link>http://digitalsandwich.com/archives/93-pear-channel-set-up-for-phake.html</link>
	<description>&lt;p&gt;For those that may not have caught my first post on the subject, &lt;a href=&quot;https://github.com/mlively/Phake&quot;&gt;Phake&lt;/a&gt; is a mock framework that I announced a couple of days ago in &lt;a href=&quot;http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html&quot;&gt;Introducing Phake Mocking Framework&lt;/a&gt;. 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&amp;#8217;t had a reason to do until this week. Well, now there is an official &lt;a href=&quot;http://pear.digitalsandwich.com/&quot;&gt;Digital Sandwich Pear Channel&lt;/a&gt; that is hosting Phake. So if you want to play around with Phake you can install it like this:&lt;/p&gt;
&lt;div class=&quot;codecolorer-container text default&quot;&gt;&lt;div class=&quot;text codecolorer&quot;&gt;pear channel-discover pear.digitalsandwich.com&lt;br /&gt;
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;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 &lt;a href=&quot;https://github.com/mlively/Phake/wiki&quot;&gt;Phake Wiki&lt;/a&gt; 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 &amp;#8216;alpha&amp;#8217; makes you nervous, don&amp;#8217;t worry. It&amp;#8217;ll be okay.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div class=&quot;topsy_widget_data topsy_theme_blue&quot;&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 31 Dec 2010 05:52:28 +0000</pubDate>
</item>
<item>
	<title>Mike Lively: Introducing Phake Mocking Framework</title>
	<guid>http://digitalsandwich.com/?p=84</guid>
	<link>http://digitalsandwich.com/archives/84-introducing-phake-mocking-framework.html</link>
	<description>&lt;p&gt;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 &lt;a href=&quot;http://www.jmock.org/jmock1-getting-started.html&quot;&gt;JMock&lt;/a&gt;. 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 &amp;#8220;mockee&amp;#8217;s&amp;#8221; 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.&lt;/p&gt;
&lt;p&gt;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&amp;#8217;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 &lt;a href=&quot;http://mockito.org/&quot;&gt;Mockito&lt;/a&gt; mocking library for Java. The result of this work is the &lt;a href=&quot;https://github.com/mlively/Phake&quot;&gt;Phake Mocking Framework&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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&amp;#8217;ll just show you how to use it. Phake was designed with PHPUnit in mind, however I don&amp;#8217;t really see any reason why it couldn&amp;#8217;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.&lt;/p&gt;
&lt;p&gt;This document assumes you already have a good understanding of the basics of mocking. If the terms &amp;#8216;Mocking&amp;#8217;, &amp;#8216;Stubbing&amp;#8217;, and &amp;#8216;Test Doubles&amp;#8217; mean nothing to you, I would recommend checking out the following links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.phpunit.de/manual/current/en/test-doubles.html&quot;&gt;PHPUnit on Mock Objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Mock_object&quot;&gt;Wikipedia on Mock Objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.google.com/search?client=ubuntu&amp;#038;channel=fs&amp;#038;q=What+are+Mock+Objects%3F&amp;#038;ie=utf-8&amp;#038;oe=utf-8&quot;&gt;The Universe on Mock Objects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;You can get a copy of &lt;a href=&quot;https://github.com/mlively/Phake&quot;&gt;Phake&lt;/a&gt; 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 &lt;a href=&quot;https://github.com/mlively/Phake/tarball/latest&quot;&gt;Phake&amp;#8217;s latest release tarball&lt;/a&gt;. 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 &amp;#8220;Phake.php&amp;#8221; in any of your tests or in your bootstrap script and you will be off to the races.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;UPDATE!!!&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;div class=&quot;codecolorer-container text default&quot;&gt;&lt;div class=&quot;text codecolorer&quot;&gt;pear channel-discover pear.digitalsandwich.com&lt;br /&gt;
pear install channel://pear.digitalsandwich.com/Phake-1.0.0alpha&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;class&lt;/span&gt; MyClass&lt;br /&gt;
&lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;private&lt;/span&gt; &lt;span&gt;$value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; __construct&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$value&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;$value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; getValue&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;return&lt;/span&gt; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; subtract&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$int&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;return&lt;/span&gt; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;$int&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;Stubbing&lt;/h2&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;require_once&lt;/span&gt; &lt;span&gt;'Phake.php'&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;class&lt;/span&gt; Test &lt;span&gt;extends&lt;/span&gt; PHPUnit_Framework_TestCase&lt;br /&gt;
&lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testStubbingGetValue&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Sets up the mock object.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Analogous to $this-&amp;gt;getMock() in PHPUnit&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Builds the stub for getValue. &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Essentially any call to getValue will return 42&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;thenReturn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also do conditional stubbing based on passed in parameters.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testStubbingGetValue2&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// You can pass parameters into the stubbed method to indicate you&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// only want to stub matching invocations. By default, anything &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// passed in must be loosely matched ('==')&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;thenReturn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// It is important to note that any unstubbed calls will return null.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Since 41 != 42 this call will return null.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertNull&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;41&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;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&amp;#8217;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.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testStubbingGetValue3&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Creates a mock object whose constructor will call &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// MyClass::__construct(42);&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;partMock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;thenReturn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Since 18 != 42, the real method gets call &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;18&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;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 &amp;#8216;Answers&amp;#8217;. Here are a list of them and what they will do when a matching invocation is called:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;thenReturn(mixed $var)&lt;/strong&gt; &amp;#8211; Will return the exact value passed in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;thenCallParent()&lt;/strong&gt; &amp;#8211; Will return the results of calling the mocked parent method.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;thenThrow(Exception $e)&lt;/strong&gt; &amp;#8211; Will throw $e.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;captureReturnTo(&amp;#038;$variable)&lt;/strong&gt; &amp;#8211; 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&amp;#8217;s scope.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The other thing to take note of stubbing is that any PHPUnit constraints are supported.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testStubbingGetValue4&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//Matches any call to subtract() where the passed in value equals 42&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;thenReturn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//Matches any call to subtract() where the passed in value is less &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// than 42. Notice that this is a phpunit constraint&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;when&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;lessThan&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;thenReturn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;29&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;29&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;41&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This gives you the same kind of stubbing flexibility that you have present in PHPUnit.&lt;/p&gt;
&lt;h2&gt;Verification&lt;/h2&gt;
&lt;p&gt;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 &lt;em&gt;after&lt;/em&gt; the calls to your test methods have been made.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify1&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// You can apply stubbings and verifications to the same mock objects&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//Notice, getValue() has already been called&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verify&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You of course have the same matching functionality at your disposal.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify2&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;40&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//Notice the constraint&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verify&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;lessThan&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default, verify only allows a single matching invocation. You can also specify that a specific number of invocations should be allowed.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify3&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;40&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;39&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//The number of times is passed as the second parameter of &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;//Phake::verify()&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verify&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;times&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;lessThan&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use Phake::atLeast($n) and Phake::atMost($n) instead of Phake::times($n).&lt;/p&gt;
&lt;p&gt;You can also specify that you don&amp;#8217;t expect there to be any interactions with a mock.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify4&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// This will ensure that UP TO THIS POINT no methods on $mock have &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// been called&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verifyNoInteraction&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// This would not result in an error, this can be prevented with &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// another method explained below&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I am sure you noticed the comment that Phake::verifyNoInteraction() only verifies that no calls were made up to that point. You can essentially &lt;em&gt;freeze&lt;/em&gt; a mock with another method&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify5&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;getValue&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// This will ensure that no methods on $mock will be called after this &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// point&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verifyNoFurtherInteraction&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There are a few more advanced things you can do with something called argument captors.&lt;/p&gt;
&lt;div class=&quot;codecolorer-container php default&quot;&gt;&lt;div class=&quot;php codecolorer&quot;&gt;&lt;span&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;function&lt;/span&gt; testVerify6&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mock&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'MyClass'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// Phake::capture tells Phake to store the parameter passed to &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;// subtract as the variable $val&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;verify&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$mock&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;subtract&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;Phake&lt;span&gt;::&lt;/span&gt;&lt;span&gt;capture&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;$val&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;$this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;assertEquals&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$val&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;More to Come&lt;/h2&gt;
&lt;p&gt;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&amp;#8217;m not so sure I have implemented &amp;#8216;consecutive calls&amp;#8217;) but I anticipate releasing an RC version no later than the end of January. Also, I am currently using and monitoring the &lt;a href=&quot;https://github.com/mlively/Phake/issues&quot;&gt;issue tracker for Phake&lt;/a&gt; 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.&lt;/p&gt;
&lt;div class=&quot;topsy_widget_data topsy_theme_blue&quot;&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 29 Dec 2010 06:22:13 +0000</pubDate>
</item>
<item>
	<title>Volker Dusch: Setting up Hudson for PHP Projects in 15 minutes</title>
	<guid>http://edorian.posterous.com/setting-up-hudson-for-php-projects</guid>
	<link>http://edorian.posterous.com/setting-up-hudson-for-php-projects</link>
	<description>&lt;p&gt;
	&lt;p&gt;&lt;span&gt;&lt;a href=&quot;http://edorian.posterous.com/setting-up-jenkins-for-php-projects &quot;&gt;Please see here for an updated version of this guide&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Some of the information in this post is out of date so just head over to the newer one.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;---------------------------------------------- Old post ---------------------------------------------------------------------&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;a href=&quot;http://edorian.posterous.com/setting-up-jenkins-for-php-projects &quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Preface:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This is the first draft oft this guide, if you have corrections or comments please let me know.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;If you know that Hudson is and just looking for the &quot;install guide&quot; just skip over the first five paragraphs right to &quot;Installing&quot;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Wait, what is Hudson ?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Hudson is a continuous integration Server !&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Ok, what is continuous integration Server then ?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For starters think of it as a glorified &quot;cron&quot; 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 &quot;works&quot; all the time. Since &quot;works&quot; is a pretty loose definition that also varies greatly among different types of Software these servers tend to be pretty flexible and open. &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot; target=&quot;_blank&quot;&gt;For a longer explanation check Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Why do i want one and what do i to with it ?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So PHP developers the last few years where awesome don't you think ? Many of us stopped &quot;programming&quot; and started &quot;creating software&quot;, our language matured greatly, got a&amp;nbsp; pretty solid object model and more and more &quot;really big&quot; 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 &quot;quality software&quot;. Without going to much into detail for most people that boils down to stuff like automated testing and some sort of quality control.&lt;/p&gt;
&lt;p&gt;I'll just assume you heard of &lt;a href=&quot;http://en.wikipedia.org/wiki/Unit_testing&quot;&gt;Unit Testing&lt;/a&gt; using &lt;a href=&quot;http://www.phpunit.de/manual/current/en/index.html&quot;&gt;PHPUnit&lt;/a&gt; and that you have written some tests or that you have some other way of making sure your software &quot;works&quot;. 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.&lt;/p&gt;
&lt;p&gt;This is where a continuous integration (ci) server jumps in !&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Why Hudson ?&lt;/span&gt;&lt;p&gt;&lt;/p&gt;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.&lt;p&gt;&lt;/p&gt;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 &quot;show demo&quot; link !&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Coming from the Java world Hudson features a variety of quality measurement tools that are integrated into the ci server via plugins. The &quot;big&quot; 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.&lt;p&gt;&lt;/p&gt;&lt;span&gt;Hudson and PHP ?&lt;/span&gt;&lt;p&gt;&lt;/p&gt;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.&lt;br /&gt;Nowadays there is &lt;a href=&quot;https://github.com/sebastianbergmann/php-hudson-template/&quot;&gt;php-hudson-template&lt;/a&gt;, a small Github project started by Sebastian Bergmann that takes all that hassle away too.&lt;p&gt;&lt;/p&gt;&lt;span&gt;Installing: In 15 minutes you will be done !&lt;/span&gt;&lt;br /&gt;If you read the preface: Nice to see you are still here. Lets get going !&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;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.&lt;p&gt;&lt;/p&gt;We will be using:&lt;br /&gt;- Ubuntu 10.10 x86 desktop edition&lt;p&gt;&lt;/p&gt;We are going to install and setup:&lt;/p&gt;
&lt;p&gt;- 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)&lt;br /&gt;- PHPUnit, many php qa tools&lt;br /&gt;- A Hudson project that will make use of all those tools&lt;p&gt;&lt;/p&gt;Starting with the basics:&lt;p&gt;&lt;/p&gt;&lt;code&gt;sudo apt-get update&lt;br /&gt; sudo apt-get install default-jre php5-cli ant daemon git-core&lt;/code&gt; &lt;p&gt;&lt;/p&gt;Your package manager will also install all the other java related programms so we are good to go for Hudson&lt;p&gt;&lt;/p&gt;Ubuntu:&lt;br /&gt; &lt;code&gt;wget -O /tmp/hudson.deb http://hudson-ci.org/latest/debian/hudson.deb&lt;br /&gt; sudo dpkg --install /tmp/hudson.deb&lt;/code&gt;&lt;p&gt;&lt;/p&gt;Any other *nix:&lt;br /&gt; Check the front page of &lt;a href=&quot;http://hudson-ci.org/&quot;&gt;http://hudson-ci.org/&lt;/a&gt; &lt;p&gt;&lt;/p&gt;Or if hudson isn't packaged for you it's very easy too:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wget http://hudson-ci.org/latest/hudson.war&lt;br /&gt; java -jar hudson.war&lt;/code&gt;&lt;p&gt;&lt;/p&gt;Now you can check &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; to see Hudson running.&lt;p&gt;&lt;/p&gt;After that we'll get going with the php parts of your shiny new Hudson.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Following php-hudson-template&lt;/span&gt;&lt;p&gt;&lt;/p&gt;From here on out you can &lt;a href=&quot;https://github.com/sebastianbergmann/php-hudson-template#readme&quot;&gt;just follow the instructions provided by Sebastian on github&lt;/a&gt; but for the sake of &quot;one page to follow and get everything set up and copy/paste as much as possible&quot; i'll rewrite it here.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;From here on out the tutorial is out of date now - Stick to the guide on github&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;-----&lt;/p&gt;
&lt;p&gt;Current changes to hudson, the plugins and that i discovered that the &quot;use publishers from another project&quot; 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.&lt;/p&gt;
&lt;p&gt;I'll try to rewrite the tutorial in the next week and maybe the github guide too.&lt;/p&gt;
&lt;p&gt;-----&lt;/p&gt;
&lt;p&gt;First off we need to install 10 Plugins, thats quite boring to do with the Interface so you could use the Hudson-cli&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wget http://localhost:8080/jnlpJars/hudson-cli.jar&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin checkstyle&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin dry&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin htmlpublisher&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin jdepend&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin pmd&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin template-project&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin violations&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin xunit&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin clover&lt;br /&gt; java -jar hudson-cli.jar -s http://localhost:8080 install-plugin git&lt;br /&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If that doesn't work just go to &lt;a href=&quot;http://localhost:8080/pluginManager/available&quot;&gt;http://localhost:8080/pluginManager/available&lt;/a&gt; and install the plugins by hand:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checkstyle&lt;/li&gt;
&lt;li&gt;DRY&lt;/li&gt;
&lt;li&gt;HTML Publisher&lt;/li&gt;
&lt;li&gt;JDepend&lt;/li&gt;
&lt;li&gt;PMD&lt;/li&gt;
&lt;li&gt;Template Project&lt;/li&gt;
&lt;li&gt;Violations&lt;/li&gt;
&lt;li&gt;xUnit&lt;/li&gt;
&lt;li&gt;Clover&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Restart Hudson while that is running lets install all the PHP Tools:&lt;/p&gt;
&lt;p&gt;First of we need the &quot;pear&quot; installer and the xdebug extension:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install php-pear php5-xdebug&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then register all the relevant pear channels:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo pear channel-discover pear.pdepend.org &lt;br /&gt;sudo pear channel-discover pear.phpmd.org &lt;br /&gt;sudo pear channel-discover pear.phpunit.de&lt;br /&gt;sudo pear channel-discover components.ez.no&lt;br /&gt;sudo pear channel-discover pear.symfony-project.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And install all the tools:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo pear install pdepend/PHP_Depend-beta&lt;br /&gt;sudo pear install phpmd/PHP_PMD-alpha&lt;br /&gt;sudo pear install phpunit/phpcpd&lt;br /&gt;sudo pear install PHPDocumentor&lt;br /&gt;sudo pear install PHP_CodeSniffer&lt;br /&gt;sudo pear install --alldeps phpunit/PHP_CodeBrowser-alpha&lt;br /&gt;sudo pear install --alldeps phpunit/PHPUnit&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Setting up a demo project&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd ~&lt;br /&gt;mkdir mydemo&lt;br /&gt;cd mydemo&lt;br /&gt;git init&lt;br /&gt;mkdir src tests&lt;br /&gt;touch build.xml phpunit.xml.dist src/MyClass.php tests/MyClassTest.php&lt;br /&gt;echo &quot;build&quot; &amp;gt; .gitignore&lt;br /&gt;git add src tests .gitignore&amp;nbsp;&lt;br /&gt;git commit -m&quot;Inital dump&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now let's fill our demo project with some life !&lt;/p&gt;
&lt;p&gt;Paste the following in your phpunit.xml.dist&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;phpunit backupGlobals=&quot;false&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; backupStaticAttributes=&quot;false&quot;&lt;br /&gt;&amp;nbsp;        &amp;nbsp;syntaxCheck=&quot;false&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;testsuites&amp;gt;&lt;br /&gt;&amp;nbsp;   &amp;nbsp;&amp;lt;testsuite name=&quot;php-demo&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;     &amp;nbsp; &amp;nbsp;&amp;lt;directory suffix=&quot;Test.php&quot;&amp;gt;tests&amp;lt;/directory&amp;gt;&lt;br /&gt;&amp;nbsp;   &amp;nbsp;&amp;lt;/testsuite&amp;gt;&lt;br /&gt; &amp;lt;/testsuites&amp;gt;&lt;br /&gt;&amp;lt;logging&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;coverage-html&quot; target=&quot;build/coverage&quot; title=&quot;php-demo&quot;&lt;br /&gt;&amp;nbsp;     &amp;nbsp;charset=&quot;UTF-8&quot; yui=&quot;true&quot; highlight=&quot;true&quot;&lt;br /&gt;&amp;nbsp;     &amp;nbsp;lowUpperBound=&quot;35&quot; highLowerBound=&quot;70&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;coverage-clover&quot; target=&quot;build/logs/clover.xml&quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;log type=&quot;junit&quot; target=&quot;build/logs/junit.xml&quot; logIncompleteSkipped=&quot;false&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/logging&amp;gt;&lt;br /&gt;&amp;lt;/phpunit&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Some sample code for &quot;src/MyClass.php&quot;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class MyClass {&lt;br /&gt;&amp;nbsp; &amp;nbsp; public function demo($a) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if($a == 1) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And a sample test for &quot;tests/MyClassTest.php&quot;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;require_once(&quot;src/MyClass.php&quot;);&lt;br /&gt;&lt;br /&gt;class MyClassTest extends PHPUnit_Framework_TestCase {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public function testDemo() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $x = new MyClass();&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;assertEquals(1, $x-&amp;gt;demo(1));&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now paste that behemoth into your build.xml:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;project name=&quot;php-demo-project&quot; default=&quot;build&quot; basedir=&quot;.&quot;&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;clean&quot;&amp;gt;&lt;br /&gt; &amp;lt;!-- Clean up --&amp;gt;&lt;br /&gt; &amp;lt;delete dir=&quot;build&quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Create build directories --&amp;gt;&lt;br /&gt; &amp;lt;mkdir dir=&quot;${basedir}/build/api&quot;/&amp;gt;&lt;br /&gt; &amp;lt;mkdir dir=&quot;${basedir}/build/code-browser&quot;/&amp;gt;&lt;br /&gt; &amp;lt;mkdir dir=&quot;${basedir}/build/coverage&quot;/&amp;gt;&lt;br /&gt; &amp;lt;mkdir dir=&quot;${basedir}/build/logs&quot;/&amp;gt;&lt;br /&gt; &amp;lt;mkdir dir=&quot;${basedir}/build/pdepend&quot;/&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Run unit tests and generate junit.xml and clover.xml &lt;br /&gt;&amp;nbsp;(This is done in the phpunit.xml.dist,&lt;br /&gt; you could also write the switches here)&lt;br /&gt; --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;phpunit&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;exec executable=&quot;phpunit&quot; failonerror=&quot;true&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Run pdepend, phpmd, phpcpd, and phpcs in parallel --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;parallelTasks&quot;&amp;gt;&lt;br /&gt; &amp;lt;parallel&amp;gt;&lt;br /&gt; &amp;lt;antcall target=&quot;pdepend&quot;/&amp;gt;&lt;br /&gt; &amp;lt;antcall target=&quot;phpmd&quot;/&amp;gt;&lt;br /&gt; &amp;lt;antcall target=&quot;phpcpd&quot;/&amp;gt;&lt;br /&gt; &amp;lt;antcall target=&quot;phpcs&quot;/&amp;gt;&lt;br /&gt; &amp;lt;antcall target=&quot;phpdoc&quot;/&amp;gt;&lt;br /&gt; &amp;lt;/parallel&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Generate jdepend.xml and software metrics charts --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;pdepend&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;pdepend&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;--jdepend-xml=${basedir}/build/logs/jdepend.xml src&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Generate pmd.xml --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;phpmd&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;phpmd&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;src xml codesize,unusedcode&lt;br /&gt; --reportfile ${basedir}/build/logs/pmd.xml&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Generate pmd-cpd.xml --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;phpcpd&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;phpcpd&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;--log-pmd ${basedir}/build/logs/pmd-cpd.xml src&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Generate checkstyle.xml --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;phpcs&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;phpcs&quot; output=&quot;/dev/null&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;--report=checkstyle&lt;br /&gt; --report-file=${basedir}/build/logs/checkstyle.xml&lt;br /&gt; --standard=Sebastian&lt;br /&gt; src&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Generate API documentation --&amp;gt;&lt;br /&gt; &amp;lt;target name=&quot;phpdoc&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;phpdoc&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;-d src -t build/api&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name=&quot;phpcb&quot;&amp;gt;&lt;br /&gt; &amp;lt;exec executable=&quot;phpcb&quot;&amp;gt;&lt;br /&gt; &amp;lt;arg line=&quot;--log    ${basedir}/build/logs&lt;br /&gt; --source ${basedir}/src&lt;br /&gt; --output ${basedir}/build/code-browser&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/exec&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name=&quot;build&quot; depends=&quot;clean,phpunit,parallelTasks,phpcb&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nearly done !&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd ~/mydemo&lt;br /&gt;git commit -am&quot;Lets do this&quot;&lt;br /&gt;cd /var/lib/hudson/jobs&lt;br /&gt; git clone git://github.com/sebastianbergmann/php-hudson-template.git&lt;br /&gt; sudo /etc/init.d/hudson stop&lt;br /&gt; sudo /etc/init.d/hudson start&lt;br /&gt; &lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Now go to &lt;a href=&quot;http://localhost:8080/&quot;&gt;http://localhost:8080/&lt;/a&gt; again&lt;/li&gt;
&lt;li&gt;Click &quot;New Job&quot;&lt;/li&gt;
&lt;li&gt;Build a free-style software project &quot;php-demo&quot;&lt;/li&gt;
&lt;li&gt;Select &quot;git&quot; as the &quot;Source Code Management&quot;&lt;/li&gt;
&lt;li&gt;User /home/$USERNAME/mydemo as the URL&lt;/li&gt;
&lt;li&gt;Under Build: click &quot;Add build Step -&amp;gt; Invoke Ant&quot;&lt;/li&gt;
&lt;li&gt;Under &quot;Post-build Actions&quot;: click &quot;Use publishers from another project&quot; and select php-hudson-template as the &quot;Template Project&quot;&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;li&gt;Click &quot;Build now&quot;&lt;/li&gt;
&lt;li&gt;Enjoy your first build ! Click it and look at all the pretty output :)&lt;/li&gt;
&lt;li&gt;If you want to build every time you commit that option is under &quot;configure, build triggers, poll scm&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;Done !&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;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 !&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thanks for reading&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://edorian.posterous.com/setting-up-hudson-for-php-projects&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://edorian.posterous.com/setting-up-hudson-for-php-projects#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Sun, 19 Dec 2010 13:15:00 +0000</pubDate>
</item>
<item>
	<title>Qafoo GmbH: Testing file uploads with PHP</title>
	<guid>http://qafoo.com/blog/013_testing_file_uploads_with_php.html</guid>
	<link>http://qafoo.com/blog/013_testing_file_uploads_with_php.html</link>
	<description>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.</description>
	<pubDate>Thu, 09 Dec 2010 08:37:11 +0000</pubDate>
</item>
<item>
	<title>Stefan Priebsch: Der Weg zur Tanzfl&#228;che</title>
	<guid>http://priebsch.de/blog/der-weg-zur-tanzflaeche</guid>
	<link>http://priebsch.de/blog/der-weg-zur-tanzflaeche</link>
	<description>Es wurde schon viel dar&#252;ber spekuliert, wie gro&#223; der Anteil der PHP-Nutzer ist,
die von HipHop profitieren werden. Die Zahlen bewegen sich im Wesentlichen 
zwischen 0% und 100%, daher versuche ich mich gar nicht erst an einer eigenen
Sch&#228;tzung, sondern will stattdessen &#252;ber die Voraussetzungen schreiben, die
ein Team beziehungsweise eine Firma erf&#252;llen muss, um von HipHop profitieren zu
k&#246;nnen.</description>
	<pubDate>Sun, 05 Dec 2010 19:34:38 +0000</pubDate>
	<author>stefan@priebsch.de (Stefan Priebsch)</author>
</item>
<item>
	<title>Stefan Priebsch: Der erste deutsche PHP Summit</title>
	<guid>http://priebsch.de/blog/php-summit-in-duesseldorf</guid>
	<link>http://priebsch.de/blog/php-summit-in-duesseldorf</link>
	<description>Der erste deutsche PHP Summit - powered by thePHP.cc - ist eine neue und
einzigartige Veranstaltung, die alle wichtigen Themen rund um die
Software-Entwicklung mit PHP in kompakter Form vermittelt.</description>
	<pubDate>Sun, 05 Dec 2010 19:34:38 +0000</pubDate>
	<author>stefan@priebsch.de (Stefan Priebsch)</author>
</item>
<item>
	<title>Sebastian Bergmann: PHPUnit 3.5 Upgrading Woes</title>
	<guid>http://sebastian-bergmann.de/archives/899-guid.html</guid>
	<link>http://sebastian-bergmann.de/archives/899-PHPUnit-3.5-Upgrading-Woes.html</link>
	<description>&lt;p&gt;The issues related to upgrading from a previous version to PHPUnit 3.5 that I mentioned in the &lt;a href=&quot;http://sebastian-bergmann.de/archives/897-PHPUnit-3.5.html&quot;&gt;release announcement&lt;/a&gt; are more serious than I initially thought. Only today did I find the time to really investigate the root cause.&lt;/p&gt;
&lt;p&gt;Here is the situation before the upgrade:&lt;/p&gt;
&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear list&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
Installed packages, channel pear.php.net:
=========================================
Package          Version State
Archive_Tar      1.3.7   stable
Console_Getopt   1.2.3   stable
PEAR             1.9.1   stable
Structures_Graph 1.0.3   stable
XML_Util         1.2.1   stable&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear list -c phpunit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
Installed packages, channel pear.phpunit.de:
============================================
Package Version State
PHPUnit 3.4.15  stable&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;As we can see, we have the latest version of PEAR (1.9.1) installed as well as PHPUnit 3.4.15.&lt;/p&gt;
&lt;p&gt;Lets have a look at the installed files:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# tree /usr/share/php/PHPUnit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
/usr/share/php/PHPUnit
&amp;#9500;&amp;#9472;&amp;#9472; Extensions
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSetIsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TableIsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSet
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CompositeDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CsvDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSetFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IPersistable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ISpec.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Persistors
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Abstract.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Xml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Yaml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; QueryDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; QueryTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementTableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Specs
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Csv.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DbQuery.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DbTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Xml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Yaml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableMetaDataFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; XmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; YamlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DB
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultDatabaseConnection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FilteredDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseConnection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MetaData
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InformationSchema.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MySQL.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Oci.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PgSQL.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Sqlite.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultSetTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Table.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseListConsumer.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Operation
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Composite.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DeleteAll.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Delete.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseOperation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Insert.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Null.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Replace.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; RowBased.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Truncate.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Update.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; UI
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Command.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Context.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMedium.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMediumPrinter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IModeFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMode.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; InvalidModeException.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Mediums
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; ModeFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9492;&amp;#9472;&amp;#9472; Modes
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9500;&amp;#9472;&amp;#9472; ExportDataSet
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Arguments.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9492;&amp;#9472;&amp;#9472; ExportDataSet.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GroupTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; OutputTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PerformanceTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Logger.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; RepeatedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; append.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Driver.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; phpunit_coverage.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; prepend.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Story
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Given.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario_header.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenarios.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; step.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scenario.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Step.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Then.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; When.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestDecorator.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TicketListener
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Trac.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TicketListener.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AssertionFailedError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Assert.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Array.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Object.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scalar.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; String.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Type.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; And.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ArrayHasKey.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Attribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasStaticAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FileExists.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GreaterThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsAnything.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsFalse.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsIdentical.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsInstanceOf.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsNull.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsTrue.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsType.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; LessThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Not.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ObjectHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Or.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PCREMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringEndsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringStartsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContainsOnly.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Xor.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Notice.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExpectationFailedException.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockObject
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Builder
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Identity.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvocationMocker.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Match.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MethodNameMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Namespace.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ParametersMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Stub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Generator
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_class.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_clone.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; unmocked_clone.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; wsdl_class.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; wsdl_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Generator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvocationMocker.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invokable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Matcher
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AnyInvokedCount.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AnyParameters.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedAtIndex.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedAtLeastOnce.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedCount.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedRecorder.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MethodName.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Parameters.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; StatelessInvocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Matcher.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockObject.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Stub
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ConsecutiveCalls.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MatcherCollection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReturnArgument.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReturnCallback.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Return.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Stub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Verifiable.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Process
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestCaseMethod.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SelfDescribing.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestSuiteError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestListener.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Test.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestResult.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; DataProvider.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework.php
&amp;#9500;&amp;#9472;&amp;#9472; Runner
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; BaseTestRunner.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncludePathTestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StandardTestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Version.php
&amp;#9500;&amp;#9472;&amp;#9472; TextUI
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Command.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestRunner.php
&amp;#9492;&amp;#9472;&amp;#9472; Util
    &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9500;&amp;#9472;&amp;#9472; CodeCoverage.php
    &amp;#9500;&amp;#9472;&amp;#9472; Configuration.php
    &amp;#9500;&amp;#9472;&amp;#9472; Diff.php
    &amp;#9500;&amp;#9472;&amp;#9472; ErrorHandler.php
    &amp;#9500;&amp;#9472;&amp;#9472; Fileloader.php
    &amp;#9500;&amp;#9472;&amp;#9472; File.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filesystem.php
    &amp;#9500;&amp;#9472;&amp;#9472; FilterIterator.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Getopt.php
    &amp;#9500;&amp;#9472;&amp;#9472; GlobalState.php
    &amp;#9500;&amp;#9472;&amp;#9472; InvalidArgumentHelper.php
    &amp;#9500;&amp;#9472;&amp;#9472; Log
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CodeCoverage
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; XML
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Clover.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9492;&amp;#9472;&amp;#9472; Source.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CPD.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MySQL.sql
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; SQLite3.sql
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GraphViz.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JSON.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JUnit.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Metrics.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PEAR.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PMD
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Rule
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DepthOfInheritanceTree.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; EfferentCoupling.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExcessiveClassLength.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExcessivePublicCount.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TooManyFields.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; File.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Function
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CodeCoverage.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CRAP.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CyclomaticComplexity.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExcessiveMethodLength.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExcessiveParameterList.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; NPathComplexity.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Function.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Project
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; CRAP.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Project.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Rule.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PMD.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TAP.php
    &amp;#9500;&amp;#9472;&amp;#9472; Metrics
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; File.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Function.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Project.php
    &amp;#9500;&amp;#9472;&amp;#9472; Metrics.php
    &amp;#9500;&amp;#9472;&amp;#9472; PDO.php
    &amp;#9500;&amp;#9472;&amp;#9472; PHP.php
    &amp;#9500;&amp;#9472;&amp;#9472; Printer.php
    &amp;#9500;&amp;#9472;&amp;#9472; Report
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Node
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Directory.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; File.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Node.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Template
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; butter.png
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; chameleon.png
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; close12_1.gif
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; container.css
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; container-min.js
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; directory.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; directory_item.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; file.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; file_item.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; file_no_yui.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; glass.png
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; method_item.html.dist
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; scarlet_red.png
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; snow.png
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; style.css
    &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; yahoo-dom-event.js
    &amp;#9474;&#160;&#160;     &amp;#9492;&amp;#9472;&amp;#9472; yui_item.js
    &amp;#9500;&amp;#9472;&amp;#9472; Report.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Method.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestClass.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBoolStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBool.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodExceptionStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodException.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton.php
    &amp;#9500;&amp;#9472;&amp;#9472; Template.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestDox
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; NamePrettifier.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; ResultPrinter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteIterator.php
    &amp;#9500;&amp;#9472;&amp;#9472; Timer.php
    &amp;#9500;&amp;#9472;&amp;#9472; Type.php
    &amp;#9492;&amp;#9472;&amp;#9472; XML.php

50 directories, 312 files&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;Pay particular attention to files such as &lt;code&gt;MockObject/Generator.php&lt;/code&gt; that were part of the &lt;code&gt;PHPUnit&lt;/code&gt; package in version 3.4, but have been moved to a separate package, &lt;code&gt;PHPUnit_MockObject&lt;/code&gt; in this case, for version 3.5.&lt;/p&gt;
&lt;p&gt;Now we perform the upgrade to PHPUnit 3.5&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear upgrade phpunit/PHPUnit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
phpunit/PHPUnit can optionally use PHP extension &quot;dbus&quot;
phpunit/PHP_CodeCoverage can optionally use PHP extension &quot;xdebug&quot; (version &gt;= 2.0.5)
downloading PHPUnit-3.5.2.tgz ...
Starting to download PHPUnit-3.5.2.tgz (114,862 bytes)
.........................done: 114,862 bytes
downloading DbUnit-1.0.0.tgz ...
Starting to download DbUnit-1.0.0.tgz (38,183 bytes)
...done: 38,183 bytes
downloading File_Iterator-1.2.3.tgz ...
Starting to download File_Iterator-1.2.3.tgz (3,406 bytes)
...done: 3,406 bytes
downloading Text_Template-1.0.0.tgz ...
Starting to download Text_Template-1.0.0.tgz (2,493 bytes)
...done: 2,493 bytes
downloading PHP_CodeCoverage-1.0.0.tgz ...
Starting to download PHP_CodeCoverage-1.0.0.tgz (109,022 bytes)
...done: 109,022 bytes
downloading PHP_Timer-1.0.0.tgz ...
Starting to download PHP_Timer-1.0.0.tgz (2,536 bytes)
...done: 2,536 bytes
downloading PHPUnit_MockObject-1.0.0.tgz ...
Starting to download PHPUnit_MockObject-1.0.0.tgz (17,287 bytes)
...done: 17,287 bytes
downloading PHPUnit_Selenium-1.0.0.tgz ...
Starting to download PHPUnit_Selenium-1.0.0.tgz (15,252 bytes)
...done: 15,252 bytes
downloading YAML-1.0.3.tgz ...
Starting to download YAML-1.0.3.tgz (9,794 bytes)
...done: 9,794 bytes
downloading ConsoleTools-1.6.1.tgz ...
Starting to download ConsoleTools-1.6.1.tgz (869,994 bytes)
...done: 869,994 bytes
downloading PHP_TokenStream-1.0.0.tgz ...
Starting to download PHP_TokenStream-1.0.0.tgz (7,240 bytes)
...done: 7,240 bytes
downloading Base-1.8.tgz ...
Starting to download Base-1.8.tgz (236,357 bytes)
...done: 236,357 bytes
upgrade ok: channel://pear.phpunit.de/File_Iterator-1.2.3
upgrade ok: channel://pear.phpunit.de/Text_Template-1.0.0
upgrade ok: channel://pear.phpunit.de/PHP_Timer-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit_Selenium-1.0.0
upgrade ok: channel://pear.symfony-project.com/YAML-1.0.3
upgrade ok: channel://components.ez.no/Base-1.8
upgrade ok: channel://pear.phpunit.de/DbUnit-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit_MockObject-1.0.0
upgrade ok: channel://components.ez.no/ConsoleTools-1.6.1
upgrade ok: channel://pear.phpunit.de/PHP_TokenStream-1.0.0
upgrade ok: channel://pear.phpunit.de/PHP_CodeCoverage-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit-3.5.2&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;The new dependencies of the &lt;code&gt;PHPUnit&lt;/code&gt; package, such as &lt;code&gt;PHPUnit_MockObject&lt;/code&gt; for instance, are installed first. The &lt;code&gt;PHPUnit&lt;/code&gt; package itself is installed last. And herein lies the problem: &lt;code&gt;PHPUnit_MockObject&lt;/code&gt; installs the new version of &lt;code&gt;MockObject/Generator.php&lt;/code&gt; before the &lt;code&gt;PHPUnit&lt;/code&gt; package is upgraded. This upgrade deletes the &lt;code&gt;MockObject/Generator.php&lt;/code&gt; file as it previously belonged to the &lt;code&gt;PHPUnit&lt;/code&gt; package:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# tree /usr/share/php/PHPUnit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
/usr/share/php/PHPUnit
&amp;#9500;&amp;#9472;&amp;#9472; Autoload.php
&amp;#9500;&amp;#9472;&amp;#9472; Extensions
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; DataSet
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; MysqlXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9492;&amp;#9472;&amp;#9472; Persistors
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9492;&amp;#9472;&amp;#9472; MysqlXml.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GroupTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; OutputTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Logger.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; RepeatedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Story
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Given.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario_header.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenarios.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; step.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scenario.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Step.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Then.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; When.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestDecorator.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TicketListener
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GitHub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; GoogleCode.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TicketListener.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Assert
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Functions.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AssertionFailedError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Assert.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Array.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Object.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scalar.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; String.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Type.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; And.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ArrayHasKey.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Attribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasStaticAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FileExists.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GreaterThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsAnything.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsEmpty.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsFalse.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsIdentical.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsInstanceOf.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsNull.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsTrue.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsType.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; LessThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Not.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ObjectHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Or.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PCREMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringEndsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringMatches.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringStartsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContainsOnly.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Xor.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Notice.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExpectationFailedException.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockObject
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Generator
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_object_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; mocked_static_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Object.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Static.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; MockBuilder.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Process
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestCaseMethod.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SelfDescribing.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestSuiteError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SyntheticError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestListener.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Test.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestResult.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; DataProvider.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework.php
&amp;#9500;&amp;#9472;&amp;#9472; Runner
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; BaseTestRunner.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncludePathTestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StandardTestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Version.php
&amp;#9500;&amp;#9472;&amp;#9472; TextUI
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Command.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestRunner.php
&amp;#9492;&amp;#9472;&amp;#9472; Util
    &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9500;&amp;#9472;&amp;#9472; Configuration.php
    &amp;#9500;&amp;#9472;&amp;#9472; Diff.php
    &amp;#9500;&amp;#9472;&amp;#9472; ErrorHandler.php
    &amp;#9500;&amp;#9472;&amp;#9472; Fileloader.php
    &amp;#9500;&amp;#9472;&amp;#9472; File.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filesystem.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Getopt.php
    &amp;#9500;&amp;#9472;&amp;#9472; GlobalState.php
    &amp;#9500;&amp;#9472;&amp;#9472; InvalidArgumentHelper.php
    &amp;#9500;&amp;#9472;&amp;#9472; Log
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DBUS.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JSON.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JUnit.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TAP.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; XHProf.php
    &amp;#9500;&amp;#9472;&amp;#9472; PHP.php
    &amp;#9500;&amp;#9472;&amp;#9472; Printer.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Method.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestClass.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBoolStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBool.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodExceptionStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodException.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestDox
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; NamePrettifier.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; ResultPrinter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteIterator.php
    &amp;#9500;&amp;#9472;&amp;#9472; Type.php
    &amp;#9492;&amp;#9472;&amp;#9472; XML.php

27 directories, 139 files&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;&lt;code&gt;MockObject/Generator.php&lt;/code&gt; is missing (see above) but PEAR claims it is their as part of &lt;code&gt;PHPUnit_MockObject&lt;/code&gt;:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear list-files phpunit/PHPUnit_MockObject&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
Installed Files For phpunit/PHPUnit_MockObject
==============================================
Type Install Path
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Identity.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Match.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Namespace.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Stub.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_object_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_static_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation/Object.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation/Static.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/Invocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/MethodName.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/Parameters.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/Exception.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/Return.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator.php
php  /usr/share/php/PHPUnit/Framework/MockObject/InvocationMocker.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invokable.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher.php
php  /usr/share/php/PHPUnit/Framework/MockObject/MockBuilder.php
php  /usr/share/php/PHPUnit/Framework/MockObject/MockObject.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Verifiable.php&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;The only way to fix this messed up situation is to force-install the new subpackages:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear install -f phpunit/DbUnit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
downloading DbUnit-1.0.0.tgz ...
Starting to download DbUnit-1.0.0.tgz (38,183 bytes)
...done: 38,183 bytes
upgrade ok: channel://pear.phpunit.de/DbUnit-1.0.0&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear install -f phpunit/PHPUnit_MockObject&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
downloading PHPUnit_MockObject-1.0.0.tgz ...
Starting to download PHPUnit_MockObject-1.0.0.tgz (17,287 bytes)
...done: 17,287 bytes
upgrade ok: channel://pear.phpunit.de/PHPUnit_MockObject-1.0.0&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# pear install -f phpunit/PHPUnit_Selenium&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
downloading PHPUnit_Selenium-1.0.0.tgz ...
Starting to download PHPUnit_Selenium-1.0.0.tgz (15,252 bytes)
...done: 15,252 bytes
upgrade ok: channel://pear.phpunit.de/PHPUnit_Selenium-1.0.0&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;Now we have all the files:&lt;/p&gt;

&lt;dl&gt;&lt;dd&gt;&lt;strong&gt;&lt;pre&gt;root@ubuntu:~# tree /usr/share/php/PHPUnit&lt;/pre&gt;&lt;/strong&gt;&lt;pre&gt;
/usr/share/php/PHPUnit
&amp;#9500;&amp;#9472;&amp;#9472; Autoload.php
&amp;#9500;&amp;#9472;&amp;#9472; Extensions
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Database
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSetIsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TableIsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSet
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AbstractXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CompositeDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; CsvDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSetFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IPersistable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ISpec.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MysqlXmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Persistors
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Abstract.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MysqlXml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Xml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Yaml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; QueryDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; QueryTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementTableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReplacementTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Specs
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Csv.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DbQuery.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DbTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FlatXml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Xml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Yaml.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableMetaDataFilter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; XmlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; YamlDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DB
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultDatabaseConnection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FilteredDataSet.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseConnection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MetaData
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InformationSchema.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MySQL.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Oci.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PgSQL.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Sqlite.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultSetTable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableIterator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TableMetaData.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Table.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DefaultTester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseListConsumer.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ITester.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Operation
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Composite.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DeleteAll.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Delete.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Factory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IDatabaseOperation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Insert.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Null.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Replace.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; RowBased.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Truncate.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Update.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; UI
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Command.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Context.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMedium.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMediumPrinter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IModeFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; IMode.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; InvalidModeException.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; Mediums
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9500;&amp;#9472;&amp;#9472; ModeFactory.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;     &amp;#9492;&amp;#9472;&amp;#9472; Modes
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9500;&amp;#9472;&amp;#9472; ExportDataSet
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Arguments.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160;         &amp;#9492;&amp;#9472;&amp;#9472; ExportDataSet.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GroupTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; OutputTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Logger.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PhptTestSuite.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; RepeatedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; append.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Driver.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; phpunit_coverage.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; prepend.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Story
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Given.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario_header.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenario.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; scenarios.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; step.html.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scenario.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SeleniumTestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Step.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Then.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; When.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestDecorator.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TicketListener
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GitHub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; GoogleCode.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TicketListener.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Assert
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Functions.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AssertionFailedError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Assert.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Array.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Object.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Scalar.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; String.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Type.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ComparisonFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; And.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ArrayHasKey.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Attribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ClassHasStaticAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; FileExists.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; GreaterThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsAnything.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsEmpty.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsEqual.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsFalse.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsIdentical.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsInstanceOf.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsNull.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsTrue.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IsType.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; LessThan.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Not.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ObjectHasAttribute.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Or.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; PCREMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringEndsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringMatches.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StringStartsWith.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContainsOnly.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TraversableContains.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Xor.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Constraint.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Notice.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Error.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ExpectationFailedException.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockObject
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Builder
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Identity.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvocationMocker.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Match.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MethodNameMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Namespace.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ParametersMatch.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Stub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Generator
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_class.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_clone.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_object_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; mocked_static_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; unmocked_clone.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; wsdl_class.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; wsdl_method.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Generator.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Object.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Static.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvocationMocker.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invokable.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Matcher
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AnyInvokedCount.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; AnyParameters.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Invocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedAtIndex.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedAtLeastOnce.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedCount.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; InvokedRecorder.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MethodName.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Parameters.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; StatelessInvocation.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Matcher.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockBuilder.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MockObject.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Stub
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ConsecutiveCalls.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Exception.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; MatcherCollection.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReturnArgument.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ReturnCallback.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Return.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Stub.php
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Verifiable.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Process
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestCaseMethod.tpl.dist
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SelfDescribing.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTest.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SkippedTestSuiteError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; SyntheticError.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCase.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestFailure.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestListener.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Test.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestResult.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite
&amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; DataProvider.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuite.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Warning.php
&amp;#9500;&amp;#9472;&amp;#9472; Framework.php
&amp;#9500;&amp;#9472;&amp;#9472; Runner
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; BaseTestRunner.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncludePathTestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; StandardTestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestCollector.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteLoader.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Version.php
&amp;#9500;&amp;#9472;&amp;#9472; TextUI
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Command.php
&amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter.php
&amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestRunner.php
&amp;#9492;&amp;#9472;&amp;#9472; Util
    &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9500;&amp;#9472;&amp;#9472; Configuration.php
    &amp;#9500;&amp;#9472;&amp;#9472; Diff.php
    &amp;#9500;&amp;#9472;&amp;#9472; ErrorHandler.php
    &amp;#9500;&amp;#9472;&amp;#9472; Fileloader.php
    &amp;#9500;&amp;#9472;&amp;#9472; File.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filesystem.php
    &amp;#9500;&amp;#9472;&amp;#9472; Filter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Getopt.php
    &amp;#9500;&amp;#9472;&amp;#9472; GlobalState.php
    &amp;#9500;&amp;#9472;&amp;#9472; InvalidArgumentHelper.php
    &amp;#9500;&amp;#9472;&amp;#9472; Log
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; DBUS.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JSON.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; JUnit.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TAP.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; XHProf.php
    &amp;#9500;&amp;#9472;&amp;#9472; PHP.php
    &amp;#9500;&amp;#9472;&amp;#9472; Printer.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Template
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Class.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; IncompleteTestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; Method.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestClass.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBoolStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodBool.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodExceptionStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodException.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; TestMethodStatic.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; TestMethod.tpl.dist
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; Skeleton.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestDox
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; NamePrettifier.php
    &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; ResultPrinter
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9500;&amp;#9472;&amp;#9472; HTML.php
    &amp;#9474;&#160;&#160; &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; Text.php
    &amp;#9474;&#160;&#160; &amp;#9492;&amp;#9472;&amp;#9472; ResultPrinter.php
    &amp;#9500;&amp;#9472;&amp;#9472; Test.php
    &amp;#9500;&amp;#9472;&amp;#9472; TestSuiteIterator.php
    &amp;#9500;&amp;#9472;&amp;#9472; Type.php
    &amp;#9492;&amp;#9472;&amp;#9472; XML.php

40 directories, 266 files&lt;/pre&gt;&lt;/dd&gt;&lt;/dl&gt;

&lt;p&gt;I hope that this &lt;a href=&quot;http://pear.php.net/bugs/bug.php?id=17986&quot;&gt;bug in the PEAR Installer&lt;/a&gt; will be fixed soon.&lt;/p&gt;</description>
	<pubDate>Fri, 22 Oct 2010 08:30:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>
<item>
	<title>Qafoo GmbH: IPC 2010 recap</title>
	<guid>http://qafoo.com/blog/009_international_php_conference_2010_recap.html</guid>
	<link>http://qafoo.com/blog/009_international_php_conference_2010_recap.html</link>
	<description>The &lt;a href=&quot;http://phpconference.com&quot;&gt;International PHP Conference 2010&lt;/a&gt;, 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 &lt;a href=&quot;http://joind.in/event/ipc2010&quot;&gt;feedback via joind.in&lt;/a&gt;!</description>
	<pubDate>Fri, 15 Oct 2010 10:28:48 +0000</pubDate>
</item>
<item>
	<title>Christian Schaefer: symfony day 2010 &#8211; a review</title>
	<guid>http://www.testically.org/?p=1560</guid>
	<link>http://www.testically.org/2010/10/11/symfony-day-2010%e2%80%93a-review/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.testically.org/wp-content/uploads/2010/10/sfday2010pwned.jpg&quot;&gt;&lt;img class=&quot;alignleft size-medium wp-image-1562&quot; title=&quot;symfony-day-2010-pwned&quot; src=&quot;http://www.testically.org/wp-content/uploads/2010/10/sfday2010pwned-300x234.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;234&quot; /&gt;&lt;/a&gt;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.&#160;But I think I wasn&amp;#8217;t the only one enjoying hi time there.&lt;/p&gt;
&lt;p&gt;For those unfortunate of you who couldn&amp;#8217;t attend to it here&amp;#8217;s a wrap-up.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-1560&quot;&gt;&lt;/span&gt;First of all I have to thank Interlutions and in person Dennis Benkert and Stefan Jung for organising this event! &#160;From my perspective it was perfect throughout.&lt;/p&gt;
&lt;p&gt;Now to the talks.&lt;/p&gt;
&lt;h2&gt;Doctrine MongoDB Object Document Mapper&#160;&lt;span&gt;&lt;em&gt;Jonathan Wage&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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&amp;#8217;t developed a feeling for when to choose the one over the other&amp;#8230;? However if I would choose MongoDB I would surely use Doctrine 2 ODM for it.&lt;/p&gt;
&lt;div id=&quot;__ss_5393200&quot;&gt;&lt;strong&gt;&lt;a title=&quot;Symfony Day 2010 Doctrine MongoDB ODM&quot; href=&quot;http://www.slideshare.net/jwage/symfony-day-2010-doctrine-mongodb-odm&quot;&gt;Symfony Day 2010 Doctrine MongoDB ODM&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/jwage&quot;&gt;Jonathan Wage&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;PHP, symfony and software lifecycles&#160;&lt;span&gt;&lt;em&gt;Pierre Joye&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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&#160;works on windows). We the PHP community owe them a lot.&lt;/p&gt;
&lt;h2&gt;Unit testing symfony plugins with PHPUnit&#160;&lt;span&gt;&lt;em&gt;Christian Schaefer&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;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&amp;#8217;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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div id=&quot;__ss_5401851&quot;&gt;&lt;strong&gt;&lt;a title=&quot;Unit testing symfony plugins with php unit&quot; href=&quot;http://www.slideshare.net/caefer/unit-testing-symfony-plugins-with-php-unit-5401851&quot;&gt;Unit testing symfony plugins with php unit&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/caefer&quot;&gt;caefer&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Advanced symfony Techniques&#160;&lt;span&gt;&lt;em&gt;Kris Wallsmith&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Go beyond the documentation and explore some of what&amp;#8217;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&amp;#8217;re comfortable in symfony and wondering what&amp;#8217;s next, this session is for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div id=&quot;__ss_5396592&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.slideshare.net/kriswallsmith/advanced-symfony-techniques&quot; title=&quot;Advanced symfony Techniques&quot;&gt;Advanced symfony Techniques&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/kriswallsmith&quot;&gt;Kris Wallsmith&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Framework or CMS&#160;&lt;span&gt;&lt;em&gt;Gaylord Aulke&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;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 &amp;#8220;sell&amp;#8221; 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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;The State of Symfony2&#160;&lt;span&gt;&lt;em&gt;Fabien Potencier&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I get the impression that Fabien likes to use conferences such as this one to announce yet another killer feature and really I can&amp;#8217;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.&lt;/p&gt;
&lt;div id=&quot;__ss_5399986&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.slideshare.net/fabpot/the-state-of-symfony2-symfonyday-2010&quot; title=&quot;The state of Symfony2 - SymfonyDay 2010&quot;&gt;The state of Symfony2 &amp;#8211; SymfonyDay 2010&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/fabpot&quot;&gt;Fabien Potencier&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Workshop&#160;&lt;span&gt;&lt;em&gt;Stefan Koopmanschap&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Get to know symfony &amp;#8211; at the end of the day, you will have completed your first running prototype app!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In parallel to all the session Stefan gave a workshop where he developed a simple facebook clone called &amp;#8220;GesichBuch&amp;#8221; together with all attendees. The bit of feedback that I overheard was appreciative and positive throughout. Makes me wonder why diaspora takes so long. &lt;img src=&quot;http://www.testically.org/wp-includes/images/smilies/icon_wink.gif&quot; alt=&quot;;)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;div id=&quot;__ss_5404379&quot;&gt;&lt;strong&gt;&lt;a title=&quot;symfony 1.4 workshop&quot; href=&quot;http://www.slideshare.net/skoop/symfony-14-workshop&quot;&gt;symfony 1.4 workshop&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/skoop&quot;&gt;Stefan Koopmanschap&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;</description>
	<pubDate>Mon, 11 Oct 2010 03:21:43 +0000</pubDate>
</item>
<item>
	<title>Quality Assurance in PHP Projects: The German Edition Started Shipping!</title>
	<guid>http://qualityassuranceinphpprojects.com/archives/18-guid.html</guid>
	<link>http://qualityassuranceinphpprojects.com/archives/18-The-German-Edition-Started-Shipping!.html</link>
	<description>&lt;p&gt;The &lt;a href=&quot;http://qualityassuranceinphpprojects.com/pages/german_edition.html&quot;&gt;German Edition&lt;/a&gt; of the PHP Quality Assurance book started shipping. &lt;a href=&quot;http://priebsch.de/&quot;&gt;Stefan&lt;/a&gt; and I, as well as all our &lt;a href=&quot;http://qualityassuranceinphpprojects.com/categories/Case-Studies&quot;&gt;contributing authors&lt;/a&gt;, are very happy about this. Below you can find additional information about the book in German.&lt;/p&gt;&lt;a href=&quot;http://www.amazon.de/gp/product/3446419233?ie=UTF8&amp;amp;tag=sbergmann&amp;amp;linkCode=as2&amp;amp;camp=1638&amp;amp;creative=6742&amp;amp;creativeASIN=3446419233&quot;&gt;&lt;img src=&quot;http://qualityassuranceinphpprojects.com/uploads/cover_de.jpg&quot; alt=&quot;Softwarequalit&#228;t in PHP-Projekten&quot; width=&quot;238&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;img src=&quot;http://www.assoc-amazon.de/e/ir?t=sbergmann&amp;amp;l=as2&amp;amp;o=3&amp;amp;a=3446419233&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;p&gt;Wenn die H&#252;tte brennt, werden &#220;berstunden gemacht und Urlaube abgesagt. Trotzdem werden Termine und Qualit&#228;tsziele meist verfehlt. Da Software jedoch weit l&#228;nger lebt als urspr&#252;nglich geplant, gehen die Probleme erst dann richtig los, wenn sp&#228;ter &#196;nderungen und Erweiterungen notwendig werden.&lt;/p&gt;&lt;p&gt;Im vorliegenden Buch vermitteln Sebastian Bergmann und Stefan Priebsch gemeinsam mit ihren Co-Autoren umfassendes Fachwissen und Erfahrungen zur Qualit&#228;tssicherung in PHP-Projekten. Zahlreiche Fallstudien veranschaulichen die Planung, Durchf&#252;hrung und Automation von Tests f&#252;r die unterschiedlichen Softwareschichten sowie die Beurteilung von Softwarequalit&#228;t mit Hilfe von Softwaremetriken. Sie sind die Grundlage daf&#252;r, Entwicklungsprozesse durch den Einsatz geeigneter Methoden wie etwa Continuous Integration zu optimieren. Die Fallstudien zeigen, wie bekannte Firmen und Projekte die Qualit&#228;t ihrer Software messen, kontrollieren und sichern, erm&#246;glichen einen Blick hinter die Kulissen und vermitteln so wertvolle Praxiserfahrungen.&lt;/p&gt;&lt;p&gt;Das Buch empfiehlt sich allen, die eine Referenz f&#252;r die Entwicklung qualitativ hochwertiger und nachhaltiger Softwareanwendungen in PHP suchen.&lt;/p&gt;&lt;h4&gt;Das Standardwerk zur Qualit&#228;tssicherung&lt;/h4&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Liefert wichtiges Grundlagenwissen zum Testen PHP-basierter Software&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Zeigt die Umsetzung von Ma&#223;nahmen zur Qualit&#228;tssicherung in der Praxis&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Enth&#228;lt hochinformative Fallstudien bekannter Firmen und Projekte&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Aus der Feder anerkannter PHP-Experten&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Beschreibt den aktuellen Wissensstand in Sachen Software-Qualit&#228;tssicherung&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The &lt;a href=&quot;http://qualityassuranceinphpprojects.com/pages/english_edition.html&quot;&gt;English edition&lt;/a&gt; of the book is scheduled for publication in December -- stay tuned!&lt;/p&gt;</description>
	<pubDate>Thu, 07 Oct 2010 08:00:00 +0000</pubDate>
	<author>nospam@example.com (Sebastian Bergmann)</author>
</item>

</channel>
</rss>

