Changes between Version 2 and Version 3 of TestingGuidelines

Show
Ignore:
Timestamp:
12/23/06 06:07:13 (6 years ago)
Author:
jarrod.millman
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • TestingGuidelines

    v2 v3  
     1'''CAUTION:  This page is in the process of being migrated from an older page.  Until this process is completed, information found here may be incorrect.''' 
    12= Testing Guidelines = 
    23SciPy's testing structure is based on the unit testing framework offered by unittest.py. scipy_test.py also provides a few helper functions. 
     
    3031}}} 
    3132 
     33== Setting up your module for testing == 
     34Every module or package requires two things for its testing to be included in the SciPy test suite. 
     35 1. A test module -- Every directory in the SciPy directory structure has a {{{tests/}}} sub-directory. The test module for {{{dir1/module_xxx.py}}} is named {{{dir1/tests/test_module_xxx.py}}}. 
     36 1. Two test routines -- Every module should have the functions {{{test()}}} and {{{test_suite()}}} defined. The first of these is used when running tests from the command line. The second returns a {{{unittest.TestSuite}}} object that can be used by other programs to test SciPy. This is beneficial, for instance, in generating web pages that show how healthly the current version of SciPy is. 
     37 
     38== Template for {{{test_module_xxx.py}}} == 
     39More complete documentation for how to use the unittest framework is found here. The following code will give you a basic idea of how to add unit tests to your module in SciPy. Suppose you have a module {{{scipy/stats/foo.py}}} that has a function sum(a) that should accept a 1-D array or a scalar value. Create a test module called {{{scipy/stats/tests/test_foo.py}}}. This test file should include a class that tests {{{sum()}}} and a couple of other functions, {{{test_suite()}}} and {{{test()}}}. The test class has test methods that test various aspects of {{{sum()}}}. Within these test methods, {{{assert()}}} is used to test whether some case is true. If the assert fails, the test fails. Again, see here for more detailed info on defining test classes. The {{{test_suite()}}} function combines all the test classes that live in this module together to form a test suite that can be used for testing. The {{{test()}}} function actually runs the test suite. This file should look something like this: 
     40{{{ 
     41... 
     42}}} 
     43 
     44== Template for {{{test()}}} and {{{test_suite()}}} in {{{module_xxx.py}}} == 
     45 
     46Once the {{{test_foo.py}}} is written, its possible to run the tests by going to the {{{tests/}}} directory and typing: 
     47{{{ 
     48python test_foo.py 
     49}}} 
     50Or if {{{tests/}} was put in the python path, you could run the tests interactively in the interpreter like this: 
     51{{{ 
     52>>> import test_foo.py 
     53>>> test_foo.test() 
     54}}} 
     55Usually however, adding the {{{tests/}}} directory to the python path isn't desireable. It would be nice to invoke the test straight from the module {{{foo.py}}}. To this end, {{{test()}}} and {{{test_suite()}}} methods are added to the {{{foo.py}}} module also. They use a couple of helper functions that live in {{{scipy/common/scipy_test.py}}} to handle the messy work. Place the following two definitions at the end of your module: 
     56{{{ 
     57""" foo.py 
     58""" 
     59 
     60def sum(a): 
     61   ... 
     62 
     63def test(): 
     64    from scipy.common.scipy_test import module_test 
     65    module_test(__name__,__file__) 
     66 
     67def test_suite(): 
     68    from scipy.common.scipy_test import module_test_suite 
     69    return module_test_suite(__name__,__file__) 
     70}}} 
     71Now you can do the following to test your module: 
     72{{{ 
     73>>> import scipy 
     74>>> scipy.common.foo.test() 
     75}}} 
     76 
     77Also, when invoking the entire SciPy test suite, your tests will be found and run: 
     78{{{ 
     79>>> import scipy 
     80>>> scipy.test()  
     81# your tests are included and run automatically! 
     82}}} 
     83Testing packages is a little more work, but not bad. See {{{scipy/common/__init__.py}}}. 
     84 
     85== {{{scipy_test.py}}} == 
     86 
     87This module holds a few helper routines. Several were discussed in the previous section. A couple of others are something of a verbose assert() function that give feedback as to what error occured. One of them, assert_array_equal(), is useful for comparing values in two arrays. The library of assert functions should grow to test for other general cases. 
     88 
     89== Testing Wishes == 
     90 
     91 * '''Speed testing:''' It'd be nice to have some speed testing facilities so that we could keep track of whether new code hurts or helps our speed. It would provide some simple benchmarking facilities also. To do this correctly, we'd need something like {{{start_timer()}}} and {{{stop_timer()}}} calls that could be placed in the {{{check_xxx()}}} methods. This would allow the set up and error checking code at the beginning and end of check methods to be ignored for timing purposes. If these functions weren't used in the check method, then the entire check method would be timed. 
     92 * '''Regression testing and database:''' If each test could be stored in a database, including timing information, that would allow us to see how speed is changing over time (using a reference machine). 
     93 * '''Web output of test results:''' Haven't looked much at the {{{TestRunner}}} stuff, but I imagine it is possible to grab info from the test suite and write it out to an HTML file. We should do this on several architectures every evening on the scipy.org site.