1=head1 NAME 2 3DBIx::Class::Migration::Tutorial::Testing - Test Your Database 4 5=head1 GOAL 6 7Let's take an interlude from creating migrations and turn to writing test 8cases for your database. 9 10It would help if you are familiar with L<Test::Most> and L<Test::DBIx::Class> 11and with general Perl testing procedures. You could also benefit from reviewing 12our fixtures hook class L<Test::DBIx::Class::FixtureCommand::Population>. 13 14=head1 Test your 1-2 Upgrade 15 16When doing upgrades it would be great to have some automated tests in place so 17that whoever does the upgrade can immediately verify that all is well. Let's 18add a test case now! 19 20 touch t/upgrade-1to2.t 21 22Then open the new files in the editor of choice and enter the following code: 23 24 #!/usr/bin/env perl 25 26 use Test::Most; 27 use Test::DBIx::Class 28 -schema_class=>'MusicBase::Schema', 29 -fixture_class => '::Population', 30 qw(Artist Country); 31 32 plan skip_all => 'not correct schema version' 33 if Schema->schema_version != 2; 34 35 fixtures_ok ['all_tables']; 36 37 is Country->count, 3, 'Correct Number of Countries'; 38 ok Artist->first->has_country, 'Artist has a country'; 39 40 done_testing; 41 42This creates a basic test case that only runs for version 2 of the schema (this 43is just testing that the version 2 update was correct after all). It uses 44L<Test::DBIx::Class> to automatically deploy a temporary test database (by 45default it creates a C<SQLite> in-memory database) which reflects the current 46schema and then we populate the C<all_tables> fixtures using the utility class 47L<DBIx::Class::Migration::Population> which is part of the L<DBIx::Class::Migration> 48distribution. (In this case, since we are using L<Test::DBIx::Class>, we are 49using the fixture hook L<Test::DBIx::Class::FixtureCommand::Population>). 50 51Before we can run the test case, we need to update our C<dist.ini> 52file. Open this is a text editor and change it to look like this: 53 54 name = DBIx-Class-Migration 55 author = John Napiorkowski <jjnapiork@cpan.org> 56 license = Perl_5 57 copyright_holder = John Napiorkowski 58 copyright_year = 2012 59 abstract = Tutorial Application for DBIx-Class-Migration 60 61 version = 0.001 62 63 [@Basic] 64 [Prereqs] 65 DBIx::Class = 0 66 DBIx::Class::Migration = 0 67 68 [Prereqs / TestRequires] 69 Test::Most = 0 70 Test::DBIx::Class = 0 71 72We just added a new section "[Prereqs / TestRequires]" and listed the two 73testing modules. Great, now install the new dependencies: 74 75 dzil listdeps | cpanm 76 77Perfect, we are now fully up to date and anyone that checks out our code can 78also be sure to have all the right dependencies. Let's run the test case: 79 80 $ prove -lv t/upgrade-1to2.t 81 t/upgrade-1to2.t .. 82 Restored set all_tables to database 83 ok 1 - Correct Number of Tests 84 ok 2 - Artist has a country 85 1..2 86 ok 87 All tests successful. 88 Files=1, Tests=2, 1 wallclock secs ( ... ) 89 Result: PASS 90 91So hopefully that was easier database testing than you might be used too. :) 92 93=head1 Additional Domain Logic Testing 94 95Let's create another test for the Artist ResultSet class. You might have 96wondered about this code, which you added way back at the start of the 97tutorial: 98 99C<lib/MusicBase/Schema/ResultSet/Artist.pm> 100 101 package MusicBase::Schema::ResultSet::Artist; 102 103 use strict; 104 use warnings; 105 use base 'DBIx::Class::ResultSet'; 106 107 sub has_more_than_one_cds { 108 my $me = (my $self = shift)->current_source_alias; 109 $self->search( 110 {}, 111 { 112 join=>['cd_rs'], 113 '+select'=> [ { count => 'cd_rs.cd_id', -as => 'cd_count'} ], 114 '+as'=> ['cd_count'], 115 group_by=>["$me.artist_id"], 116 having => { cd_count => { '>', 1 } } 117 } 118 ); 119 } 120 121 1; 122 123This is a bit of logic that just returns the set of Artist with more than one 124cd. This is the kind of custom resultset logic your application may require 125and therefore you should have a test case. Let's build one: 126 127 touch t/more-than-1.t 128 129Then open C<t/more-than-1.t> in your text editor and add this code: 130 131 #!/usr/bin/env perl 132 133 use Test::Most; 134 use Test::DBIx::Class 135 -schema_class=>'MusicBase::Schema', 136 -fixture_class => '::Population', 137 qw(Artist); 138 139 fixtures_ok ['all_tables']; 140 141 ok my $more_than_one_rs = Artist->has_more_than_one_cds, 142 'Got some artists'; 143 144 is $more_than_one_rs->count, 1, 145 'Got expected number of artists with more than one CD'; 146 147 done_testing; 148 149If you go back to the original fixture data, you'll see we only have one Artist 150in the C<all_tables> fixture set that has more than one CD (Michael Jackson). 151 152Obviously this is a pretty minimal test case, but it at least gets you started. 153let's run it: 154 155 $ prove -lv t/more-than-1.t 156 t/more-than-1.t .. 157 Restored set all_tables to database 158 ok 1 - Got some artists 159 ok 2 - Got expected number of artists with more than one CD 160 1..2 161 ok 162 All tests successful. 163 Files=1, Tests=2, 1 wallclock secs ( ... ) 164 Result: PASS 165 166That's it for Testing! 167 168=head1 SUMMARY 169 170This was a short section, but important. We explored how straightforward it is 171to create meaningful test cases using our generated fixtures, if you use the 172right tools to help you. We also explored the idea of limiting test cases to 173certain database versions, which will be an important thing for you to remember 174as you continue moving forward with your database changes. 175 176=head1 NEXT STEPS 177 178Proceed to L<DBIx::Class::Migration::Tutorial::ThirdMigration> 179 180=head1 AUTHOR 181 182See L<DBIx::Class::Migration> for author information 183 184=head1 COPYRIGHT & LICENSE 185 186See L<DBIx::Class::Migration> for copyright and license information 187 188=cut 189 190