NAME
DBIx::Class::Migration::Tutorial::Testing - Test Your Database
GOAL
Let's take an interlude from creating migrations and turn to writing test cases for your database.
It would help if you are familiar with Test::Most and Test::DBIx::Class and with general Perl testing procedures. You could also benefit from reviewing our fixtures hook class Test::DBIx::Class::FixtureCommand::Population.
Test your 1-2 Upgrade
When doing upgrades it would be great to have some automated tests in place so that whoever does the upgrade can immediately verify that all is well. Let's add a test case now!
touch t/upgrade-1to2.t
Then open the new files in the editor of choice and enter the following code:
#!/usr/bin/env perl
use Test::Most;
use Test::DBIx::Class
-schema_class=>'MusicBase::Schema',
-fixture_class => '::Population',
qw(Artist Country);
plan skip_all => 'not correct schema version'
if Schema->schema_version != 2;
fixtures_ok ['all_tables'];
is Country->count, 3, 'Correct Number of Countries';
ok Artist->first->has_country, 'Artist has a country';
done_testing;
This creates a basic test case that only runs for version 2 of the schema (this is just testing that the version 2 update was correct after all). It uses Test::DBIx::Class to automatically deploy a temporary test database (by default it creates a SQLite
in-memory database) which reflects the current schema and then we populate the all_tables
fixtures using the utility class DBIx::Class::Migration::Population which is part of the DBIx::Class::Migration distribution. (In this case, since we are using Test::DBIx::Class, we are using the fixture hook Test::DBIx::Class::FixtureCommand::Population).
Before we can run the test case, we need to update our dist.ini
file. Open this is a text editor and change it to look like this:
name = DBIx-Class-Migration
author = John Napiorkowski <jjnapiork@cpan.org>
license = Perl_5
copyright_holder = John Napiorkowski
copyright_year = 2012
abstract = Tutorial Application for DBIx-Class-Migration
version = 0.001
[@Basic]
[Prereqs]
DBIx::Class = 0
DBIx::Class::Migration = 0
[Prereqs / TestRequires]
Test::Most = 0
Test::DBIx::Class = 0
We just added a new section "[Prereqs / TestRequires]" and listed the two testing modules. Great, now install the new dependencies:
dzil listdeps | cpanm
Perfect, we are now fully up to date and anyone that checks out our code can also be sure to have all the right dependencies. Let's run the test case:
$ prove -lv t/upgrade-1to2.t
t/upgrade-1to2.t ..
Restored set all_tables to database
ok 1 - Correct Number of Tests
ok 2 - Artist has a country
1..2
ok
All tests successful.
Files=1, Tests=2, 1 wallclock secs ( ... )
Result: PASS
So hopefully that was easier database testing than you might be used too. :)
Additional Domain Logic Testing
Let's create another test for the Artist ResultSet class. You might have wondered about this code, which you added way back at the start of the tutorial:
lib/MusicBase/Schema/ResultSet/Artist.pm
package MusicBase::Schema::ResultSet::Artist;
use strict;
use warnings;
use base 'DBIx::Class::ResultSet';
sub has_more_than_one_cds {
my $me = (my $self = shift)->current_source_alias;
$self->search(
{},
{
join=>['cd_rs'],
'+select'=> [ { count => 'cd_rs.cd_id', -as => 'cd_count'} ],
'+as'=> ['cd_count'],
group_by=>["$me.artist_id"],
having => { cd_count => { '>', 1 } }
}
);
}
1;
This is a bit of logic that just returns the set of Artist with more than one cd. This is the kind of custom resultset logic your application may require and therefore you should have a test case. Let's build one:
touch t/more-than-1.t
Then open t/more-than-1.t
in your text editor and add this code:
#!/usr/bin/env perl
use Test::Most;
use Test::DBIx::Class
-schema_class=>'MusicBase::Schema',
-fixture_class => '::Population',
qw(Artist);
fixtures_ok ['all_tables'];
ok my $more_than_one_rs = Artist->has_more_than_one_cds,
'Got some artists';
is $more_than_one_rs->count, 1,
'Got expected number of artists with more than one CD';
done_testing;
If you go back to the original fixture data, you'll see we only have one Artist in the all_tables
fixture set that has more than one CD (Michael Jackson).
Obviously this is a pretty minimal test case, but it at least gets you started. let's run it:
$ prove -lv t/more-than-1.t
t/more-than-1.t ..
Restored set all_tables to database
ok 1 - Got some artists
ok 2 - Got expected number of artists with more than one CD
1..2
ok
All tests successful.
Files=1, Tests=2, 1 wallclock secs ( ... )
Result: PASS
That's it for Testing!
SUMMARY
This was a short section, but important. We explored how straightforward it is to create meaningful test cases using our generated fixtures, if you use the right tools to help you. We also explored the idea of limiting test cases to certain database versions, which will be an important thing for you to remember as you continue moving forward with your database changes.
NEXT STEPS
Proceed to DBIx::Class::Migration::Tutorial::ThirdMigration
AUTHOR
See DBIx::Class::Migration for author information
COPYRIGHT & LICENSE
See DBIx::Class::Migration for copyright and license information