#!/usr/bin/env python from os.path import dirname, basename from importlib import import_module import argparse import os import sys import glob import unittest import logging def load_tests_from_modules(names, template): loader = unittest.defaultTestLoader test_suites = [] for name in names: module = import_module(template.format(name=name)) test_suites.append(loader.loadTestsFromModule(module)) return test_suites def parse_args(available_bots): description = """ Script to run test_.py files in the zulip_bot/zulip_bots/bots/ directories. Running tests for all bots: ./test-bots Running tests for specific bots: ./test-bots define thesaurus Running tests for all bots excluding certain bots (the following command would run tests for all bots except the tests for xkcd and wikipedia bots): ./test-bots --exclude xkcd wikipedia """ parser = argparse.ArgumentParser(description=description) parser.add_argument('bots_to_test', metavar='bot', nargs='*', default=available_bots, help='specific bots to test (default is all)') parser.add_argument('--exclude', metavar='bot', nargs='*', default=[], help='bot(s) to exclude') return parser.parse_args() def main(): current_dir = os.path.dirname(os.path.abspath(__file__)) bots_dir = os.path.join(current_dir, '..', 'zulip_bots/zulip_bots/bots') glob_pattern = bots_dir + '/*/test_*.py' test_modules = glob.glob(glob_pattern) # get only the names of bots that have tests available_bots = map(lambda path: basename(dirname(path)), test_modules) options = parse_args(available_bots) bots_to_test = filter(lambda bot: bot not in options.exclude, options.bots_to_test) test_suites = load_tests_from_modules( bots_to_test, template='zulip_bots.bots.{name}.test_{name}' ) suite = unittest.TestSuite(test_suites) runner = unittest.TextTestRunner(verbosity=2) result = runner.run(suite) if result.failures or result.errors: sys.exit(1) if __name__ == '__main__': main()