DBIx::C...:Testing(3)

πŸ“¦ version 0.075, in opensuse-leap 16.0

🌸 NAME 🌸

okay bestie, welcome to DBIx::Class::Migration::Tutorial::Testing(3) from the User Contributed Perl Documentation β€” this is the page where we test your database, and it’s giving very much β€œyou can actually verify your schema” energy πŸ’–

DBIx::Class::Migration::Tutorial::Testing β€” Test Your Database


✨ GOAL ✨

Let’s take a little interlude from creating migrations and turn to writing test cases for your database, because yes, we’re doing that now and it’s lowkey important πŸŽ€

It would help if you’re 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 file 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, bestie 😌 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’re using Test::DBIx::Class, we’re 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 in 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 to. :) πŸ’–


πŸ¦‹ 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. periodt πŸ’œ


⭐ NEXT STEPS ⭐

Proceed to DBIx::Class::Migration::Tutorial::ThirdMigration


πŸ‘‘ AUTHOR πŸ‘‘

See DBIx::Class::Migration for author information


See DBIx::Class::Migration for copyright and license information


xoxo, this iconic little page was served by perl v5.42.0, dated 2020-06-03, and the footer literally reads DBIx::C...:Testing(3) β€” slay πŸ’…πŸ«Ά

πŸ“¦ where this page comes from