source: anuga_work/development/2010-projects/anuga_1d/test_all.py @ 7839

Last change on this file since 7839 was 7839, checked in by steve, 12 years ago

Changing name of 1d projects so that it will be easy to moveto the trunk

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