Skip to content
Lukas Mueller edited this page Jun 12, 2021 · 28 revisions

How To Write Tests for Breedbase

Types of test

Unit tests

  • are stored in the sgn repo under t/unit/<class_name>.t
  • unit tests are tests that use and test Perl modules directly
  • unit tests can be only used for Perl modules that do not access the database
  • unit tests can be run with prove directly, or with t/test_fixture.pl

Unit Fixture tests

  • are stored under t/unit_fixture/<test_name>.t
  • test Perl classes that interact with the database
  • are run using t/test_fixture.pl.

Integration tests

  • Integration tests test how different units cooperate
  • In the Breedbase testing suite, there are two types of integration tests, mech tests and selenium tests.
  • Integration tests are run using t/test_fixture.pl

Mech tests

  • mech tests are based on Test::WWW::Mechanize
  • they can be used to test html or json generated by the server
  • mech tests do not run javascript code, only raw html/json can be tested
  • are run using t/test_fixture.pl

Selenium tests

  • based on Selenium2
  • Selenium will run a browser, and the tests will send requests to the browser.
  • Tests can access the Javascript interpolated structure of a web page
  • are run using t/test_fixture.pl

Old tests, no longer used

Validation tests
  • the old validation tests have been moved to t/legacy/validate. They should still be run, but require an intact SGN database (such as cxgn-test).
  • Tests that verify that web requests don't blow up (return a 500/etc) and that HTML/JSON/etc is valid #####Selenium version 1 tests
  • the old selenium tests have been moved to t/legacy/selenium

General info about writing tests in Perl

An introduction to the philosophy of testing in Perl can be found [http://search.cpan.org/dist/perl-5.10.0/lib/Test/Tutorial.pod here]

Some general guidelines:

  • The test script lives in a folder "t/" in the root directory of the component (perllib/t, sgn/t, etc). In general, the directory structure inside t/ mirrors the directory structure of the component.
  • The test script should be based on Test::More or Test::Most. Use Test::Warn if you have warnings. Use Test::Exception to test exceptions and die messages.
  • The test script does not take any parameters.
  • If the test needs file-based test data, include them in the t/data/
  • Use the diag function of Test::More to produce diagnostic output for when a test fails. However, do not produce this output for normal successful test runs!
  • The last argument to most testing functions is what to print when a test runs. Make this output useful for debugging failing tests.

Using the fixture

  • The test should be based on the database fixture, not a version of the production database (which is too large and unwieldy, and whose contents could change and the tests fail).
  • The fixture can be cloned from GitHub, https://github.com/solgenomics/fixture.git. It should be placed in the cxgn/ directory, where the t/test_fixture.pl script will look for it.
  • If you write a test using the fixture, but the fixture contains no corresponding data, the data needs to be added to the fixture (talk to Lukas).
  • test using the fixture have to be run using the t/test_fixture.pl script.

More on t/test_fixture.pl

How To Write Unit Tests

Unit tests should use Perl modules or other programs directly. If you need to do web requests, then you are writing an integration test, not a unit test.

You can create a new unit test and start editing it with the new_sgn_file command

new_sgn_file perl_unit_test.t mytest.t

where mytest.t will be the name of the newly created test. If you are testing SGN::Foo::Bar, then you should probably call the test t/SGN/Foo/Bar.t, so it is easy to find.

Here is an example:

#!perl
use strict;
use warnings;
use Test::More;

BEGIN {
  use_ok(  'The::Module::Being::Tested'  )
    or BAIL_OUT('could not include the module being tested');
}

# add your tests here

done_testing;

How to Write Unit tests using the Database Fixture

These tests should be in t/unit_fixture/. Some unit tests will require a database backend. It is preferable to use the database fixture as the test database. To use the fixture, include the following code at the beginning of your test script:

use lib 't/lib';
use SGN::Test::Fixture;

The SGN::Test::Fixture class makes available accessors for a database handle and different schema objects (Bio::Chado::Schema, SGN::Schema, and CXGN::Phenome::Schema), that will access the fixture. Note that you have to run the test script using t/test_fixture.pl to use the fixture features.

Perldoc of SGN::Test::Fixture has more details on its usage.

How To Write Integration Tests

All integration tests should be written based on the Selenium2 framework. The should be in t/selenium2/.

The Selenium2 framework has two components: The testing scripts and libraries, and the Selenium2 !WebDriver, which connects to the browser and needs to be running for the tests to work.

Download the WebDriver from [http://docs.seleniumhq.org/download/].

The recommended location for the web driver jar files are in ~/cxgn/selenium2/

Start the WebDriver using java -jar selenium-server-standalone-2.25.0.jar before starting the tests.

To write tests, first read the POD of SGN::Test::WWW::WebDriver int he sgn repo with

perldoc t/lib/SGN/Test/WWW/WebDriver.pm

Note that the preferred location for the actual test files is in ~/sgn/t/selenium2/

An example test may look like this:


use strict;
use lib 't/lib';
use Test::More 'tests'=>8;
use SGN::Test::WWW::WebDriver;

my $t = SGN::Test::WWW::WebDriver->new();

$t->while_logged_in_as("submitter", sub { 
    $t->get_ok('/breeders/manage_programs');
    
    my $new_bp_link = $t->find_element_ok('new_breeding_program_link', 'id', 'new breeding program link');

    $new_bp_link->click();

    my $breeding_program_name_input = $t->find_element_ok('new_breeding_program_name', 'id', 'find add breeding program name input');

    $breeding_program_name_input->send_keys('WEBTEST');

    #### and so forth...
}

Clone this wiki locally