-
Notifications
You must be signed in to change notification settings - Fork 36
Writing 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 witht/test_fixture.pl
- are stored under
t/unit_fixture/<test_name>.t
- test Perl classes that interact with the database
- are run using
t/test_fixture.pl
. - Unit fixture tests are based on the
SGN::Test::Fixture
class, which instantiates a fixture database and has accessors for different types of database handles and schemas.
- Integration tests test how different units cooperate
- In the Breedbase testing suite, there are two types of integration tests,
mech
tests andselenium
tests. - Integration tests are run using
t/test_fixture.pl
- 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
- 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
- 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
An introduction to the philosophy of testing in Perl can be found here.
- The test script lives in a folder "t/" in the root directory of the component (
perllib/t
,sgn/t
, etc). Inside the t/ directory, the first level of directories defines the type of test (unit
,unit_fixture
,unit_mech
, orselenium2
). In general, the subdirectories inside the different test type directories mirror the directory structure of the components. - 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.
- 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.
The main script to run tests is t/test_fixture.pl
in the sgn
repo. It creates a fixture database from the fixture dump, runs missing db patches on the fixture, starts a test server, and runs the tests. It bases the configuration on sgn_test.conf.
Some popular options include:
- --noserver Don't run the server
- --nocleanup Don't clean up the fixture database or logfile
- --noparallel Don't run in parallel mode
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;
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.
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...
}