mirror of
https://github.com/kennethreitz/python-guide.git
synced 2026-06-05 23:00:18 +00:00
Merge pull request #118 from guibog/master
On unit test, doctest and web frameworks
This commit is contained in:
@@ -21,10 +21,10 @@ documented in `PEP-3333 <http://www.python.org/dev/peps/pep-3333/>`_.
|
|||||||
Frameworks
|
Frameworks
|
||||||
::::::::::
|
::::::::::
|
||||||
|
|
||||||
Broadly speaking, a web framework is a set of libraries upon which you can
|
Broadly speaking, a web framework consist of a set of libraries and a main
|
||||||
build custom code to implement a web application (i.e. an interactive web
|
handler within which you can build custom code to implement a web application
|
||||||
site). Most web frameworks include patterns and utilities to accomplish at
|
(i.e. an interactive web site). Most web frameworks include patterns and
|
||||||
least the following:
|
utilities to accomplish at least the following:
|
||||||
|
|
||||||
URL Routing
|
URL Routing
|
||||||
Matches an incoming HTTP request to a particular piece of Python code to
|
Matches an incoming HTTP request to a particular piece of Python code to
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Inline comments are used for individual lines and should be used sparingly.: ::
|
|||||||
But sometimes, this is useful: ::
|
But sometimes, this is useful: ::
|
||||||
x = x + 1 # Compensate for border
|
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/)
|
PEP 257 is the primary reference for docstrings. (http://www.python.org/dev/peps/pep-0257/)
|
||||||
|
|||||||
+91
-1
@@ -3,6 +3,69 @@ Testing Your Code
|
|||||||
|
|
||||||
Testing your code is very important.
|
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
|
The Basics
|
||||||
::::::::::
|
::::::::::
|
||||||
@@ -37,9 +100,36 @@ Doctest
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
The doctest module searches for pieces of text that look like interactive Python
|
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.
|
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
|
Tools
|
||||||
:::::
|
:::::
|
||||||
|
|||||||
Reference in New Issue
Block a user