Mercurial > cgi-bin > hgweb.cgi > tincan
diff run-tests @ 71:88adf10be709 draft
Add tests.
author | David Barts <n5jrn@me.com> |
---|---|
date | Mon, 15 Jul 2019 13:16:31 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/run-tests Mon Jul 15 13:16:31 2019 -0700 @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# Run our tests. Basically, these use the python unittest framework, but +# are organized into a directory tree containing test code and the server +# files to run the tests against. The tests are done by creating a local +# server on the specified port (default 8080) and issuing requests to it. +# +# Note that some of the test suites we run require the requests and/or +# Beautiful Soup libraries (these are not needed for running TInCan, only +# for testing it.) + +# I m p o r t s + +import os, sys +import importlib +import logging +import unittest +from argparse import ArgumentParser + +# V a r i a b l e s + +MYNAME = os.path.basename(sys.argv[0]) +TESTDIR = "tests" +FPREFIX = "suite_" +FILESDIR = "files" +FILESVAR = "files" +PORTVAR = "port" + +# F u n c t i o n s + +def is_test(d): + if not d.startswith(FPREFIX): + return False + return os.path.isdir(os.path.join(TESTDIR, d)) and os.path.isdir(os.path.join(TESTDIR, d, FILESDIR)) + +def is_subclass(a, b): + try: + return issubclass(a, b) + except TypeError: + return False + +# M a i n P r o g r a m + +# Parse arguments +parser = ArgumentParser(prog=sys.argv[0], usage="%(prog)s [options]") +parser.add_argument("-p", "--port", default=8080, help="port to use (default: 8080)") +args = parser.parse_args(sys.argv[1:]) + +# Reject attempts to run out of directory +if not os.path.isdir(TESTDIR): + sys.stderr.write("{0}: {1!r} - no such directory\n".format(MYNAME, TESTDIR)) + sys.exit(2) + +# Get the log file name and ensure the log file is cleared +from tests import LOGNAME, LOGGERNAME +open(LOGNAME, "w").close() + +# Make a logger object for ServerFixture to use +mylog = logging.getLogger(LOGGERNAME) +handler = logging.FileHandler(LOGNAME) +handler.setFormatter( + logging.Formatter(fmt="%(asctime)s - %(levelname)s: %(message)s")) +mylog.addHandler(handler) +mylog.setLevel(logging.INFO) + +# Locate all fixtures and operate on them +failures = 0 +fixtures = sorted(filter(is_test, os.listdir(TESTDIR))) +if not fixtures: + sys.stderr.write("{0}: warning - no fixtures found\n".format(MYNAME)) +for fixture in fixtures: + name = "{0}.{1}".format(TESTDIR, fixture) + sys.stderr.write("{0}: running {1} ...\n".format(MYNAME, name)) + module = importlib.import_module(name) + directory = os.path.join(TESTDIR, fixture, FILESDIR) + for i in dir(module): + v = getattr(module, i) + if is_subclass(v, unittest.TestCase): + setattr(v, FILESVAR, directory) + setattr(v, PORTVAR, args.port) + suite = unittest.defaultTestLoader.loadTestsFromModule(module) + result = unittest.TextTestRunner(verbosity=1).run(suite) + if result.wasSuccessful(): + sys.stderr.write("{0}: {1} passed\n".format(MYNAME, name)) + else: + sys.stderr.write("{0}: {1} failed\n".format(MYNAME, name)) + failures += 1 + +# AMF... +if failures: + sys.stderr.write("{0}: {1} suite{2} failed\n".format( + MYNAME, + failures, + "" if failures == 1 else "s")) + +sys.stdout.write("Note: server log output is in {0!r}.\n".format(LOGNAME)) +sys.exit(1 if failures else 0)