Mercurial > cgi-bin > hgweb.cgi > tincan
comparison run-tests @ 71:88adf10be709 draft
Add tests.
author | David Barts <n5jrn@me.com> |
---|---|
date | Mon, 15 Jul 2019 13:16:31 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
70:a78c74c73d98 | 71:88adf10be709 |
---|---|
1 #!/usr/bin/env python3 | |
2 # Run our tests. Basically, these use the python unittest framework, but | |
3 # are organized into a directory tree containing test code and the server | |
4 # files to run the tests against. The tests are done by creating a local | |
5 # server on the specified port (default 8080) and issuing requests to it. | |
6 # | |
7 # Note that some of the test suites we run require the requests and/or | |
8 # Beautiful Soup libraries (these are not needed for running TInCan, only | |
9 # for testing it.) | |
10 | |
11 # I m p o r t s | |
12 | |
13 import os, sys | |
14 import importlib | |
15 import logging | |
16 import unittest | |
17 from argparse import ArgumentParser | |
18 | |
19 # V a r i a b l e s | |
20 | |
21 MYNAME = os.path.basename(sys.argv[0]) | |
22 TESTDIR = "tests" | |
23 FPREFIX = "suite_" | |
24 FILESDIR = "files" | |
25 FILESVAR = "files" | |
26 PORTVAR = "port" | |
27 | |
28 # F u n c t i o n s | |
29 | |
30 def is_test(d): | |
31 if not d.startswith(FPREFIX): | |
32 return False | |
33 return os.path.isdir(os.path.join(TESTDIR, d)) and os.path.isdir(os.path.join(TESTDIR, d, FILESDIR)) | |
34 | |
35 def is_subclass(a, b): | |
36 try: | |
37 return issubclass(a, b) | |
38 except TypeError: | |
39 return False | |
40 | |
41 # M a i n P r o g r a m | |
42 | |
43 # Parse arguments | |
44 parser = ArgumentParser(prog=sys.argv[0], usage="%(prog)s [options]") | |
45 parser.add_argument("-p", "--port", default=8080, help="port to use (default: 8080)") | |
46 args = parser.parse_args(sys.argv[1:]) | |
47 | |
48 # Reject attempts to run out of directory | |
49 if not os.path.isdir(TESTDIR): | |
50 sys.stderr.write("{0}: {1!r} - no such directory\n".format(MYNAME, TESTDIR)) | |
51 sys.exit(2) | |
52 | |
53 # Get the log file name and ensure the log file is cleared | |
54 from tests import LOGNAME, LOGGERNAME | |
55 open(LOGNAME, "w").close() | |
56 | |
57 # Make a logger object for ServerFixture to use | |
58 mylog = logging.getLogger(LOGGERNAME) | |
59 handler = logging.FileHandler(LOGNAME) | |
60 handler.setFormatter( | |
61 logging.Formatter(fmt="%(asctime)s - %(levelname)s: %(message)s")) | |
62 mylog.addHandler(handler) | |
63 mylog.setLevel(logging.INFO) | |
64 | |
65 # Locate all fixtures and operate on them | |
66 failures = 0 | |
67 fixtures = sorted(filter(is_test, os.listdir(TESTDIR))) | |
68 if not fixtures: | |
69 sys.stderr.write("{0}: warning - no fixtures found\n".format(MYNAME)) | |
70 for fixture in fixtures: | |
71 name = "{0}.{1}".format(TESTDIR, fixture) | |
72 sys.stderr.write("{0}: running {1} ...\n".format(MYNAME, name)) | |
73 module = importlib.import_module(name) | |
74 directory = os.path.join(TESTDIR, fixture, FILESDIR) | |
75 for i in dir(module): | |
76 v = getattr(module, i) | |
77 if is_subclass(v, unittest.TestCase): | |
78 setattr(v, FILESVAR, directory) | |
79 setattr(v, PORTVAR, args.port) | |
80 suite = unittest.defaultTestLoader.loadTestsFromModule(module) | |
81 result = unittest.TextTestRunner(verbosity=1).run(suite) | |
82 if result.wasSuccessful(): | |
83 sys.stderr.write("{0}: {1} passed\n".format(MYNAME, name)) | |
84 else: | |
85 sys.stderr.write("{0}: {1} failed\n".format(MYNAME, name)) | |
86 failures += 1 | |
87 | |
88 # AMF... | |
89 if failures: | |
90 sys.stderr.write("{0}: {1} suite{2} failed\n".format( | |
91 MYNAME, | |
92 failures, | |
93 "" if failures == 1 else "s")) | |
94 | |
95 sys.stdout.write("Note: server log output is in {0!r}.\n".format(LOGNAME)) | |
96 sys.exit(1 if failures else 0) |