in reply to
Testing database updates.
Personally, I really like to use DBD::SQLite with a :memory: database for each test. For each test case, I load the database mostly using DBIx::RunSQL, then run the test modifications against it and then run query statements as tests that check the database status for the "interesting" results.
A typical test file looks like this:
AUFGABENBEDARFZEITRAUM Werte durch Trigger
---
SELECT
Aufgabe,
Anfang,
Ende,
id as aufgabenbedarf,
werktage,
tagesbedarf,
tagesbedarf_mak
FROM t_aufgabenbedarf --AUFGABENBEDARFZEITRAUM_V
order by aufgabe
---
[
[
'301',
'2011-10-01 00:00:00',
'2011-10-31 00:00:00',
'141',
'20',
'28080',
'1.04545454545455'
],
[
'302',
'2011-10-01 00:00:00',
'2011-10-31 00:00:00',
'142',
'20',
'14040',
'0.522727272727273'
],
[
'303',
'2011-10-01 00:00:00',
'2011-10-31 00:00:00',
'143',
'20',
'14040',
'0.522727272727273'
]]
It is basically the test title, test query and the expected results, as I have to test many views that should remain constant.
The driver for these tests is (abridged) the following program, with some Oracle-to-SQLite converter ripped out for brevity:
#!perl -w
use strict;
use DBD::SQLite;
use File::Glob qw(bsd_glob);
use Getopt::Long;
use DBIx::RunSQL;
use Test::More;
use Data::Dumper;
GetOptions(
'verbose|v' => \my $verbose,
'db:s' => \my @ora,
'commit-prepare' => \my $do_commit,
'sqlite:s' => \my $dbfile,
);
$dbfile ||= ':memory:';
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef,
{ AutoCommit => 0, PrintError => 0, RaiseError => 1 }
);
$dbh->do('PRAGMA synchronous = OFF;');
print "# Using DBD::SQLite $DBD::SQLite::VERSION on Perl $^V\n"
if $verbose;
my (@sql_files) = @ARGV;
@sql_files = sort map { bsd_glob $_ } @sql_files;
# First read the SQL files that set up this test case
my @setup = grep /\.sql$/, @sql_files;
push @setup, 'tests/compat-triggers.sql';
# And separate out the test files that run against this test case
my @tests = grep /\.t$/, @sql_files;
# Also find some global invariant tests that should hold true for
# any test case. These are mostly sanity tests that the database
# was constructed correctly
my @invarianten = glob "tests/*.invariante";
if (@tests) {
unshift @tests, @invarianten;
plan tests => 0+@tests;
};
if (@ora) {
load_oracle($_) for @ora;
create_views();
$dbh->commit;
};
for my $prepare (@setup){
DBIx::RunSQL->run_sql_file(
dbh => $dbh,
sql => $prepare,
verbose => $verbose,
);
$dbh->commit if $do_commit;
};
for my $test (@tests) {
open my $fh, '<', $test
or die "$test: $!";
local $/ = "---";
chomp( my ($description,$sql,$expected) = <$fh>);
$description =~ s/\s+$//;
my $res = eval { $dbh->selectall_arrayref($sql) };
if( $@ ) {
die "$@ when running \n$sql";
};
if(! is_deeply($res, eval $expected, $description)) {
diag Dumper eval $expected;
diag Dumper $res;
};
}