Custom PHPUnit Annotations

Here’s a trick that I just implemented on our own testing framework to handle custom annotations. Annotations are comments written in a standard format that are used to declare properties for tests, such as dependencies and grouping. You can read more about the standard PHPUnit annotations here: http://www.phpunit.de/manual/current/en/appendixes.annotations.html

There are only a handful of annotations available natively to the PHPUnit framework. I’ve written some code that allows you to create additional rules you might need, and trigger them with your own custom annotations. You’ll need to instantiate a ReflectionMethod and then parse the doc block for the proper data.

In the sample code provided below, I look for the annotation “@browser” to determine what type of browser to launch (Firefox, Chrome, Internet Explorer, etc.) If the browser is not found, then setUp() does not launch a browser. I create a user through the web app using Selenium, and then test that user with curl requests against our API. The curl requests did not require a Selenium browser, which saved about 10 seconds of setup per test.


protected function setUp() {
 
  $class      = get_class( $this );
  $method     = $this->getName();
  $reflection = new ReflectionMethod( $class, $method );
  $doc_block  = $reflection->getDocComment();
 
  // Use regex to parse the doc_block for a specific annotation
  $browser = self::parseDocBlock( $doc_block, '@browser' );
 
  if ( !self::isBrowser( $browser )
    return false;
 
  // Start Selenium with the specified browser
 
} // setup
 
private static function parseDocBlock( $doc_block, $tag ) {
 
  $matches = array();
 
  if ( empty( $doc_block ) )
    return $matches;
  
  $regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U";
  preg_match_all( $regex, $doc_block, $matches );
 
  if ( empty( $matches[1] ) )
    return array();
 
  // Removed extra index
  $matches = $matches[1];
 
  // Trim the results, array item by array item
  foreach ( $matches as $ix => $match )
    $matches[ $ix ] = trim( $match );
 
  return $matches;
 
} // parseDocBlock
 
private static function isBrowser( $browser ) {
 
  $browsers = array(
    'firefox',
    'chrome'
  );
 
  return ( array_search( $browser, $browsers ) !== false );
 
} // isBrowser

There are definitely more uses for custom annotations. Let me know how you use annotations in your testing framework by either tweeting me at @brokenthumbs or leaving a comment in the form below.

2 comments

  1. — December 8, 2012 3:32 pm

    I might definitely be all for getting rid in the West twins, as they have dragged down The Flash comics over the past few a long time. For that matter, I would also jettison Linda Park, as I have never warmed up to this character in any respect. Wally would be retconned as being a single guy. And why never they call the character JESSICA Quick rather of Jesse (which is the MALE spelling from the name). It would be way more feminine. And also concentrate more on her marriage to Rick Tyler, aka Hourman. Even during their time in the JSA, I hardly ever saw any connection or chemistry in between them whatsoever. Zero!

  2. Spudley
    — October 20, 2014 9:51 am

    Or you could just use phpUnit’s built-in getAnnotations() method:

    $browser = $this->getAnnotations()['method']['browser'];

    (I know it isn’t documented anywhere, but it does work)

Submit