chrestomanci has asked for the wisdom of the Perl Monks concerning the following question:

Learned brothers, I have a question:

I am working on an application that uses DBIx::Class to store it's data. There are around 100 tables, with plenty of joins and other relationships between the various tables. It is a complicated beast.

As with any large project, I have a number of tests. Most of them work by starting with an empty copy of the database, populating a small number of tables with a small amount of data, and then testing that the API calls retrieve the expected data. For example:

use strict; use warnings; use Test::More tests => 134; use My::Company::Schema; # Creates an empty SQLite DB in memory and deploys the schema to it. my $schema = My::Company::Schema->connect; # set-up some test data my $tblFoo = $schema->resultset('Foo'); my $foo_item_1 = $tblFoo->create({ name => 'item1', # Other fields }); my $foo_item_2 = $tblFoo->create({ name => 'item2', # More fields }); my $bar_item = $foo_item_2->add_to_relation({'key'=>'value'}); # More code to populate the test DB. # Tests: my $found_entry_foo = $tblFoo_rs->big_complex_api_call(); is( $found_entry_foo->id, $bar_item->id, "The correct entry from tblFo +o was found" );

The problem is, is that test above contains a bug. On the last line the primary key of the returned row is compared with the expected value from the WRONG table. The idiom is used in thousands of tests, and I have a nasty feeling that the wrong comparisons are done in quite a few places.

The reason the bug goes un-detected, is that the test tables only contain a few rows, and the numeric primary keys start from 1, and number incrementally, so there is a good chance that row 2 in one table could get confused with row 2 in another.

Is there an extension, or directive I can give to DBIx::Class, that will cause it to start the numbering of primary keys from a random large number, in order to flush out bugs like this? I did not find anything from reading the DBIx::Class docs, or from Google, though I could be looking in the wrong place.

Replies are listed 'Best First'.
Re: DBIx::Class Randomise datbase primary keys for testing.
by moritz (Cardinal) on Nov 24, 2010 at 12:42 UTC

    By default DBIx::Class lets the database generate the primary key.

    And I think that's a very sensible default; so you should investigate if your database has a way to customize primary key generation.

      If one creates a complete database scheme just for testing, as done in the original post, inserting a random number of dummy records into each of the tables could be sufficient. On a RDBMS with real sequences (like Oracle), creating the sequences in a way that they start at a random number should give a similar effect.

      A different approach, again needing sequences, would be to use a single sequence to generate all IDs, at least for the test database. That would reliably detect that special problem of using IDs from a wrong table.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: DBIx::Class Randomise datbase primary keys for testing.
by locked_user sundialsvc4 (Abbot) on Nov 24, 2010 at 14:06 UTC

    Since a Test script is Perl, would it be possible for you to define a sub, either within the script or within a used module of your own devising, that would supply a random primary-key value to a designated field?

    It is difficult to contemplate changing “thousands of” tests, but... c’est la guerre...