Monday, January 18, 2010

Why I created my Own Contiuous Integration Server

To begin, I wanted to post, if it wasn't obvious from other posts, my setup previously and the kinds of tools I am using and want to use.

  1. Selenium Grid
  2. CruiseControl with phpUnderControl
  3. ant for build tasks 
  4. Several VM's running various browsers and Selenium RC
  5. PHPUnit v 3.3.15 (more one this)
  6. PHP 5.2.10
  7. symfony framework v 1.2
  8. Doctrine 1.1
The projects I am working on range from simple to enterprise level, and it was at the enterprise level that I needed a high degree of reliability and reporting. Also, it has to be simple, and easy to manage (cause I don't have time to be creative).

Symfony comes with the lime testing framework, and I use this as a way to "unit test" my controllers/actions.  Most of my applications however have a high degree of Javascript built into them, making calls, updating the DOM, and I need to test this in as many browsers as possible.

Problems I ran into:

  1. New versions of PHPUnit (3.4) have removed the capability to log the test runs to a database without replacing these features in other products (phpc, phpuc etc) 
  2. If the code running the unit test doesn't log this information anymore how would you get accurate code coverage results without running the tests again.
  3. Complex XML logs are bulky and eat up disk space, and need to be rotated and managed. Not to mention, they are not human readable, so need to be parsed and exported into reports.
  4. Selenium Grid would hang occasionally if the browser gets in a bad state. 
  5. Other php unit testing frameworks do not integrate nicely with Selenium
  6. No way to easily store historic logs or screenshots in a logical manner.
  7. Just no "central" one tool to run, log, and view all the testing data. 
Since PHPUnit has removed the capability to log test runs in a database, and would rely on XML files in the future, I found this to be bulky and cumbersome. I would not be upgrading to the latest versions and instead be continuing to use the older versions that have this feature. This is a hard choice as I really wanted some of the newer features (grouping, required tests etc).

I needed a solution that I could setup quickly to replace my existing setup, without all the hassle that CruiseControl has (java server that is a memory hog). So, I decided to use the same tools that I use for development, and create a frontend to the PHPUnit database schema in 3.3.15.  This is easily accomplished with Doctrine and Symfony.

I ran the provided schema from phpunit in SQLite 3, placed the database in the /data directory, setup my database.yml file and ran the build-schema build-model command. I now had classes that mapped to the PHPUnit schema for logging.

I also setup a symfony task to execute phpunit using the sfPhpunit Plugin as well. Word of caution: this pulgin needs to be worked on to work correctly, and needs some extra work to accept several parameters. Mainly, I needed the test database parameters, the xml configuration file to use, and the bootstrap arguments. This was all easily added to the task, and the output is captured into the database.

From there, I created all the admin modules, as well as a few frontend modules to view the test runs in reports that made sense.

No comments:

Post a Comment