| 14 | | This runs through the set of tests suite for !SciPy. If you are only interested in testing a subset of !SciPy, for example, the {{{integrate}}} module, use the following: |
| | 11 | The test method may take two arguments; the first specifies the level of testing and the second the verbosity. The higher the level the more test will be run. If the verbosity is 1 or less, the tests will just show information messages about the tests that are run; but if it is greater than 1, then the tests will also provide warnings on missing tests. So if you want to run every test and get messages about which modules don't have tests: |
| | 12 | {{{ |
| | 13 | >>> scipy.test(level=10, verbosity=2) # or |
| | 14 | >>> scipy.test(10, 2) |
| | 15 | }}} |
| | 16 | Finally, if you are only interested in testing a subset of !SciPy, for example, the {{{integrate}}} module, use the following: |
| 24 | | The test level can be varied from 1 to 10. Increasing the verbosity provides more detailed messages about what tests are being executed. |
| 25 | | {{{ |
| 26 | | level: |
| 27 | | None --- do nothing, return None |
| 28 | | < 0 --- scan for tests of level=abs(level), |
| 29 | | don't run them, return TestSuite-list |
| 30 | | > 0 --- scan for tests of level, run them, |
| 31 | | return TestRunner |
| 32 | | |
| 33 | | verbosity: |
| 34 | | >= 0 --- show information messages |
| 35 | | > 1 --- show warnings on missing tests |
| 36 | | }}} |
| | 25 | Please feel free to choose one of these modules to develop test for either after or even as you read through this introduction. |
| 39 | | Much of !SciPy is legacy code that was written without unit tests. As such, much of the functionality remains untested. However, more unit tests are being written all the time (and we encourage you to contribute). If you are writing a package that you'd like to become part of !SciPy, please write the tests as you develop the package. |
| | 28 | Ideally, every Python code, extension module, or subpackage in the !SciPy package directory should have a corresponding {{{test_<name>.py}}} file. This file should define classes derived from the {{{NumpyTestCase}}} (or the {{{unittest.TestCase}}}) class and have names starting with {{{test_}}}. The methods of these classes whose names start with {{{bench_}}}, {{{check_}}}, or {{{test_}}}, are passed on to the {{{unittest}}} machinery. In addition, the value of the first optional argument of these methods determines the level of the corresponding test. (Default level is 1.) |
| 41 | | === Setting up a module for testing === |
| 42 | | Every module or package requires two things for its testing to be included in the !SciPy test suite. |
| 43 | | 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}}}. |
| 44 | | 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. |
| 45 | | |
| 46 | | === The ``__init__.py`` file === |
| 47 | | |
| 48 | | {{{ |
| 49 | | # |
| 50 | | # Package ... - ... |
| 51 | | # |
| 52 | | |
| 53 | | from info import __doc__ |
| 54 | | |
| 55 | | ... |
| 56 | | |
| 57 | | from numpy.testing import NumpyTest |
| 58 | | test = NumpyTest().test |
| 59 | | }}} |
| 60 | | |
| 61 | | === The ``tests/`` directory === |
| 62 | | |
| 63 | | Ideally, every Python code, extension module, or subpackage in Scipy package directory should have the corresponding {{{test_<name>.py}}} file in {{{tests/}}} directory. This file should define classes derived from {{{NumpyTestCase}}} (or from {{{unittest.TestCase}}}) class and have names starting with {{{test}}}. The methods of these classes which names start with {{{bench}}}, {{{check}}}, or {{{test}}}, are passed on to unittest machinery. In addition, the value of the first optional argument of these methods determine the level of the corresponding test. Default level is 1. |
| 64 | | |
| 65 | | A minimal example of a {{{test_yyy.py}}} file that implements tests for a Scipy package module {{{scipy.xxx.yyy}}} containing a function {{{zzz()}}}, is shown below:: |
| 66 | | |
| | 30 | === test_yyy.py === |
| | 31 | Suppose you have a !SciPy module {{{scipy/xxx/yyy.py}}} containing a function {{{zzz()}}}. To test this you would start by creating a test module called {{{test_yyy.py}}}. This test file should include a class that tests {{{zzz()}}}. The test class has test methods that test various aspects of {{{zzz()}}}. Within these test methods, {{{assert()}}} is used to test whether some case is true. If the assert fails, the test fails. The {{{NumpyTest().run()}}} function actually runs the test suite. A minimal example of a {{{test_yyy.py}}} file that implements tests for a Scipy package module {{{scipy.xxx.yyy}}}, is shown below: |
| 92 | | Note that all classes that are inherited from {{{TestCase}}} class, are picked up by the test runner when using {{{testoob}}}. |
| 93 | | |
| 94 | | === Template for {{{test_module_xxx.py}}} === |
| 95 | | 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: |
| | 59 | Once the {{{scipy/xxx/tests/test_yyy.py}}} is written, its possible to run the tests by going to the {{{tests/}}} directory and typing: |
| 104 | | python test_foo.py |
| 105 | | }}} |
| 106 | | Or if {{{tests/}} was put in the python path, you could run the tests interactively in the interpreter like this: |
| 107 | | {{{ |
| 108 | | >>> import test_foo.py |
| 109 | | >>> test_foo.test() |
| 110 | | }}} |
| 111 | | Usually 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: |
| 112 | | {{{ |
| 113 | | """ foo.py |
| 114 | | """ |
| 115 | | |
| 116 | | def sum(a): |
| 117 | | ... |
| 118 | | |
| 119 | | def test(): |
| 120 | | from scipy.common.scipy_test import module_test |
| 121 | | module_test(__name__,__file__) |
| 122 | | |
| 123 | | def test_suite(): |
| 124 | | from scipy.common.scipy_test import module_test_suite |
| 125 | | return module_test_suite(__name__,__file__) |
| | 72 | from numpy.testing import NumpyTest |
| | 73 | test = NumpyTest().test |