Forget SEO – what about Test Optimization?

I’ve recently been working on a project trying to take an existing customized wordpress site and create automated integration tests around parts of it.  I’m using phpUnderControl, phpUnit, Selenium RC, Firefox, Xvfb (virtaul frame buffer) and … well, I think that’s it.

So, phpUC is configured to do a checkout from svn on a commit, then run tests.  I have a few base unit tests written, then a set of integration tests.  The integration tests are written in phpUnit and use the Selenium integration to launch a Firefox browser in a virtual frame buffer and then interact with the browser programmatically.  The basics work fine, and I’ve had some basic success after not *too* much setup time.

The first problem I ran in to was with wordpress.  WordPress will only work on the configured ‘siteurl’ (which is configured in the database).  I did a dump of a dev db from a different server, then brought that over to the qa server and set up a wp db, then pointed the svn ‘checked out’ code to that database.  Every time I hit the qa server it was redirecting me to the original server.  After some futzing around, I realized the problem – ‘siteurl’ and maybe another config are set in the database.  The short solution was to search/replace through the MySQL dump the reimport that for the QA installation.  Worked fine.  I don’t think this is an ideal solution, but it got me through the initial hump.

Second problem is much more subtle (insidious, even).  The original dev site was at dev.mainsite.com.  I moved it over to qa.generalsite.com/project/.  Even after switching the ‘siteurl’ in the WordPress MySQL dump, I ran in to problems.  The templates all were written to be relative to a site running at the root (in this case, dev.mainsite.com).  All css and js were looking for “/js/myjs.js” and “/css/mycss.css” and so on.  There’s no easy fix for this without having to actually go in and forecefully make the templates use full paths.  I *can* in this case add new domain names (I could make “qa_project.generalsite.com, for instance), but this is less than ideal.

Why is it less than ideal?  Well, it’s not a process that everyone can engage in.  To make something testable now requires that I have access to manage the DNS and add virtual hosts.  This is just not something that everyone can do.  The original option – modifying core code for a project – is doable, but likely not something many people will end up doing.  They’d probably just skip automated testing rather than have to make the code testable in the first place.

Obviously *writing* a system that’s testable from day 1 would be better, but most systems aren’t built that way, and because many people don’t test much (or at all), the concept of a ‘testable’ system is just not high on their list of priorities.  I took over a system a few years ago that announced all system messages on the site via an ‘alert’ in the body’s “onload” method.  This was the *one* case that Selenium couldn’t deal with.  That’s not to say that no automated browser managers could handle it – Silk Performer could, and some others, but they also cost money that not everyone can spend.

In my view, for code to be testable (both unit and integration testing) it needs to be portable.  The code should be able to be checked out and set up in a new server environment with a minimum of steps and time.  The entire process should be able to be scripted (in other words, a build process) and eventually automated, but it’s not something I shoot for right out of the gate with existing legacy code.  The process of making the code portable (and therefore more easily testable) is not something that will often come quickly, and will likely be something you’ll need to work towards while doing the ‘real’ work.

As I aluded to earlier, the code needs to be portable both from a code standpoint but also from a ‘front end’ standpoint.  If relative URLs are used in the HTML, use a “base href” tag at the top which is filled in with a dynamic parameter set in a config file.  In PHP, set a constant indicating a base path, and make include() statements reference the constant.  *Don’t* hardcode include_path in an .htaccess file.  Why not?  .htaccess files are only ‘valid’ in the context of a web server running.  If you want to run unit tests from a command line, your code will simply not work.

What steps have you taken to make sure your code (both backend and frontend) is testable?


I'm currently working on a book for web freelancers, covering everything you need to know to get started or just get better. Want to stay updated? Sign up for my mailing list to get updates when the book is ready to be released!

Web Developer Freelancing Handbook

Share and Enjoy:
  • del.icio.us
  • DZone
  • Facebook
  • Reddit
  • StumbleUpon
  • Digg
  • Simpy
  • Technorati

Tags: , , , , , , , ,

{ 5 comments to read ... please submit one more! }

  1. The static files problem: you can do a little trick. Set an auto_prepend PHP on the dev box, and register an output buffer function, and in function you can replace the urls.

    Best Regards,
    Felhő

  2. Thank you for the tip. I’ve used that trick in some cases, and it works like a champ some times. It does not help with redirects tho – header(“Location: wherever”); – and there’s no way to intercept that without doing some changing to the core code itself.

  3. Re database configuration:
    Begining with phpunit 3.2 you have the ability to use the database extension. Using the database extension you can actually set up your database contents prior to each test. It could help you ensure your configuration on your test database isn’t getting changed on you.

    Re dns:
    I have started using dnsmasq for local development. Using dnsmasq you can actually set up a particular domain to basically wildcard to a particular address. Using this I have pointed lively.loc to 127.0.0.1 so any site I am working on can have an address such as wordpress.lively.loc

    dnsmasq is an incredibly usful tool when it comes to local development.

  4. Wow, building a test suite for wordpress IS an ambitious undertaking. It is a collection of procedural legacy code layered together over several years. How far did you get?

  5. @eran – it’s not specifically testing wordpress functionality, but extra functionality that’s been built around wordpress – a paid subscription feature for some of the blog, for example. I’m only concentrating on testing those features for now. I think the long term goal is to move off wordpress on to something else.

{ 0 Pingbacks/Trackbacks }

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">



0.18453216552734