view 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 source

#!/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)