PHP Quality Assurance tools

in

PHP Quality Assurance tools are a must for any project, they can help in the analysis and optimization of your code by testing your code autonomously, finding duplicate code across your code base and giving you useful metrics towards your project goals.

In this post, we’ll discuss a few of the commonly used tools in PHP, and the very basics of how they are used. You’d usually use them in a continuous integration environment like Jenkins, but can also be run locally through your IDE whilst developing for a more real time update.

Installing the required tools

You can install all the tools we discuss here with Composer, Phar archives or PEAR.

I’ve written a separate post on how to do all three here:

Installing packages with Composer, Phar archives or PEAR


PHPUnit

PHPUnit allows you to write unit, integration and functional tests for your application written in PHP.

PHPUnit is pretty much the de facto standard in testing for PHP. There’s so much to go over I’ll probably save this for another blog post, but for now here’s a quick intro.

Unit Tests

Unit tests test the smallest unit of functionality, typically a method or function. Unit tests are usually done all in-memory and should not access the database, use the file system, access any API’s or create any new threads, it’s sole job is to test a single specific function, independent of any dependencies. If the method your testing requires access to a database, API or file system, you should Mock these methods so that they return the expected value and you can continue with your test. It may turn out that your unit tests work perfectly independently, but when combined together they fail for any reason. This brings us onto…

Integration Tests

Integration tests are used to build on unit tests by combining the individual units together and testing them combined to achieve the same result. The key here is to test that the code and the environment works together (without Mocks). We need to be sure our unit tests (above) can successfully read and write from the file system, read and write from the DB etcetera. This would test the individual unit with all the dependencies required. The advantage is they will find bugs that unit tests can’t especially with external dependencies.

Functional Tests

Functional tests checks that a particular function or feature functions as expected. Functional tests don’t involve any intermediate results or side effects, they simply test the result to assert it is as expected.

Acceptance Tests

We won’t cover acceptance tests, but they are basically tests described in plain English that ensure the applications features are completed as requested. This could be useful for example in an agile development environment to ensure the customer’s requirements have been met.

A basic PHPUnit example

Here’s a basic example of a PHPUnit test using the Symfony framework. Symfony provides us with a WebTestCase class we can extend to help us perform our tests. It goes to a page, ensures we have a 200 OK response, and that the content Hello World is displayed within HTML <h1> tags.

/**
 * A simple Symfony PHPUnit example test
 */
public function testPageLoadsOKwithHelloWorld()
{
    // Create a client GET request for the homepage "/"
    $client = $this->createClient();
    $crawler = $client->request('GET', '/');

    // Check for our `Hello World` h1 tag
    $this->assertRegExp('/Hello World!/', $crawler->filter('h1')->html());

    // We should have a 200 OK
    $this->assertTrue($client->getResponse()->isSuccessful());
}

This is a very basic example, but hopefully you understand how powerful this can be. You can test almost every aspect of your application using a similar approach as above. After running the tests on your code, you can optionally have it configured so that it also outputs code coverage, to enable this you will need to install and configure the xDebug PHP extension. You can have the code coverage reported in a HTML document in your browser, or directly in your IDE.

Here’s a screenshot below of my editor (Netbeans) displaying the code coverage in-line. The light green lines are code that has been reported as covered by PHPUnit, the red lines as code that has not been covered. It also shows the total code coverage for this class at the bottom.

PHPUnit Code Coverage Netbeans

PHP Code Sniffer

PHP Code Sniffer is extremely useful for detecting violations of a specified coding standard. Using this you’ll definitely find your code is much more consistent and readable throughout. You can run this via your IDE, terminal or Jenkins to sniff your code as your team commits to the repository.

$ phpcs Controller/

FILE: .../Sites/mywebsite/src/Acme/BlogBundle/Controller/BlogController.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
34  | ERROR | Missing @return tag in function comment
147 | ERROR | Missing blank line before return statement
--------------------------------------------------------------------------------

Here phpcs is expecting a blank line before a return statement (for readability) and a missing @return tag in phpDoc.

You can use this in your IDE to highlight issues as you code. You can imagine that if you have a team of developers working on a project, this can help tremendously in writing clean, consistent, readable code.


PHP Mess Detector

PHP Mess Detector (phpmd) is used to check your source code for possible bugs, sub-optimal code, unused variables and over complicated expressions, all of these can be configured by the user using rulesets. Similar to phpcs but it does several different things.

$ phpmd Controller xml codesize,unusedcode,naming
<?xml version="1.0" encoding="UTF-8" ?>
<pmd version="@package_version@" timestamp="2014-07-03T20:10:39+01:00">
  <file name="/path/to/file/Controller/BlogController.php">
    <violation
      beginline="154"
      endline="154"
      rule="UnusedLocalVariable"
      ruleset="Unused Code Rules"
      externalInfoUrl="http://phpmd.org/rules/unusedcode.html#unusedlocalvariable"
      priority="3">
      Avoid unused local variables such as '$var'.
    </violation>
  </file>
</pmd>

Here phpmd reports that we have an unused variable $var in our BlogController.php:Line-154. This is quite cool and you’ll certainly notice an improvement in your code after fixing these inconsistencies.


PHP Lines Of Code

phploc is a tool for quickly measuring the size and analysing the structure of a PHP project. This one is simple, it gives you a bunch of useful statistics on your code.

$ phploc app/bootstrap.php.cache
phploc 2.0.5 by Sebastian Bergmann.

Size
  Lines of Code (LOC)                             3071
  Comment Lines of Code (CLOC)                       0 (0.00%)
  Non-Comment Lines of Code (NCLOC)               3071 (100.00%)
  Logical Lines of Code (LLOC)                    1255 (40.87%)
    Classes                                       1178 (93.86%)
      Average Class Length                          78
      Average Method Length                          3
    Functions                                       37 (2.95%)
      Average Function Length                       37
    Not in classes or functions                     40 (3.19%)

# ... ... ...
# example truncated for brevity

PHP Depend

PHP_Depend is a program that performs analysis on your code base. It can provide a whole bunch of software metrics related to your code. It also generates SVG graphs that can help visualize statistics. The PHP_Depend website provides a more complete explanation as to how it works.

http://pdepend.org/documentation/what-is-php-depend.html


What is PHP Copy Paste Detector?

This ones simple, it shows any lines of duplicated code across files.

Example: within AcmeDemoBundle directory

$ phpcpd .
phpcpd 2.0.1 by Sebastian Bergmann.
0.00% duplicated lines out of 393 total lines of code.
Time: 30 ms, Memory: 2.75Mb

Example: within a new Wordpress directory

$ phpcpd .
phpcpd 2.0.1 by Sebastian Bergmann.
Found 48 exact clones with 1633 duplicated lines in 30 files:
# ... {lines of all the filenames and line numbers ...
0.66% duplicated lines out of 246965 total lines of code.
Time: 12.4 seconds, Memory: 234.50Mb

What is PHP Code Browser?

PHP Code Browser (phpcb) can be used to generate the HTML structure of your code base to be navigated through a web browser. It will generate the entire directory structure and allow you to navigate and view your source files through your browser (like Github - but very basic). This works great with Jenkins and other tools like phpmd and phpcs, any violations will be shown in-line when browsing the generated files.

Example: (within the directory you want to generate for (.), output it to phpcb directory)

$ phpcb --source . --output phpcb

This will create a new folder named phpcb within your directory. Open the phpcb/index.html in your browser!


What is PHP Documenter?

PHPDocumenter is fantastic; it parses your PHP project, reads all your PHPDoc comments, and builds all that information into traversable HTML documentation. The best way to see this is to run it on one of your projects or an open source framework (Zend or Symfony). It’s amazing, You can even theme the generated documentation to match your brand or agency.

// src: /src/Acme/DemoBundle/Controller/DefaultController.php

/**
 * These are the `doc comments` that are parsed by PHPDoc
 * The params, return types and description are automatically
 * documented using phpDoc
 *
 * @param array $someParam That array I forgot to document! and nobody knows about!
 *
 * @return Type Description of item
 */
 public function indexAction($someParam) { /* Truncated */}

Example: Make documentation from all the files in -d directory src/ (Symfony User Bundles)

$ phpdoc -d src/
# .. lots of output.., your documentation is in the "output" directory
# open the "output/index.html" in your browser!

Conclusion

These are great tools and can be used independently or with a continuous integration server. I mainly use them in conjunction with a Jenkins CI server and the Jenkins PHP Template. Whenever a new commit is made to my git repository, I fire off a request to my Jenkins server with a post commit hook. Jenkins will then trigger a new build and run all the tools above.

I’d highly recommend the usage of a Jenkins continuous integration server along with these tools. If your not currently using them, I’m sure they will help you to write even more cleaner, testable & consistent code.