Changes between Version 109 and Version 110 of DeveloperGuidelinesTesting


Ignore:
Timestamp:
08/08/11 21:10:54 (13 years ago)
Author:
Mike A
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DeveloperGuidelinesTesting

    v109 v110  
    6969 * simplification of integration testing (because all the parts are known to work, only interfaces between them need testing),
    7070 * better system design by:
    71  * * easing refactoring (changes can be more rapidly verified not to create new bugs),
    72  * * promoting refactoring (dividing units into testable pieces also creates more reusable pieces),
    73  * * standing in for specification documents (i.e. describing by example what the code needs to do).
     71 ** easing refactoring (changes can be more rapidly verified not to create new bugs),
     72 ** promoting refactoring (dividing units into testable pieces also creates more reusable pieces),
     73 ** standing in for specification documents (i.e. describing by example what the code needs to do).
    7474
    7575Cons:
    76 * it takes time to develop and maintain the tests - which means sloppy tests are as bad or worse than sloppy code.
    77 
    78 === Test Runner ===
     76 * it takes time to develop and maintain the tests - unit tests are not a free lunch,
     77 * sloppy tests are as bad or worse than sloppy code - unit tests are not a silver bullet or a free lunch,
     78
     79=== Running unit tests ===
    7980
    8081Web2py imposes a severe problem on any external test runner, i.e. application code is provided a global environment by web2py, it must expect that environment. Therefore, the test runner must reproduce and provide that environment to the tests. This means that we can't use any external test runner that doesn't know about web2py.
    8182
    82 nose is a python module/command which finds and runs tests. nose is suitable as it has been widely adopted in the python community, allows standard test specifications and is highly configurable and customisable, without confusing "magical" behaviour. To work with web2py, a plugin has been written, which means that nosetests isn't run in the normal way, although we'll aim for that as much as possible.
     83[http://readthedocs.org/docs/nose/ nose] is a python module/command which finds and runs tests. nose is suitable as it has been widely adopted in the python community, allows standard test specifications and is highly configurable and customisable, without confusing "magical" behaviour. Documentation is [http://readthedocs.org/docs/nose/ here].
     84
     85To work with web2py, a plugin has been written, which means that nosetests isn't run in the normal way, although we'll aim for that as much as possible. Extra arguments are just passed on to nose, so the command's argument format is the same as original as the original nosetest command.
    8386
    8487To run the unit tests in Sahana Eden via nose, there is a nose.py command in the tests/ folder within the application. Note: This command is not installed outside of the application as it is designed for developers, who may have several versions of Sahana Eden at any one time.
     88
     89=== Writing unit tests ===
     90
     91When writing unit tests, note that nose uses a convention over configuration approach when finding tests. i.e. if it looks like a test, then nose assumes it is a test.
     92
     93To make your test look like a test, there are two options:
     94
     95# easy: write a procedure whose name starts with "test_"
     96# advanced: inherit from unittest.TestCase and write your tests as described in [http://docs.python.org/library/unittest.html]
     97
     98{{{
     99# examples:
     100
     101def test_addition():
     102    assert 1 + 1 == 2
     103
     104import unittest
     105class AdditionTest(unittest.TestCase):
     106    def test_positive(test):
     107        assert 1+1 == 2
     108
     109    def test_negative(test):
     110        assert -1 + -1 == -2
     111}}}
     112
     113Currently these tests are stored in {{{/tests}}}. Duplicate the module folder there of the unit being tested inside the tests/ folder. We know this duplication is not ideal, this may well change in future and tests be placed nearer the code being tested.
     114
     115'''Advice:'''
     116
     117One unittest.TestCase per unit (procedure, method or function). This makes test output easy to follow as it is what unittest expects. I.e. don't test several units in one TestCase.
     118You can just use asserts instead of the cumbersome test.assertEquals etc. methods which often don't do what you need. nose can introspect the stack to make meaningful messages.
     119Avoid inheritance trees with unittests as the unittest.TestCase isn't really designed for inheritance, more as a convenient place to put the tests.
     120Break test methods up into smaller methods. Non-test code can be extracted out into external procedures/functions which are easier to reuse.
     121Read the nose documentation regarding writing tests: [http://readthedocs.org/docs/nose/en/latest/writing_tests.html]
     122Read this too: [http://ivory.idyll.org/articles/nose-intro.html]
    85123
    86124=== Examples ===