howto-testsuite.dxy

00001 /*      -*- mode: text; fill-column: 70; indent-tabs-mode: nil -*-
00002       $Id: howto-testsuite.dxy 6337 2006-02-28 18:26:26Z rjpeters $
00003 
00004                    ------------------------------------
00005                    iLab Neuromorphic Vision C++ Toolkit
00006                    ------------------------------------
00007 
00008                              Programmer Notes
00009                              ----------------
00010 
00011 */
00012 
00013 /*! \page howto-testsuite HOWTO add tests to the test suite
00014 
00015 <i>For the impatient: if you want to write low-level tests IN c++ OF
00016 your c++ code, start with the \ref whitebox-tests "whitebox tests"
00017 section; if you want to write high-level regression tests for existing
00018 executables, start with the \ref blackbox-tests "blackbox tests"
00019 section.</i>
00020 
00021 \note This HOWTO was originally written around svn revision 6562 of
00022 the toolkit, around March 2006; if you are reading this later and find
00023 discrepancies between this HOWTO and the latest code, please either:
00024 fix the HOWTO and commit a change back through svn, or post a comment
00025 to http://ilab.usc.edu/forum/ mentioning the problem.
00026 
00027 
00028 
00029 <!--############################################################-->
00030 <!--############################################################-->
00031 <!--############################################################-->
00032 
00033 \section introduction Introduction
00034 
00035 The files for the test suite all live in the <tt>tests/</tt>
00036 subdirectory; these include
00037 
00038 - perl modules (<tt>*.pm</tt> files) that implement the test suite
00039 framework,
00040 - perl scripts (<tt>*.pl</tt> files) that run the individual
00041 test suites,
00042 - input files for the various tests (in theory these should
00043 all go in <tt>tests/inputs/</tt>, but in practice some still sit
00044 directly in <tt>tests/</tt> for historical reasons), and
00045 - reference files for regression tests (in <tt>tests/ref</tt>).
00046 
00047 The test suite is split into two parts: one is the main test suite,
00048 and the other is the so-called testlong suite, so named because it
00049 contains tests that take much longer to run. The main test suite can
00050 be run with:
00051 \verbatim
00052 $ make test
00053 # OR
00054 $ cd tests && ./run_test_suite.pl
00055 \endverbatim
00056 
00057 Note that for a number of reasons, you <i>must</i> be sitting in the
00058 <tt>tests/</tt> directory in order for <tt>./run_test_suite.pl</tt> to
00059 work; that is, you can't be sitting in the top-level directory and
00060 call <tt>./tests/run_test_suite.pl</tt> (the main reason is that many
00061 of the tests use relative, not absolute, paths to refer to input and
00062 output files).
00063 
00064 Likewise, the testlong suite can be run with:
00065 \verbatim
00066 $ make testlong
00067 # OR
00068 $ cd tests && ./run_testlong_suite.pl
00069 \endverbatim
00070 
00071 Each of the <tt>./run_test_suite.pl</tt> and
00072 <tt>./run_testlong_suite.pl</tt> scripts are implemented with the
00073 <tt>testrun.pm</tt> perl module defined in <tt>tests</tt>; their job
00074 is essentially to run a bunch of individual test scripts and collect
00075 status information from each of those scripts. Scripts matching
00076 <tt>test_*.pl</tt> are run in the main test suite, and scripts
00077 matching <tt>testlong_*.pl</tt> are run in the testlong suite. The
00078 only condition on the individual test scripts is that they must emit a
00079 line of the form "MMM of NNN tests succeeded", where MMM and NNN are
00080 integers. Specifically, <tt>testrun.pm</tt> does that parsing with a
00081 block like the following:
00082 
00083 \verbatim
00084 if (/^([0-9]+) of ([0-9]+) tests succeeded/) {
00085   # increment counters
00086 }
00087 \endverbatim
00088 
00089 After running all the scripts and parsing the status lines emitted by
00090 each script, the test suite drivers print a status summary of all the
00091 scripts that were run, and exit with a status code that indicates the
00092 number of tests that failed (thus, as usual, 0 indicates success).
00093 
00094 \verbatim
00095 SUMMARY: ALL TESTS PASSED (267 of 267)
00096            1 of   1 tests succeeded (./test_Brain_whitebox.pl)
00097            7 of   7 tests succeeded (./test_Component_whitebox.pl)
00098            3 of   3 tests succeeded (./test_ImageEqual.pl)
00099          100 of 100 tests succeeded (./test_Image_whitebox.pl)
00100            1 of   1 tests succeeded (./test_Learn_whitebox.pl)
00101            7 of   7 tests succeeded (./test_LevelSpec_whitebox.pl)
00102           60 of  60 tests succeeded (./test_Pixels_whitebox.pl)
00103            8 of   8 tests succeeded (./test_Raster_whitebox.pl)
00104            6 of   6 tests succeeded (./test_ShapeEstimator_blackbox.pl)
00105           19 of  19 tests succeeded (./test_ezvision_blackbox.pl)
00106            4 of   4 tests succeeded (./test_mpeg2yuv_blackbox.pl)
00107            4 of   4 tests succeeded (./test_retina_blackbox.pl)
00108           19 of  19 tests succeeded (./test_scriptvision_blackbox.pl)
00109            2 of   2 tests succeeded (./test_sformat_whitebox.pl)
00110           17 of  17 tests succeeded (./test_vision_blackbox.pl)
00111            9 of   9 tests succeeded (./test_yuv2ppm_blackbox.pl)
00112 \endverbatim
00113 
00114 So, in theory, any script that emitted such a line could be integrated
00115 into the test suite. However, in practice, most tests fall into either
00116 the \ref blackbox-tests "blackbox" or \ref whitebox-tests "whitebox"
00117 category, and the job of writing a one of those kinds of test scripts
00118 is much easier if you use either the <tt>whitebox.pm</tt> or the
00119 <tt>blackbox.pm</tt> perl module.
00120 
00121 
00122 
00123 
00124 <!--############################################################-->
00125 <!--############################################################-->
00126 <!--############################################################-->
00127 
00128 \section whitebox-tests Whitebox tests
00129 
00130 Whitebox tests are so named because they inspect the inner workings of
00131 the code (rather than treating the code as a "black box"). So,
00132 whitebox tests are written in C++, using the TestSuite class, and are
00133 used to test the low-level workings of various C++
00134 classes.
00135 
00136 <!--############################################################-->
00137 
00138 \subsection whitebox-perl The whitebox.pm perl module
00139 
00140 Implementing a whitebox test program means writing a single C++ source
00141 file plus a tiny perl script that loads the whitebox perl module and
00142 uses that to drive the C++ program, like so:
00143 
00144 \verbatim
00145 #!/usr/bin/perl -w
00146 
00147 use invt_config;
00148 use whitebox;
00149 
00150 whitebox::run("$invt_config::exec_prefix/bin/whitebox-Image");
00151 \endverbatim
00152 
00153 Internally, that <tt>whitebox::run</tt> call first calls the whitebox
00154 c++ program with a <tt>--perlquery</tt> option to retrieve a list of
00155 available tests, and then loops over those tests, calling the c++
00156 program with a <tt>--run</tt> option for each test. Along the way,
00157 <tt>whitebox::run</tt> prints each test name and the success or
00158 failure status of running that test. If a test fails, the stderr from
00159 that test run is also printed.
00160 
00161 <!--############################################################-->
00162 
00163 \subsection whitebox-cxx The whitebox C++ program
00164 
00165 Writing the C++ implementation for a new whitebox test is much like
00166 writing any other new program for the toolkit. By convention, whitebox
00167 test sources live in <tt>src/TestSuite/</tt> and are named like
00168 <tt>whitebox-MyTestClass.C</tt>, for the whitebox tests of class
00169 <tt>MyTestClass</tt>. You can make a template for the source file like
00170 this:
00171 
00172 \verbatim
00173 $ ./devscripts/newclass.tcl src/TestSuite/whitebox-MyTestClass
00174 generated src/TestSuite/whitebox-MyTestClass.H
00175 generated src/TestSuite/whitebox-MyTestClass.C
00176 $ rm src/TestSuite/whitebox-MyTestClass.H       # you don't need the .H file
00177 \endverbatim
00178 
00179 Then you need to add a line to <tt>depoptions.in</tt> telling the
00180 dependency calculator how to build an executable from your new source
00181 file. You would want to add a line like this:
00182 
00183 \verbatim
00184 --exeformat testx , @source@TestSuite/whitebox-MyTestClass.C :@exec_prefix@/bin/whitebox-MyTestClass
00185 \endverbatim
00186 
00187 This line says
00188 - to make an executable named
00189 <tt>${exec_prefix}/bin/whitebox-MyTestClass</tt> (where
00190 <tt>${exec_prefix}</tt> is determined by the configure script; by
00191 default it is just <tt>./</tt>),
00192 - whose main function is found in
00193 <tt>src/TestSuite/whitebox-MyTestClass.C</tt>,
00194 - to link in all necessary object files and libraries indicated by
00195 following the <tt>#include</tt>s from that source file, and
00196 - to build that executable as part of <tt>make testx</tt> (itself part
00197 of <tt>make all</tt>).
00198 
00199 Inside the source file, you need the following to bring in the
00200 TestSuite class:
00201 
00202 \code
00203 #include "TestSuite/TestSuite.H"
00204 \endcode
00205 
00206 Then you can start writing tests. Let's look at some of the code from
00207 <tt>src/TestSuite/whitebox-Image.C</tt> as an example. First, let's
00208 look at a portion of the <tt>main()</tt> function:
00209 
00210 \code
00211 int main(int argc, const char** argv)
00212 {
00213   TestSuite suite;
00214 
00215   suite.ADD_TEST(Image_xx_type_convert_xx_1);
00216 
00217   suite.parseAndRun(argc, argv);
00218 
00219   return 0;
00220 }
00221 \endcode
00222 
00223 There are four lines within <tt>main()</tt> there:
00224 - the first line creates a <tt>TestSuite</tt> object which will handle
00225 the command-line options and run the tests;
00226 - the second line adds a test function to the test suite (more on that
00227 in a moment);
00228 - the third line handles the command-line options and proceeds
00229 accordingly;
00230 - finally we <tt>return 0</tt> -- even if a test fails, we still
00231 return 0, since the failure of the test is indicated through the
00232 program's stdout.
00233 
00234 The <tt>ADD_TEST</tt> line is actually a macro that calls
00235 <tt>TestSuite::addTest()</tt> with the address of the test function
00236 <tt>&Image_xx_type_convert_xx_1</tt> and the name of that function as
00237 a string, i.e. <tt>"Image_xx_type_convert_xx_1"</tt>. The idea is that
00238 the test name should have three parts, separated by <tt>_xx_</tt> (the
00239 <tt>whitebox.pm</tt> perl module will later clean up those ugly
00240 <tt>_xx_</tt> and convert them to <tt>--</tt>): first, the class name
00241 being tested, in this case <tt>Image</tt>; second, the name of the
00242 test or group of tests, in this case <tt>type_convert</tt>; third, the
00243 number of the test within its group, in this case <tt>1</tt>. A test
00244 function itself looks like this:
00245 
00246 \code
00247 void Image_xx_type_convert_xx_1(TestSuite& suite)
00248 {
00249   float array[4] = { -10.9, 3.2, 254.7, 267.3 };
00250 
00251   Image<float> f(array, 4, 1);
00252 
00253   Image<byte> b = f;
00254 
00255   REQUIRE_EQ((int)b.getVal(0), 0); // clamped
00256   REQUIRE_EQ((int)b.getVal(1), 3);
00257   REQUIRE_EQ((int)b.getVal(2), 254);
00258   REQUIRE_EQ((int)b.getVal(3), 255); // clamped
00259 }
00260 \endcode
00261 
00262 You can make as many test functions as you want; just be sure to
00263 <tt>ADD_TEST</tt> each of them within <tt>main()</tt>. Basically, you
00264 can do whatever you want within a test function, and along the way you
00265 call one or more of the <tt>REQUIRE</tt> macros to verify that things
00266 are as they should be. There are several varieties to choose from:
00267 
00268 \code
00269 REQUIRE_EQ(lhs, rhs);        // require (lhs == rhs)
00270 REQUIRE_EQFP(lhs, rhs, eps); // require (abs(lhs-rhs) < eps)
00271 REQUIRE(expr);               // require (expr == true)
00272 REQUIRE_NEQ(lhs, rhs);       // require (lhs != rhs)
00273 REQUIRE_LT(lhs, rhs);        // require (lhs < rhs)
00274 REQUIRE_LTE(lhs, rhs);       // require (lhs <= rhs)
00275 REQUIRE_GT(lhs, rhs);        // require (lhs > rhs)
00276 REQUIRE_GTE(lhs, rhs);       // require (lhs >= rhs)
00277 \endcode
00278 
00279 Each of these is a macro that actually calls back to
00280 <tt>TestSuite::require()</tt> or <tt>TestSuite::requireEq()</tt>.
00281 
00282 
00283 
00284 
00285 <!--############################################################-->
00286 <!--############################################################-->
00287 <!--############################################################-->
00288 
00289 \section blackbox-tests Blackbox tests
00290 
00291 Blackbox tests are so named because they test the external behavior of
00292 a program, treating it as a "black box", without requiring any
00293 knowledge of its inner workings (although you yourself may use such
00294 knowledge to help decide what tests will best exercise the program).
00295 
00296 <!--############################################################-->
00297 
00298 \subsection blackbox-perl The blackbox.pm perl module
00299 
00300 In our toolkit, the <tt>blackbox.pm</tt> perl module helps you
00301 implement what are essentially regression tests of executables in the
00302 toolkit. Unlike whitebox tests, where you write a dedicated piece of
00303 C++ code that implements the tests, with blackbox tests you typically
00304 have an existing program in place that already does something useful,
00305 and you just want to write some tests to verify that that program
00306 continues to behave as expected under a variety conditions (e.g.,
00307 different inputs, different command-line options). In some cases you
00308 may need to tweak an existing program slightly to make it more
00309 testable; for example:
00310 
00311 - if your program normally uses some randomness in its calculations,
00312 you'll want to have a command-line option to turn off that randomness
00313 for testing purposes, otherwise regression tests won't work
00314 
00315 - if your program normally sends its output to an onscreen window,
00316 you'll want to have an option to tell it to send that output to disk
00317 files instead (perhaps image files, or a text log file) so that you
00318 can easily compare the results of different program runs
00319 
00320 Once you have those elements in place, writing blackbox tests for you
00321 program is very easy. Let's look at
00322 <tt>tests/test_retina_blackbox.pl</tt> as an example. Each blackbox
00323 test script has three main parts. In practice, it's probably easiest
00324 to get going by copying an existing blackbox test script and then
00325 modifying the various segments to fit your needs, but for now let's
00326 step through each part. First, it should begin with the following to
00327 import the necessary modules:
00328 
00329 \verbatim
00330 #!/usr/bin/perl -w
00331 
00332 use strict;
00333 
00334 use blackbox;
00335 use invt_config;
00336 \endverbatim
00337 
00338 Second, the core of the test script is a local array of anonymous
00339 hashes, where each hash describes one test to be run; for example:
00340 
00341 \verbatim
00342 my @tests =
00343     (
00344 
00345      # ...
00346 
00347      {
00348          name  => 'bluecones--1',
00349          args  => ['-f', 'testpic001.pnm', 'retinaout.ppm'],
00350          files => ['retinaout.ppm'],
00351      },
00352 
00353      {
00354          name  => 'allopt--1',
00355          args  => ['-bf', 'testpic001.pnm', 'retinaout.ppm', 100, 100],
00356          files => ['retinaout.ppm'],
00357      },
00358      );
00359 \endverbatim
00360 
00361 More on that in a moment. The third and final part is a call to
00362 <tt>blackbox::run</tt> with the name of the executable to be tested,
00363 and our local array of test descriptors:
00364 
00365 \verbatim
00366 # Run the black box tests; note that the default executable can be
00367 # overridden from the command-line with "--executable"
00368 
00369 blackbox::run("$invt_config::exec_prefix/bin/retina", @tests);
00370 \endverbatim
00371 
00372 Once you have those elements in place, make sure the script is
00373 executable (with <tt>chmod +x</tt>), and then you have a
00374 fully-functioning test script. Each test script accepts a standard set
00375 of command-line options; you can try passing <tt>--help</tt> to see a
00376 description of the available options.
00377 
00378 <!--############################################################-->
00379 
00380 \subsection blackbox-test-descriptors Blackbox test descriptors
00381 
00382 Now let's return to the test descriptors in more detail. Here's one
00383 example again:
00384 
00385 \verbatim
00386 my @tests =
00387     (
00388      {
00389          name  => 'noopt--1',
00390          args  => ['testpic001.pnm', 'retinaout.ppm'],
00391          files => ['retinaout.ppm'],
00392      },
00393      );
00394 \endverbatim
00395 
00396 Each descriptor is an anonymous hash with three fields:
00397 
00398 - <tt>name</tt> is just a human readable name for the test, using double
00399 dashes to separate different parts of the test name
00400 - <tt>args</tt> is a list of command line options that should be
00401 passed to the test program for this test
00402 - <tt>files</tt> is a list of outputs that the test program is
00403 expected to produce, and which should be compared against stored
00404 reference files
00405 
00406 Internally, <tt>blackbox::run</tt> loops over all of the descriptors,
00407 and for each one, it runs the test program (<tt>bin/retina</tt> in
00408 this case) with the desired <tt>args</tt>, and then checks each output
00409 file in <tt>files</tt> against the corresponding reference file. If
00410 any test file doesn't match its reference file, then a detailed
00411 comparison of the two files is run and a summary of this comparison is
00412 printed.
00413 
00414 <!--############################################################-->
00415 
00416 \subsection blackbox-createref Adding a new test and creating the reference files
00417 
00418 When you first write a new test, obviously the reference files won't
00419 be there, but creating them the first time is very easy: just pass a
00420 <tt>--createref</tt> option to the test script. For example, let's add
00421 a new test to the <tt>test_retina_blackbox.pl</tt> test script, by
00422 adding the following to the <tt>@tests</tt> array:
00423 
00424 \verbatim
00425      {
00426          name  => 'allopt--2',
00427          args  => ['-bf', 'testpic001.pnm', 'retinaout.ppm', 90, 90],
00428          files => ['retinaout.ppm'],
00429      },
00430 \endverbatim
00431 
00432 Now let's try running the test script and see what happens:
00433 
00434 \verbatim
00435 $ ./test_retina_blackbox.pl
00436 
00437 ...
00438 
00439 =========================================================
00440 test 'allopt--1' ...
00441 
00442 running command '/path/to/saliency/bin/retina
00443         -bf
00444         testpic001.pnm
00445         retinaout.ppm
00446         100
00447         100'
00448 
00449 checking retinaout.ppm ... ok
00450 ---------------------------------------------------------
00451 
00452 =========================================================
00453 test 'allopt--2' ...
00454 
00455 running command '/path/to/saliency/bin/retina
00456         -bf
00457         testpic001.pnm
00458         retinaout.ppm
00459         90
00460         90'
00461 
00462 checking retinaout.ppm ... FAILED!
00463         reference file '/path/to/saliency/tests/ref/allopt--2--retinaout.ppm' is missing!
00464 Raster::ReadFrame: reading raster file: testpic001.pnm
00465 PnmParser::PnmParser: PBM Reading RGB Image: testpic001.pnm
00466 retinafilt::main: Using (90, 90) for fovea center
00467 retinafilt::showtypeof: type of pix0 is 6PixRGBIhE
00468 retinafilt::showtypeof: type of pix1 is 6PixRGBIhE
00469 retinafilt::showtypeof: type of pix1-pix0 is 6PixRGBIiE
00470 retinafilt::showtypeof: type of (pix1-pix0)*dd is 6PixRGBIfE
00471 retinafilt::showtypeof: type of pix0 + (pix1-pix0)*dd is 6PixRGBIfE
00472 retinafilt::showtypeof: type of (pix0 + (pix1-pix0)*dd) * blind is 6PixRGBIfE
00473 Raster::WriteFrame: writing raster file: retinaout.ppm
00474 
00475 test FAILED (command exited with exit status '1'):
00476 ---------------------------------------------------------
00477 
00478 4 of 5 tests succeeded
00479 
00480 FAILED tests:
00481         allopt--2
00482 \endverbatim
00483 
00484 OK, so it ran our test, but of course the test failed because it
00485 didn't find the reference file that we haven't created yet. Notice how
00486 the name of the missing reference file includes both the test name
00487 (<tt>allopt--2</tt>) and the test file name (<tt>retinaout.ppm</tt>):
00488 
00489 \verbatim
00490 /path/to/saliency/tests/ref/allopt--2--retinaout.ppm
00491 \endverbatim
00492 
00493 Now let's use the <tt>--match</tt> option, which lets you specify a
00494 regular expression to filter the names of tests to be run, to run just
00495 our new test:
00496 
00497 \verbatim
00498 $ ./test_retina_blackbox.pl --match allopt--2
00499 
00500 =========================================================
00501 test 'allopt--2' ...
00502 
00503 ...
00504 
00505 ---------------------------------------------------------
00506 
00507 0 of 1 tests succeeded
00508 
00509 FAILED tests:
00510         allopt--2
00511 \endverbatim
00512 
00513 You might also try the different <tt>--verbosity</tt> levels. The
00514 default level is 3, but you can use any of <tt>--verbosity</tt> -1, 0,
00515 1, 2, 3, or 4.
00516 
00517 So now let's create the missing reference file for our new test,
00518 using the <tt>--createref</tt> option:
00519 
00520 \verbatim
00521 $ ./test_retina_blackbox.pl --match allopt--2 --createref
00522 
00523 =========================================================
00524 test 'allopt--2' ...
00525 
00526 running command '/path/to/saliency/bin/retina
00527         -bf
00528         testpic001.pnm
00529         retinaout.ppm
00530         90
00531         90'
00532 
00533 checking retinaout.ppm ... (creating reference file from results) ok
00534 ---------------------------------------------------------
00535 
00536 1 of 1 tests succeeded
00537 \endverbatim
00538 
00539 Now, having created the reference file, if we re-run the test without
00540 <tt>--createref</tt>, it should pass:
00541 
00542 \verbatim
00543 $ ./test_retina_blackbox.pl --match allopt--2
00544 
00545 =========================================================
00546 test 'allopt--2' ...
00547 
00548 running command '/path/to/saliency/bin/retina
00549         -bf
00550         testpic001.pnm
00551         retinaout.ppm
00552         90
00553         90'
00554 
00555 checking retinaout.ppm ... ok
00556 ---------------------------------------------------------
00557 
00558 1 of 1 tests succeeded
00559 \endverbatim
00560 
00561 <!--############################################################-->
00562 
00563 \subsection blackbox-breakage When a reference/test comparison fails
00564 
00565 Now let's make the test break on purpose, to see what happens in that
00566 case. Let's change the args for our new test from this:
00567 
00568 \verbatim
00569          args  => ['-bf', 'testpic001.pnm', 'retinaout.ppm', 90, 90],
00570 \endverbatim
00571 
00572 to this:
00573 
00574 \verbatim
00575          args  => ['-bf', 'testpic001.pnm', 'retinaout.ppm', 91, 91],
00576 \endverbatim
00577 
00578 Now when we re-run the test, it fails, and prints a detailed
00579 comparison of how the test file differs from the reference file:
00580 
00581 \verbatim
00582 $ ./test_retina_blackbox.pl --match allopt--2
00583 
00584 =========================================================
00585 test 'allopt--2' ...
00586 
00587 running command '/home/rjpeters/projects/saliency/bin/retina
00588         -bf
00589         testpic001.pnm
00590         retinaout.ppm
00591         91
00592         91'
00593 
00594 checking retinaout.ppm ... FAILED check against '/home/rjpeters/projects/saliency/tests/ref/allopt--2--retinaout.ppm.gz'!
00595 
00596 comparison statistics:
00597         magnitude -25: 4 diffs
00598         magnitude -24: 9 diffs
00599         magnitude -23: 21 diffs
00600         magnitude -22: 14 diffs
00601         magnitude -21: 16 diffs
00602 
00603         ...
00604 
00605         magnitude 17: 10 diffs
00606         magnitude 18: 17 diffs
00607         magnitude 19: 10 diffs
00608         magnitude 20: 6 diffs
00609         num diff locations: 100334
00610         file1 length: 196623 bytes
00611         file2 length: 196623 bytes
00612         % of bytes differing: 51.0286182186214
00613         mean offset position: 103514.439880798
00614         num (file diff location % 2) == 0: 50251
00615         num (file diff location % 2) == 1: 50083
00616         num (file diff location % 3) == 0: 33460
00617         num (file diff location % 3) == 1: 33719
00618         num (file diff location % 3) == 2: 33155
00619         num (file diff location % 4) == 0: 25104
00620         num (file diff location % 4) == 1: 25066
00621         num (file diff location % 4) == 2: 25147
00622         num (file diff location % 4) == 3: 25017
00623         sum of file1 bytes (at diff locations): 11107399
00624         sum of file2 bytes (at diff locations): 11100625
00625         mean diff (at diff locations): -0.0675145015647736
00626         mean abs diff (at diff locations): 2.01233878844659
00627         mean diff (at all locations): -0.0344517172456935
00628         mean abs diff (at all locations): 1.02686867762164
00629         corrcoef: 0.999408
00630         md5sum (test) retinaout.ppm:
00631                 f7009f3aed7dd4270816b7512d4f89c8
00632         md5sum (ref)  allopt--2--retinaout.ppm:
00633                 4ffb20c024537328d692aff9309b020d
00634 Raster::ReadFrame: reading raster file: testpic001.pnm
00635 PnmParser::PnmParser: PBM Reading RGB Image: testpic001.pnm
00636 retinafilt::main: Using (91, 91) for fovea center
00637 retinafilt::showtypeof: type of pix0 is 6PixRGBIhE
00638 retinafilt::showtypeof: type of pix1 is 6PixRGBIhE
00639 retinafilt::showtypeof: type of pix1-pix0 is 6PixRGBIiE
00640 retinafilt::showtypeof: type of (pix1-pix0)*dd is 6PixRGBIfE
00641 retinafilt::showtypeof: type of pix0 + (pix1-pix0)*dd is 6PixRGBIfE
00642 retinafilt::showtypeof: type of (pix0 + (pix1-pix0)*dd) * blind is 6PixRGBIfE
00643 Raster::WriteFrame: writing raster file: retinaout.ppm
00644 
00645 test FAILED (command exited with exit status '256'):
00646 ---------------------------------------------------------
00647 
00648 0 of 1 tests succeeded
00649 
00650 FAILED tests:
00651         allopt--2
00652 \endverbatim
00653 
00654 In a real situation, you might be able to use the comparison stats to
00655 help diagnose why the test failed.
00656 
00657 
00658 <!--############################################################-->
00659 
00660 \subsection blackbox-replaceref Updating/replacing reference files
00661 
00662 If you are sure that the reason for the test failure is innocuous, or
00663 if you have deliberately changed your program to produce different
00664 results, you can interactively replace the reference files with the
00665 <tt>--interactive</tt> command-line option. If you give
00666 <tt>--interactive 1</tt>, you will just see the textual comparison of
00667 the two files; if you give <tt>--interactive 2</tt>, then two windows
00668 will also pop up showing the two image files for visual comparison
00669 (you need to have the program xv installed for that to work). Either
00670 way, you will be asked
00671 
00672 \verbatim
00673 replace previous reference file (y or n)?
00674 \endverbatim
00675 
00676 for each non-matching reference file.
00677 
00678 <b>Use great care with this option:</b> If you are absolutely sure you
00679 want to update ALL non-matching reference files, you can pass the
00680 <tt>--replaceref</tt> command-line option, which will
00681 NON-interactively replace all reference files. Be sure you know what
00682 changes are going to be made when you use this option.
00683 
00684 
00685 <!--############################################################-->
00686 
00687 \subsection blackbox-cmdline Blackbox command-line options
00688 
00689 Each blackbox test script comes equipped with a number of useful
00690 command-line options (some of these we've discussed already).
00691 
00692 
00693 
00694 \subsubsection blackbox-cmdline-creatref --createref
00695 
00696 With <tt>--createref</tt>, any reference files that are missing will
00697 be instantiated from the corresponding test file generated during the
00698 test run. The new reference file will either go in the default
00699 <tt>ref/</tt> directory or in the location specified by a
00700 <tt>--refdir</tt> option.
00701 
00702 
00703 
00704 \subsubsection blackbox-cmdline-executable --executable /path/to/alternate/exe
00705 
00706 Normally, the blackbox tests use the executable that is hardwired into
00707 the <tt>blackbox::run()</tt> call. However, it is possible to override
00708 that by specifying an alternate executable on the command line with
00709 the <tt>--executable</tt> option. This might be useful if you have an
00710 alternate build that has extra debugging or profiling built in.
00711 
00712 
00713 
00714 \subsubsection blackbox-cmdline-help --help
00715 
00716 This just lists the available command-line options along with a
00717 description of their behavior.
00718 
00719 
00720 
00721 \subsubsection blackbox-cmdline-interactive --interactive <level>
00722 
00723 As we discussed before, if a non-matching test file is found,
00724 <tt>--interactive</tt> will cause the test script to ask you whether
00725 to replace the reference file with the new test file. With
00726 <tt>--interactive 1</tt>, you'll just get the textual comparison stats
00727 of the two files; with <tt>--interactive 2</tt>, you'll also get a
00728 visual comparison of the two files if they are image files.
00729 
00730 
00731 
00732 \subsubsection blackbox-cmdline-list --list
00733 
00734 Then there is <tt>--list</tt>, which causes the driver to list the
00735 names of available tests. For example, let's use this option with the
00736 <tt>test_ezvision_blackbox.pl</tt> script in the <tt>tests/</tt>
00737 directory:
00738 
00739 \verbatim
00740 $ ./test_ezvision_blackbox.pl --list
00741 ez-trajectory--1
00742 ez-vc-type-entropy--1
00743 ez-vc-type-variance--1
00744 ez-raw-maps--1
00745 ez-feature-maps--1
00746 ez-conspicuity-maps--1
00747 ez-conspicuity-maps--2
00748 ez-saliency-map--1
00749 ez-saliency-map--2
00750 ez-saliency-map--3
00751 ez-saliency-map--4
00752 ez-foa--1
00753 ez-saliency-map--5
00754 ez-saliency-map--6
00755 ez-variable-rate--1
00756 ez-save-everything--1
00757 ez-junction-channels--2
00758 ez-target-mask--1
00759 ez-eye-trace--1
00760 \endverbatim
00761 
00762 
00763 
00764 \subsubsection blackbox-cmdline-list-refs --list-refs
00765 
00766 Also useful is <tt>--list-refs</tt>, which lists the full paths to all
00767 of the reference files involved in the test script. Again, you can
00768 combine this with <tt>--match</tt> to restrict the output to only
00769 matching tests. For example:
00770 
00771 \verbatim
00772 $ ./test_ezvision_blackbox.pl --list-refs --match foa
00773 /path/to/saliency/tests/ref/ez-foa--1--test.txt
00774 /path/to/saliency/tests/ref/ez-foa--1--T000000.pnm.gz
00775 /path/to/saliency/tests/ref/ez-foa--1--T000001.pnm.gz
00776 /path/to/saliency/tests/ref/ez-foa--1--T000002.pnm.gz
00777 /path/to/saliency/tests/ref/ez-foa--1--T000003.pnm.gz
00778 /path/to/saliency/tests/ref/ez-foa--1--T000004.pnm.gz
00779 \endverbatim
00780 
00781 Note how that list mirrors the <tt>files</tt> element of the
00782 <tt>ez-foa--1</tt> test descriptor in
00783 <tt>test_ezvision_blackbox.pl</tt>:
00784 
00785 \verbatim
00786      {
00787          name  => "ez-foa--1",
00788          args  => ['-ZT', '--boring-delay=FOREVER', '--boring-sm-mv=0.0',
00789                    '--nodisplay-eye', '--nodisplay-eye-traj',
00790                    '--textlog=test.txt', '--output-frames=0-4@250',
00791                    '--crop-foa=64x64',
00792                    '--in=raster:testpic001.pnm', '-+', '--out=ppm:'],
00793          files => ['test.txt', 'T000000.pnm', 'T000001.pnm',
00794                    'T000002.pnm', 'T000003.pnm', 'T000004.pnm'],
00795      },
00796 \endverbatim
00797 
00798 
00799 
00800 \subsubsection blackbox-cmdline-match --match <regexp>
00801 
00802 You might want to use the output of <tt>--list</tt> to help you select
00803 a <tt>--match</tt> pattern for a later test run; or in fact you can
00804 use <tt>--match</tt> along with <tt>--list</tt> to just list matching
00805 tests.
00806 
00807 \verbatim
00808 $ ./test_ezvision_blackbox.pl --list --match sal.*map
00809 ez-saliency-map--1
00810 ez-saliency-map--2
00811 ez-saliency-map--3
00812 ez-saliency-map--4
00813 ez-saliency-map--5
00814 ez-saliency-map--6
00815 \endverbatim
00816 
00817 
00818 
00819 \subsubsection blackbox-cmdline-nocomparison --nocomparison
00820 
00821 If you are interested in using the test suite for benchmarking, for
00822 example to compare run times with different build options, or across
00823 different machines, you may want to use the <tt>--nocomparison</tt>
00824 option. This option causes the script to run the program with all the
00825 same command-line option sets that it normally would, but all
00826 test/reference file comparisons are skipped. That way, the vast
00827 majority of the CPU time spent will be due to running the program
00828 itself (and not spent running cmp or diff on the test files). For
00829 example:
00830 
00831 \verbatim
00832 $ ./test_retina_blackbox.pl --match bluecones --nocomparison
00833 
00834 =========================================================
00835 test 'bluecones--1' ...
00836 
00837 running command '/path/to/saliency/bin/retina
00838         -f
00839         testpic001.pnm
00840         retinaout.ppm'
00841 
00842 checking retinaout.ppm ... comparison skipped for benchmarking
00843 ---------------------------------------------------------
00844 
00845 1 of 1 tests succeeded
00846 \endverbatim
00847 
00848 
00849 
00850 \subsubsection blackbox-cmdline-quit --quit-on-fail
00851 
00852 Normally, the blackbox test scripts run all the tests, continuing even
00853 some tests fail. If you want instead to have the script stop
00854 immediately if/when a test fails, you can pass <tt>--quit-on-fail</tt>
00855 on the command line.
00856 
00857 
00858 
00859 \subsubsection blackbox-cmdline-refdir --refdir /path/to/alternate/refdir
00860 
00861 If you are working on a system for which the test suite doesn't pass
00862 as-is (this is usually due to differences in floating-point operations
00863 between different CPUs and between different compiler versions), you
00864 may want to use the <tt>--refdir</tt> option to build an alternate set
00865 of reference files.
00866 
00867 Let's say you are working on such a machine, and you want to make some
00868 changes to the source code, and you want to make sure those changes
00869 don't break the test suite. Normally, you'd just make your changes and
00870 then run the test suite, but on this machine, the test suite doesn't
00871 even pass in the first place. To get around that, you can first build
00872 a fresh set of reference files by combining <tt>--refdir</tt> with
00873 <tt>--createref</tt>:
00874 
00875 \verbatim
00876 $ ./test_ezvision_blackbox.tcl --refdir my_alternate_ref --createref
00877 \endverbatim
00878 
00879 Then make your source code changes, then check that test suite still
00880 passes against the NEW set of reference files:
00881 
00882 \verbatim
00883 $ ./test_ezvision_blackbox.tcl --refdir my_alternate_ref
00884 \endverbatim
00885 
00886 This is already automated as part of <tt>make localtest</tt>, which
00887 will build a fresh reference set the first time it is run, and will
00888 test against that reference set on subsequent runs.
00889 
00890 
00891 
00892 \subsubsection blackbox-cmdline-replaceref --replaceref
00893 
00894 <b>Use great care with this option!</b> This will cause the test
00895 script to NON-interactively replace ALL non-matching reference files
00896 with the corresponding new test files. If you are going to use this
00897 option, it's generally a very good idea to first run the test script
00898 once without <tt>--replaceref</tt> so you can see exactly which
00899 reference files would be replaced.
00900 
00901 
00902 
00903 \subsubsection blackbox-cmdline-verbosity --verbosity <level>
00904 
00905 This option controls how much information is printed. Allowable levels
00906 are -1, 0, 1, 2, 3, 4:
00907 - -1 = no output, result of test run is given by
00908 exit status
00909 - 0 = just print a single summary line indicating
00910 how many tests succeeded
00911 - 1 = just print one line per test indicating
00912 success or failure
00913 - 2 = print the command-line options used for
00914 each test, and list each reference file that is
00915 tested
00916 - 3 = as before, but print detailed analysis of
00917 any failed reference tests
00918 - 4 = as before, but show the stdout+stderr from
00919 every command, even if the test doesn't fail
00920 
00921 */
Generated on Sun May 8 08:04:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3