From d73fa0f50fcf7db54746a26ed63e1fac68df1b07 Mon Sep 17 00:00:00 2001 From: "neiljp (Neil Pilgrim)" Date: Sun, 3 Jun 2018 15:01:39 -0700 Subject: [PATCH] test-bots: Add option to use pytest for running tests. * Add pytest to requirements.txt * Add pass-through option to run pytest in verbose mode * Use various default pytest options * Exclude merels bot for now --- requirements.txt | 1 + tools/test-bots | 65 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/requirements.txt b/requirements.txt index b425dcd..a22c3a9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ twine coverage>=4.4.1 pycodestyle==2.3.1 mock +pytest -e ./zulip -e ./zulip_bots -e ./zulip_botserver diff --git a/tools/test-bots b/tools/test-bots index ac2dbe5..6f48fd7 100755 --- a/tools/test-bots +++ b/tools/test-bots @@ -9,6 +9,7 @@ import argparse import glob import unittest from unittest import TestCase, TestSuite +import pytest def parse_args(): description = """ @@ -50,6 +51,14 @@ the tests for xkcd and wikipedia bots): default=False, action="store_true", help="whether to exit if a bot has tests which won't run due to no __init__.py") + parser.add_argument('--pytest', '-p', + default=False, + action='store_true', + help="run tests with pytest") + parser.add_argument('--verbose', '-v', + default=False, + action='store_true', + help='show verbose output (with pytest)') return parser.parse_args() @@ -80,28 +89,44 @@ def main(): bots_to_test = filter(lambda bot: bot not in options.exclude, specified_bots) - # Codecov seems to work only when using loader.discover. It failed to - # capture line executions for functions like loader.loadTestFromModule - # or loader.loadTestFromNames. - top_level = "zulip_bots/zulip_bots/bots/" - loader = unittest.defaultTestLoader - test_suites = [] - for name in bots_to_test: - try: - test_suites.append(loader.discover(top_level + name, top_level_dir=top_level)) - except ImportError as exception: - print(exception) - print("This likely indicates that you need a '__init__.py' file in your bot directory.") - if options.error_on_no_init: - sys.exit(1) + if options.pytest: + excluded_bots = ['merels'] + pytest_bots_to_test = sorted([bot for bot in bots_to_test if bot not in excluded_bots]) + pytest_options = [ + '-s', # show output from tests; this hides the progress bar though + '-x', # stop on first test failure + '--ff', # runs last failure first + ] + pytest_options += (['-v'] if options.verbose else []) + os.chdir(bots_dir) + result = pytest.main(pytest_bots_to_test + pytest_options) + if result != 0: + sys.exit(1) + failures = False + else: + # Codecov seems to work only when using loader.discover. It failed to + # capture line executions for functions like loader.loadTestFromModule + # or loader.loadTestFromNames. + top_level = "zulip_bots/zulip_bots/bots/" + loader = unittest.defaultTestLoader + test_suites = [] + for name in bots_to_test: + try: + test_suites.append(loader.discover(top_level + name, top_level_dir=top_level)) + except ImportError as exception: + print(exception) + print("This likely indicates that you need a '__init__.py' file in your bot directory.") + if options.error_on_no_init: + sys.exit(1) - suite = unittest.TestSuite(test_suites) - runner = unittest.TextTestRunner(verbosity=2) - result = runner.run(suite) - if result.failures or result.errors: - sys.exit(1) + suite = unittest.TestSuite(test_suites) + runner = unittest.TextTestRunner(verbosity=2) + result = runner.run(suite) + failures = result.failures + if failures or result.errors: + sys.exit(1) - if not result.failures and options.coverage: + if not failures and options.coverage: cov.stop() cov.data_suffix = False # Disable suffix so that filename is .coverage cov.save()