source: pyyaml/trunk/tests/lib/test_appliance.py @ 330

Revision 330, 5.1 KB checked in by xi, 5 years ago (diff)

Share data files between Py2 and Py3 test suites.

Line 
1
2import sys, os, os.path, types, traceback, pprint
3
4DATA = 'tests/data'
5
6def find_test_functions(collections):
7    if not isinstance(collections, list):
8        collections = [collections]
9    functions = []
10    for collection in collections:
11        if not isinstance(collection, dict):
12            collection = vars(collection)
13        keys = collection.keys()
14        keys.sort()
15        for key in keys:
16            value = collection[key]
17            if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'):
18                functions.append(value)
19    return functions
20
21def find_test_filenames(directory):
22    filenames = {}
23    for filename in os.listdir(directory):
24        if os.path.isfile(os.path.join(directory, filename)):
25            base, ext = os.path.splitext(filename)
26            if base.endswith('-py3'):
27                continue
28            filenames.setdefault(base, []).append(ext)
29    filenames = filenames.items()
30    filenames.sort()
31    return filenames
32
33def parse_arguments(args):
34    if args is None:
35        args = sys.argv[1:]
36    verbose = False
37    if '-v' in args:
38        verbose = True
39        args.remove('-v')
40    if '--verbose' in args:
41        verbose = True
42    if 'YAML_TEST_VERBOSE' in os.environ:
43        verbose = True
44    include_functions = []
45    if args:
46        include_functions.append(args.pop(0))
47    if 'YAML_TEST_FUNCTIONS' in os.environ:
48        include_functions.extend(os.environ['YAML_TEST_FUNCTIONS'].split())
49    include_filenames = []
50    include_filenames.extend(args)
51    if 'YAML_TEST_FILENAMES' in os.environ:
52        include_filenames.extend(os.environ['YAML_TEST_FILENAMES'].split())
53    return include_functions, include_filenames, verbose
54
55def execute(function, filenames, verbose):
56    if hasattr(function, 'unittest_name'):
57        name = function.unittest_name
58    else:
59        name = function.func_name
60    if verbose:
61        sys.stdout.write('='*75+'\n')
62        sys.stdout.write('%s(%s)...\n' % (name, ', '.join(filenames)))
63    try:
64        function(verbose=verbose, *filenames)
65    except Exception, exc:
66        info = sys.exc_info()
67        if isinstance(exc, AssertionError):
68            kind = 'FAILURE'
69        else:
70            kind = 'ERROR'
71        if verbose:
72            traceback.print_exc(limit=1, file=sys.stdout)
73        else:
74            sys.stdout.write(kind[0])
75            sys.stdout.flush()
76    else:
77        kind = 'SUCCESS'
78        info = None
79        if not verbose:
80            sys.stdout.write('.')
81    sys.stdout.flush()
82    return (name, filenames, kind, info)
83
84def display(results, verbose):
85    if results and not verbose:
86        sys.stdout.write('\n')
87    total = len(results)
88    failures = 0
89    errors = 0
90    for name, filenames, kind, info in results:
91        if kind == 'SUCCESS':
92            continue
93        if kind == 'FAILURE':
94            failures += 1
95        if kind == 'ERROR':
96            errors += 1
97        sys.stdout.write('='*75+'\n')
98        sys.stdout.write('%s(%s): %s\n' % (name, ', '.join(filenames), kind))
99        if kind == 'ERROR':
100            traceback.print_exception(file=sys.stdout, *info)
101        else:
102            sys.stdout.write('Traceback (most recent call last):\n')
103            traceback.print_tb(info[2], file=sys.stdout)
104            sys.stdout.write('%s: see below\n' % info[0].__name__)
105            sys.stdout.write('~'*75+'\n')
106            for arg in info[1].args:
107                pprint.pprint(arg, stream=sys.stdout)
108        for filename in filenames:
109            sys.stdout.write('-'*75+'\n')
110            sys.stdout.write('%s:\n' % filename)
111            data = open(filename, 'rb').read()
112            sys.stdout.write(data)
113            if data and data[-1] != '\n':
114                sys.stdout.write('\n')
115    sys.stdout.write('='*75+'\n')
116    sys.stdout.write('TESTS: %s\n' % total)
117    if failures:
118        sys.stdout.write('FAILURES: %s\n' % failures)
119    if errors:
120        sys.stdout.write('ERRORS: %s\n' % errors)
121
122def run(collections, args=None):
123    test_functions = find_test_functions(collections)
124    test_filenames = find_test_filenames(DATA)
125    include_functions, include_filenames, verbose = parse_arguments(args)
126    results = []
127    for function in test_functions:
128        if include_functions and function.func_name not in include_functions:
129            continue
130        if function.unittest:
131            for base, exts in test_filenames:
132                if include_filenames and base not in include_filenames:
133                    continue
134                filenames = []
135                for ext in function.unittest:
136                    if ext not in exts:
137                        break
138                    filenames.append(os.path.join(DATA, base+ext))
139                else:
140                    skip_exts = getattr(function, 'skip', [])
141                    for skip_ext in skip_exts:
142                        if skip_ext in exts:
143                            break
144                    else:
145                        result = execute(function, filenames, verbose)
146                        results.append(result)
147        else:
148            result = execute(function, [], verbose)
149            results.append(result)
150    display(results, verbose=verbose)
151
Note: See TracBrowser for help on using the repository browser.