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

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

Replaced 'print' statements with log.critical() calls.

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