In addition to the libraries/frameworks that Alan has already mentioned, you can make use of mod_perl's Apache::Test, which I what I use as a harness. It allows me to very simply integrate tests into my release process. The harness uses TAP output (Test Anything Protocol) to determine whether or not the tests pass or fail, using libraries like Test::Simple or Test::More (Perl and PHP).
Out of the box Apache::Test supports writing tests in both Perl and PHP. In my own projects, it took a little bit of trickery and a lot of reading to really get it working, but an implementation of Test::More in PHP is built-in to the harness. Running all tests written in both PHP and Perl is done through a single command and any failure along the way is captured Apache::Test, noting as best it can what went wrong.
The awesome part about all this is that you can even utilize PHPUnit, or Simple-Test alongside the previous two testing frameworks. By running tests in each respective library, you can use the PHP implementation of Test::More (or even Perl by testing stdout) and spit back out TAP for your harness to interpret.
Be sure to read the Apache::Test documentation and the mod_perl guide to running Apache::Test. Additionally, I found the article here a great help.
As a quick example, you could setup a test in Perl in very few lines of code that will run through all the pages on your site (that have links) and verify all result in '200 OK
' responses and don't have any parsing errors:
#!perl
use strict;
use warnings;
use Apache::Test qw(:withtestmore);
use Apache::TestRequest;
use Test::More;
use Test::WWW::Mechanize;
use WWW::CheckSite::Validator;
use WWW::CheckSite::Spider;
plan 'no_plan';
my $config = Apache::Test::config();
my $host = "http://". Apache::TestRequest::hostport($config) || '';
my $s = WWW::CheckSite::Spider->new(
uri => $host,
ua_class => 'Test::WWW::Mechanize',
);
my $m = $s->current_agent;
while (my $page = $s->get_page) {
is($m->status(), "200", $m->uri() ." retrieved successfully.");
$m->content_lacks("Parse Error", $m->uri() ." does not contain syntax errors.");
}