{
    "href": "/post/2006/05/08/solar-0180-released-and-more-about-testing/",
    "relId": "2006/05/08/solar-0180-released-and-more-about-testing",
    "title": "Solar 0.18.0 released, and more about testing",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/solar/",
            "relId": "solar",
            "title": "Solar",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2006-05-08 22:08:55 UTC",
    "updated": [
        "2006-05-08 22:08:55 UTC"
    ],
    "html": "<p>I released <a href=\"http://solarphp.com/\">Solar</a> version 0.18.0 over the weekend.  The biggest change is in the testing methodology (yes, again ;-).</p>\n<p>A couple of weeks ago I had an IM-chat with <a href=\"http://weierophinney.net/matthew\">Matthew</a> about testing, and he related the merits of a PHPUnit-style approach, versus the <a href=\"http://paul-m-jones.com/blog/?p=193\">PHPT approach</a> I have blogged about previously.</p>\n<p>After having used both, I can say that the procedural <a href=\"http://qa.php.net/write-test.php\">PHPT</a> testing style is easier to approach for someone new to testing, and is great for smaller or standalone projects, but it doesn't seem to \"scale up\" well for larger class structures.  The object-oriented testing style used by <a href=\"http://pear.php.net/package/PHPUnit2\">PHPUnit</a> and <a href=\"http://www.lastcraft.com/simple_test.php\">SimpleTest</a> requires more inital setup work, but \"scales up\" much better in larger projects.</p>\n<p>I used PHPUnit while working at Zend, but frankly it seemed kind of magical to me; I just didn't get the way it worked internally, especially setting up test suites.  PHPUnit is a robust and highly configurable piece of software, but it does seem a bit impenetrable.  This may be due to the fact that PHPUnit is ideologically derived from similar Java projects, and I am just not a Java kind of guy.</p>\n<p>So in a spirit of meet-in-the-middle, I coded up a pair of Solar-based unit-test classes to take over from Solar_Test_Assert and .phpt, then converted a couple of existing .phpt tests to the new technique.  It worked like a champ.  After adding a Solar_Test_Suite class to scan a base directory for test cases and generate TAP-compliant output, I converted all the remaining .phpt tests to the new object-oriented testing style.  The new test suites run much faster, and it's easier to extend an abstract test-class than it is to copy and modify a bunch of .phpt files.</p>\n<p>You can see some code examples here:</p>\n<ul>\n<li>The abstract <a href=\"http://solarphp.com/svn/trunk/Solar/Test.php\">Solar_Test</a> unit test class</li>\n<li>A concrete test for <a href=\"http://solarphp.com/svn/trunk/tests/Test/Solar/Uri.php\">Solar_Uri</a>\n</li>\n<li>The <a href=\"http://solarphp.com/svn/trunk/Solar/Test/Suite.php\">Solar_Test_Suite</a> class</li>\n<li>The command-line <a href=\"http://solarphp.com/svn/trunk/tests/run.php\">test-runner</a>\n</li>\n</ul>\n<p>The test-runner is very easy to use.  If you want to run all tests, just issue \"php run.php\" from that directory and it will recursively run everything in the Test/* directory.  If you want to run a sub-series of tests, pass a class name as the only parameter; e.g., to run the Solar_Uri tests, issue \"php run.php Solar_Uri\".</p>\n<p>Test-runner output is TAP-compliant (which should make <a href=\"http://www.digitalsandwich.com/\">Mike Lively</a> happy ;-).  Among other things, this means it should be easy (in theory) to hook in to apache-test.  TAP output looks something like the following:</p>\n<pre><code>bash-2.05$ php run.php Solar_Uri\n1..21\nok 1 - Test_Solar_Uri::test__construct\nok 2 - Test_Solar_Uri::test_config\nok 3 - Test_Solar_Uri::testSet\nok 4 - Test_Solar_Uri::testFetch\nok 5 - Test_Solar_Uri::testQuick\nok 6 - Test_Solar_Uri::testSetQuery\nok 7 - Test_Solar_Uri::testSetPath\nok 8 - Test_Solar_Uri_Action::testFetch\nok 9 - Test_Solar_Uri_Action::testQuick\nok 10 - Test_Solar_Uri_Action::test__construct\nok 11 - Test_Solar_Uri_Action::test_config\nok 12 - Test_Solar_Uri_Action::testSet\nok 13 - Test_Solar_Uri_Action::testSetQuery\nok 14 - Test_Solar_Uri_Action::testSetPath\nok 15 - Test_Solar_Uri_Public::testFetch\nok 16 - Test_Solar_Uri_Public::testQuick\nok 17 - Test_Solar_Uri_Public::test__construct\nok 18 - Test_Solar_Uri_Public::test_config\nok 19 - Test_Solar_Uri_Public::testSet\nok 20 - Test_Solar_Uri_Public::testSetQuery\nok 21 - Test_Solar_Uri_Public::testSetPath\n21/21 tests, 0 seconds\n0 fail, 0 todo, 0 skip, 21 pass\nbash-2.05$</code></pre>\n<p>There's also a <a href=\"http://solarphp.com/svn/trunk/tests/make.php\">test-maker</a> script that generates a skeleton test class, with a test method for each public method in the target class.  Just issue \"php make.php My_Class_Name\".</p>\n<p>And of course, if you write your libraries to <a href=\"http://solarphp.com/index.php/docs/read/Main/SolarStandards\">Solar standards</a> (which are essentially <a href=\"http://pear.php.net/manual/en/standards.php\">PEAR standards</a> with a couple of additional points) then you too can use the Solar_Test tools to make your testing life much easier.</p>\n<p><strong>Update (11 July 2006):</strong> Updated links to point to new SVN directories.  Thanks, Clay Loveless.</p>\n"
}
