source: anuga_core/source/anuga/test_all.py @ 6718

Last change on this file since 6718 was 6718, checked in by rwilson, 15 years ago

Replace 'ANY' key with 'RETURN' - raw_input() waits for ENTER.

File size: 6.5 KB
RevLine 
[3464]1"""Regression testing framework
2This module will search for scripts in the same directory named
3test_*.py.  Each such script should be a test suite that tests a
4module through PyUnit. This script will aggregate all
5found test suites into one big test suite and run them all at once.
6"""
7
8# Author: Mark Pilgrim
9# Modified by Ole Nielsen
10
11import unittest
12import os
13import sys
[4414]14import tempfile
[6220]15import time
16import anuga.utilities.system_tools as aust
[3464]17
18
19#List files that should be excluded from the testing process.
20#E.g. if they are known to fail and under development
[3573]21exclude_files = []
[4796]22
[6086]23# Directories that should not be searched for test files.
[6218]24exclude_dirs = ['pypar_dist',                        # Special requirements
25                '.svn',                              # subversion
26                'props', 'wcprops', 'prop-base', 'text-base', 'tmp']
[4796]27
[3464]28
[6218]29##
30# @brief List a string sequence on the screen in columns.
31# @param names Sequence of strings to list.
32# @param func Function to apply to each string in sequence.
33# @param col_width Force columns to this width (default calculated).
34# @param page_width Set displayable page width to this (default 132).
35def list_names(names, func=None, col_width=None, page_width=None):
36    # set defaults
37    p_width = page_width                # set page width
38    if p_width is None:
39        p_width = 132                   # default page width
[3464]40
[6218]41    c_width = col_width                 # set column width
42    if c_width is None:
43        c_width = 0
44        for name in names:
45            if func:
46                name = func(name)
47            c_width = max(c_width, len(name))
48        c_width += 2                    # padding between columns
[6086]49
[6218]50    # calculate number of columns allowed
51    max_columns = int(p_width / c_width)
52
53    # print columns
54    column = 0
55    for name in names:
56        if func:
57            name = func(name)
58        print '%-*s' % (c_width, name),
59        column += 1
60        if column >= max_columns:
61            column = 0
62            print
63
64    # if last line not finished, end it here
65    if column > 0:
66        print
67
68
69##
70# @brief Get 'test_*.py' files and paths to directories.
71# @param path Path to directory to start walk in.
72# @return A tuple (<files>, <dirs>).
73# @note Don't include any files in and below forbidden directories.
[3464]74def get_test_files(path):
[6218]75    walk = os.walk(path)
[3464]76
77    test_files = []
78    path_files = []
79
[6218]80    for (dirpath, dirnames, filenames) in walk:
81        # exclude forbidden directories
82        for e_dir in exclude_dirs:
83            try:
84                dirnames.remove(e_dir)
85            except ValueError:
86                pass
[6086]87
[6218]88        # check for test_*.py files
89        for filename in filenames:
90            if filename.startswith('test_') and filename.endswith('.py'):
91                test_files.append(filename)
92                if dirpath not in path_files:
93                    path_files.append(dirpath)
94
[4804]95    return test_files, path_files
[3464]96
97
[4414]98def regressionTest(test_verbose=False):
[6218]99    # start off with where we are
[3464]100    path = os.getcwd()
[6218]101    print
102    print 'Testing path: %s' % path
103
104    # explain what we are doing
105    print
106    print "The following directories will be skipped over:"
107    exclude_dirs.sort()
108    list_names(exclude_dirs)
109
110    # get all test_*.py and enclosing directories
[3464]111    test_files, path_files = get_test_files(path)
[4804]112
[3464]113    files = [x for x in test_files if not x == 'test_all.py']
[6218]114    files.sort()        # Ensure same order on all platforms
[4804]115
[4461]116    print
[6215]117    print 'Paths searched:'
[6218]118    list_names(path_files, os.path.basename)
119
[6215]120    print   
[6218]121    print 'Files tested:'
122    list_names(files)
[6220]123    print
[6215]124
[6218]125    # update system path with found paths
126    for path in path_files:
127        sys.path.append(path)
128   
129    # exclude files that we can't handle
130    for file in exclude_files:
131        print 'WARNING: File '+ file + ' to be excluded from testing'
132        try:
133            files.remove(file)
134        except ValueError, e:
135            msg = 'File "%s" was not found in test suite.\n' % file
136            msg += 'Original error is "%s"\n' % e
137            msg += 'Perhaps it should be removed from exclude list?'
138            raise Exception, msg
[3464]139
[6218]140    # import all test_*.py files
141    # NOTE: This implies that test_*.py files MUST HAVE UNIQUE NAMES!
[3464]142    filenameToModuleName = lambda f: os.path.splitext(f)[0]
143    moduleNames = map(filenameToModuleName, files)
144    modules = map(__import__, moduleNames)
[6086]145
[3464]146    # Fix up the system path
147    for file in path_files:
148        sys.path.remove(file)
[6086]149
[6218]150    # bundle up all the tests
[3464]151    load = unittest.defaultTestLoader.loadTestsFromModule
[4414]152    testCaseClasses = map(load, modules)
[4418]153
[4414]154    if test_verbose is True:
[4415]155        # Test the code by setting verbose to True.
156        # The test cases have to be set up for this to work.
157        # See test data manager for an example.
[4414]158        for test_suite in testCaseClasses:
159            for tests in test_suite._tests:
[4418]160                # tests is of class TestSuite
161                if len(tests._tests) > 1:
[4414]162                    # these are the test functions
163                    try:
[6086]164                        # Calls class method set_verbose in test case classes
[4414]165                        tests._tests[0].set_verbose()
166                    except:
[6086]167                        pass                # No all classes have set_verbose
[6218]168
[4414]169    return unittest.TestSuite(testCaseClasses)
[3464]170
[6086]171
[6218]172##
173# @brief Check that the environment is sane.
174# @note Stops here if there is an error.
[4763]175def check_anuga_import():
176    try:
177        # importing something that loads quickly
178        import anuga.utilities.anuga_exceptions
179    except ImportError:
180        print "Python cannot import ANUGA module."
181        print "Check you have followed all steps of its installation."
[6086]182        import sys
183        sys.exit()
[4763]184
[6086]185
[3464]186if __name__ == '__main__':
[4763]187    check_anuga_import()
[6086]188
[4414]189    if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V':
190        test_verbose = True
[6086]191        saveout = sys.stdout
[4414]192        filename = ".temp"
193        fid = open(filename, 'w')
194        sys.stdout = fid
195    else:
[6086]196        test_verbose = False
[4414]197    suite = regressionTest(test_verbose)
[3464]198    runner = unittest.TextTestRunner() #verbosity=2
199    runner.run(suite)
[6086]200
[6220]201    # timestamp at the end
202    timestamp = time.asctime()
203    version = aust.get_revision_number()
204    print
205    print 'Finished at %s, version %s' % (timestamp, version)
206
[4414]207    # Cleaning up
208    if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V':
[6086]209        sys.stdout = saveout
[4414]210        #fid.close() # This was causing an error in windows
211        #os.remove(filename)
212
[6417]213
214   
215    if sys.platform == 'win32':
[6718]216        raw_input('Press the RETURN key')
Note: See TracBrowser for help on using the repository browser.