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 */