diff --git a/docs/scenarios/web.rst b/docs/scenarios/web.rst index 04c36e7..e3eb2ab 100644 --- a/docs/scenarios/web.rst +++ b/docs/scenarios/web.rst @@ -21,10 +21,10 @@ documented in `PEP-3333 `_. Frameworks :::::::::: -Broadly speaking, a web framework is a set of libraries upon which you can -build custom code to implement a web application (i.e. an interactive web -site). Most web frameworks include patterns and utilities to accomplish at -least the following: +Broadly speaking, a web framework consist of a set of libraries and a main +handler within which you can build custom code to implement a web application +(i.e. an interactive web site). Most web frameworks include patterns and +utilities to accomplish at least the following: URL Routing Matches an incoming HTTP request to a particular piece of Python code to diff --git a/docs/writing/documentation.rst b/docs/writing/documentation.rst index 60be079..28edaf4 100644 --- a/docs/writing/documentation.rst +++ b/docs/writing/documentation.rst @@ -33,7 +33,7 @@ Inline comments are used for individual lines and should be used sparingly.: :: But sometimes, this is useful: :: x = x + 1 # Compensate for border -Doc Strings +Docstrings ----------- PEP 257 is the primary reference for docstrings. (http://www.python.org/dev/peps/pep-0257/) diff --git a/docs/writing/tests.rst b/docs/writing/tests.rst index 90a63df..d7fed0a 100644 --- a/docs/writing/tests.rst +++ b/docs/writing/tests.rst @@ -3,6 +3,69 @@ Testing Your Code Testing your code is very important. +Getting used to writting the testing code and the running code in parallel is +now considered a good habit. Used wisely, this method helps you define more +precisely your code's intent and have a more decoupled architecture. + +Some general rules of testing: + +- A testing unit should focus on one tiny bit of functionality and prove it + correct. + +- Each test unit must be fully independent. Each of them must be able to run + alone, and also within the test suite, regardless of the order they are called. + The implication of this rule is that each test must be loaded with a fresh + dataset and may have to do some cleanup afterwards. This is usually + handled by setUp() and tearDown() methods. + +- Try hard to make tests that run fast. If one single test needs more than a + few millisecond to run, development will be slowed down or the tests will not + be run as often as desirable. I some cases, test can't be fast because they + need a complex data structure to work on, and this data structure must be loaded + every time the test runs. Keep this heavier tests in a separate test suite + that is run by some scheduled task, and run all other tests as often as needed. + +- Learn your tools and learn how to run a single test or a test case. Then, + when developing a function inside a module, run this function's tests very + often, ideally automatically when you save the code. + +- Always run the full test suite before a coding session, and run it again + after. This will give you more confidence that you did not break anything in + the rest of the code. + +- It is a good idea to implement a hook that runs all test before pushing code + to a shared repository. + +- If you are in the middle of a development and have to interrupt your work, it + is a good idea to write a broken unit test about what you want to develop next. + When comming back to work, you will have a pointer to where you were and get + faster on tracks. + +- The first step when you are debugging your code is to write a new test pinpointing + the bug. While it is not always possible to do, those bug catching test are among + the most valuable piece of code in your project. + +- Use long and descriptive names for testing functions. The style guide here is + slighlty different than that of running code, where short names are often + preferred. The reason is testing functions are never called explicitely. + ``square()`` or even ``sqr()`` is ok in running code, but in testing code you + would has names such as ``test_square_of_number_2()``, + ``test_square_negative_number()``. These function names are displayed when a + test fail, and should be as descriptive as possible. + +- When something goes wrong or has to be changed, and if your code has a good + set of tests, you or other maintainers will rely largely on the testing suite + to fix the problem or modify a given behavior. Therefore the testing code will + be read as much as or even more than the running code. A unit test whose + purpose is unclear is not very helpful is this case. + +- Another use of the testing code is as an introduction to new developpers. When + someone will have to work on the code base, runnning and reading the related + testing code is often the best they can do. They will or should discover the + hot spots, where most difficulties arise, and the corner cases. If they have to + add some functionality, the first step should be to add a test and, by this mean, + ensure the new functionality is not already a working path that has not been + plugged in the interface. The Basics :::::::::: @@ -37,9 +100,36 @@ Doctest ------- The doctest module searches for pieces of text that look like interactive Python -sessions, and then executes those sessions to verify that they work exactly as +sessions in docstrings, and then executes those sessions to verify that they work exactly as shown. +Doctests have a different use case than proper unit tests: they are usually less +detailed and don't catch special cases or obscure regression bugs. They are +useful as an expressive documentation of the main use cases of a module and +its components. However, doctests should run automatically each time +the full test suite runs. + +A simple doctest in a function: + +:: + + def square(x): + """Squares x. + + >>> square(2) + 4 + >>> square(-2) + 4 + """ + + return x * x + + if __name__ == '__main__': + import doctest + doctest.testmod() + +When running this module from the command line as in ``python module.py``, the doctests +will run and complain if anything is not behaving as described in the docstrings. Tools :::::