testdriver-after-test.inc
Go to the documentation of this file.
1 // ===========================================================================
2 // Copyright (c) Insight Software Consortium
3 // Copyright (c) 2011-2012 University of Pennsylvania
4 // Copyright (c) 2013-2016 Andreas Schuh
5 // All rights reserved.
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0.txt
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 // ===========================================================================
19 
20 /**
21  * @file testdriver-after-test.inc
22  * @brief Default implementation of test driver.
23  *
24  * This file is included in the test driver generated by the CMake command
25  * <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:create_test_sourcelist">
26  * create_test_sourcelist()</a> directly after the call to the test main function.
27  * It performs regression testing if requested.
28  *
29  * This file is a modified version of the itkTestDriverBeforeTest.inc file
30  * which is part of the TestKernel module of the ITK 4 project.
31  */
32 
33 //int main(int, char*)
34 //{
35  // #include <sbia/basis/testdriver-before-test.inc> -> try {
36  // [...]
37 
38  // revert redirection of output
39  if (oldcoutbuf) {
40  cout.rdbuf(oldcoutbuf);
41  redirectstream.close();
42  }
43  // perform regression tests of output image(s)
44  if (result == 0) {
45  if (!regression_tests.empty() && verbose.getValue() > 0) {
46  cout << "Performing regression tests" << endl;
47  }
48  for (size_t i = 0; i < regression_tests.size(); i++) {
49  const char* test_file = regression_tests[i].test_file.c_str();
50  const char* baseline_file = regression_tests[i].baseline_file.c_str();
51  if (regression_tests[i].method == BINARY_DIFF) {
52  int status = binary_diff(test_file, baseline_file);
53  if (status == -1) {
54  cerr << "No test output file found given file path " << test_file << "!" << endl;
55  status = 1;
56  } else if (status == -2) {
57  cerr << "No baseline file found given file path " << baseline_file << "!" << endl;
58  status = 1;
59  } else if (status != 0) {
60  cerr << "Files " << test_file << " and " << baseline_file << " differ!" << endl;
61  }
62  result += status;
63  } else if (regression_tests[i].method == DIFF_LINES) {
64  int status = text_diff_lines(test_file, baseline_file, regression_tests[i].max_number_of_differences);
65  if (status == -1) {
66  cerr << "No test output file found given file path " << test_file << "!" << endl;
67  status = 1;
68  } else if (status == -2) {
69  cerr << "No baseline file found given file path " << baseline_file << "!" << endl;
70  status = 1;
71  } else if (status != 0) {
72  cerr << "Files " << test_file << " and " << baseline_file << " differ by more than the allowed " << regression_tests[i].max_number_of_differences << " lines!" << endl;
73  }
74  result += status;
75  } else if (regression_tests[i].method == COMPARE_IMAGES) {
76  vector<string> baseline_files = get_baseline_filenames(baseline_file);
77  string bestmatch = baseline_file;
78  int beststatus = numeric_limits<int>::max();
79  if (baseline_files.empty()) {
80  bestmatch += " not found";
81  cerr << "No baseline images found given file path " << baseline_file << "!" << endl;
82  } else {
83  for (size_t j = 0; j < baseline_files.size(); j++) {
84  int status = image_regression_test(
85  test_file,
86  baseline_files[j].c_str(),
91  if (status < beststatus) {
92  bestmatch = baseline_files[j];
93  beststatus = status;
94  }
95  if (beststatus == 0) {
96  // perfect test result
97  break;
98  }
99  }
100  // if the best we can do still has errors...
101  if (beststatus != 0) {
103  test_file,
104  baseline_files[0].c_str(),
109  1); // ...generate error images
110  }
111  }
112  // output the matching baseline for submission to the dashboard
113  cout << "<DartMeasurement name=\"BaselineImageName\" type=\"text/string\">";
114  cout << os::path::basename(bestmatch);
115  cout << "</DartMeasurement>" << std::endl;
116  result += beststatus;
117  } else {
118  cerr << "Invalid test method: " << regression_tests[i].method << "! Check testdriver implementation." << endl;
119  }
120  }
121  // empty current working directory
122  if (clean_cwd_after_test.getValue()) {
123  os::emptydir(os::getcwd().c_str());
124  }
125  }
126 
127  // catch any exceptions
128  } catch (const exception& e) {
129  cerr << "Test driver caught an exception:\n";
130  cerr << e.what() << "\n";
131  result = -1;
132  } catch (...) {
133  cerr << "Test driver caught an unknown exception!!!\n";
134  result = -1;
135  }
136 //} end of main()
SwitchArg orientation_insensitive("", "orientation-insensitive", "Allow the test and baseline images to have different orientation." " When this option is given, the orientation of both images is made" " identical before they are compared. It is suitable if the test" " and baseline images are simply stored with different orientation," " but with proper orientation information in the file header.")
std::string getcwd()
Get absolute path of the (current) working directory.
Definition: os.cxx:47
int text_diff_lines(const char *testfile, const char *baseline, unsigned int max_number_of_differences=0)
Compare two text files line by line.
Definition: testdriver.hxx:230
DoubleArg intensity_tolerance("", "intensity-tolerance", "The accepted maximum difference between image intensities" " to use for the following regression tests." " (default: 2.0)", false, 2.0, "<float>", true)
bool emptydir(const std::string &path)
Remove files and directories from directory.
Definition: os.cxx:238
std::string basename(const std::string &path)
Get file name.
Definition: path.cxx:273
UIntArg max_number_of_differences("", "max-number-of-differences", "When comparing images specified with the following --compare option(s)," " allow the given number of image elements to differ.", false, 0, "<n>", true)
streambuf * oldcoutbuf
UIntArg tolerance_radius("", "tolerance-radius", "At most one image element in the neighborhood specified by the" " given radius has to fulfill the criteria of the following" " regression tests", false, 0, "<int>", true)
MultiSwitchArg verbose("v", "verbose", "Increase verbosity of output messages.", false)
int binary_diff(const char *testfile, const char *baseline)
Compare two files byte by byte.
Definition: testdriver.hxx:189
int image_regression_test(const char *imagefile, const char *baseline, double intensity_tolerance=2.0, unsigned int max_number_of_differences=0, unsigned int tolerance_radius=0, bool orientation_insensitive=false, int report=0)
Compare output image to baseline image.
Definition: testdriver.hxx:299
SwitchArg clean_cwd_after_test("", "clean-cwd-after", "Request the removal of all files and directories from the current" " working directory after the successful execution of the test." " This option is in particular useful if the test writes any results" " to the current working directory.", false)
vector< string > get_baseline_filenames(string filename_template)
Generate list of names of baseline files from a given template filename.
vector< RegressionTest > regression_tests
Container storing added regression tests.
Definition: testdriver.h:132