diff --git a/tools/rosunit/src/rosunit/baretest.py b/tools/rosunit/src/rosunit/baretest.py index c9dd5bd7..e8b631fc 100644 --- a/tools/rosunit/src/rosunit/baretest.py +++ b/tools/rosunit/src/rosunit/baretest.py @@ -78,11 +78,16 @@ class BareTestCase(unittest.TestCase): else: self.test_name = test_name - self.args = [self.exe] + args + # invoke pyunit tests with python executable + if self.exe.endswith('.py'): + self.args = ['python', self.exe] + args + else: + self.args = [self.exe] + args + self.retry = retry self.time_limit = time_limit or BARE_TIME_LIMIT self.pmon = None - self.results = None + self.results = junitxml.Result(self.test_name) def setUp(self): self.pmon = pmon.start_process_monitor() @@ -459,3 +464,49 @@ executable permission. This is often caused by a bad launch-prefix."""%(msg, ' ' finally: self.stopped = True self.lock.release() + +def print_runner_summary(junit_results, runner_results, runner_name='ROSUNIT'): + """ + Print summary of rostest results to stdout. + """ + # we have two separate result objects, which can be a bit + # confusing. 'result' counts successful _running_ of tests + # (i.e. doesn't check for actual test success). The 'r' result + # object contains results of the actual tests. + + import cStringIO + buff = cStringIO.StringIO() + buff.write("[%s]"%(runner_name)+'-'*71+'\n\n') + for tc_result in junit_results.test_case_results: + buff.write(tc_result.description) + for tc_result in runner_results.failures: + buff.write("[%s][failed]\n"%tc_result[0]._testMethodName) + + buff.write('\nSUMMARY\n') + if runner_results.wasSuccessful() and (junit_results.num_errors + junit_results.num_failures) == 0: + buff.write("\033[32m * RESULT: SUCCESS\033[0m\n") + else: + buff.write("\033[1;31m * RESULT: FAIL\033[0m\n") + + # TODO: still some issues with the numbers adding up if tests fail to launch + + # number of errors from the inner tests, plus add in count for tests + # that didn't run properly ('result' object). + buff.write(" * TESTS: %s\n"%junit_results.num_tests) + num_errors = junit_results.num_errors+len(runner_results.errors) + if num_errors: + buff.write("\033[1;31m * ERRORS: %s\033[0m\n"%num_errors) + else: + buff.write(" * ERRORS: 0\n") + num_failures = junit_results.num_failures+len(runner_results.failures) + if num_failures: + buff.write("\033[1;31m * FAILURES: %s\033[0m\n"%num_failures) + else: + buff.write(" * FAILURES: 0\n") + + if runner_results.failures: + buff.write("\nERROR: The following tests failed to run:\n") + for tc_result in runner_results.failures: + buff.write(" * " +tc_result[0]._testMethodName + "\n") + + print buff.getvalue() diff --git a/tools/rosunit/src/rosunit/junitxml.py b/tools/rosunit/src/rosunit/junitxml.py index 0f6993e3..ac236ec4 100644 --- a/tools/rosunit/src/rosunit/junitxml.py +++ b/tools/rosunit/src/rosunit/junitxml.py @@ -411,7 +411,7 @@ def print_summary(junit_results): # object contains results of the actual tests. buff = cStringIO.StringIO() - buff.write("[ROSTEST]"+'-'*71+'\n\n') + buff.write("[ROSUNIT]"+'-'*71+'\n\n') for tc_result in junit_results.test_case_results: buff.write(tc_result.description) diff --git a/tools/rosunit/src/rosunit/rosunit_main.py b/tools/rosunit/src/rosunit/rosunit_main.py index 1f3f980a..324d1d36 100644 --- a/tools/rosunit/src/rosunit/rosunit_main.py +++ b/tools/rosunit/src/rosunit/rosunit_main.py @@ -47,7 +47,7 @@ from . import pmon from . core import xml_results_file, create_xml_runner from .junitxml import print_summary, Result -from .baretest import BareTestCase +from .baretest import BareTestCase, print_runner_summary _NAME = 'rosunit' @@ -70,41 +70,51 @@ def rosunitmain(): parser.add_option("-t", "--text", action="store_true", dest="text_mode", default=False, help="Run with stdout output instead of XML output") - parser.add_option("--bare-limit", metavar="TIME_LIMIT", - dest="bare_limit", default=60, - help="Set time limit for --bare executable") - parser.add_option("--bare-name", metavar="TEST_NAME", - dest="bare_name", default=None, - help="Test name for --bare executable") + parser.add_option("--time-limit", metavar="TIME_LIMIT", + dest="time_limit", default=60, + help="Set time limit for test") + parser.add_option("--name", metavar="TEST_NAME", + dest="test_name", default=None, + help="Test name") (options, args) = parser.parse_args() - if len(args) != 2: - parser.error("You must supply a test file and test name argument to rosunit.") + if len(args) != 1: + parser.error("You must supply a test file.") + + test_file = args[0] + + if options.test_name: + test_name = options.test_name + else: + test_name = os.path.basename(test_file) + if '.' in test_name: + test_name = test_name[:test_name.rfind('.')] + time_limit = float(options.time_limit) if options.time_limit else None - test_file, bare_name = args logger.info('rosunit starting with options %s, args %s'%(options, args)) # compute some common names we'll be using to generate test names and files pkg_dir, pkg = roslib.packages.get_dir_pkg(test_file) try: - time_limit = float(options.bare_limit) if options.bare_limit else None + results = Result('rosunit', 0, 0, 0) test_case = BareTestCase(test_file, [], \ retry=0, time_limit=time_limit, \ - test_name=options.bare_name) + test_name=test_name) suite = unittest.TestSuite() suite.addTest(test_case) if options.text_mode: result = unittest.TextTestRunner(verbosity=2).run(suite) else: - results_file = xml_results_file(pkg, bare_name, True) - xml_runner = create_xml_runner(pkg, bare_name, \ + results_file = xml_results_file(pkg, test_name, True) + # the is_rostest really just means "wrapper" + xml_runner = create_xml_runner(pkg, test_name, \ results_file=results_file, \ is_rostest=True) - result = xml_runner.run(suite) + runner_result = xml_runner.run(suite) finally: logger.info("calling pmon_shutdown") pmon.pmon_shutdown() @@ -113,18 +123,16 @@ def rosunitmain(): # summary is worthless if textMode is on as we cannot scrape .xml results results = test_case.results if not options.text_mode: - print "TODO: PRINT SUMMARY" - if 0: - print_summary(result) + print_runner_summary(results, runner_result) else: print "WARNING: overall test result is not accurate when --text is enabled" if logfile_name: print "rosunit log file is in %s"%logfile_name - if not result.wasSuccessful(): + if not runner_result.wasSuccessful(): sys.exit(1) - elif subtest_results.num_errors or subtest_results.num_failures: + elif results.num_errors or results.num_failures: sys.exit(2) if __name__ == '__main__':