[IMP] doc: add testing reference and improve docstrings

This commit is contained in:
Xavier Morel 2014-10-09 15:38:36 +02:00
parent 1c9ed9f534
commit bc59cfce61
5 changed files with 106 additions and 30 deletions

View File

@ -12,6 +12,7 @@ Reference
reference/module
reference/cmdline
reference/security
reference/testing
reference/http
reference/qweb

View File

@ -38,6 +38,10 @@ Running the server
(:file:`{$HOME}/.openerp_serverrc` by default, overridable using
:option:`-c`)
.. option:: --test-enable
runs tests after installing modules
.. _reference/cmdline/scaffold:
Scaffolding

73
doc/reference/testing.rst Normal file
View File

@ -0,0 +1,73 @@
.. _reference/testing:
===============
Testing Modules
===============
Odoo provides support for testing modules using unittest2_.
To write tests, simply define a ``tests`` sub-package in your module, it will
be automatically inspected for test modules. Test modules should have a name
starting with ``test_`` and should be imported from ``tests/__init__.py``,
e.g.
.. code-block:: text
your_module
|-- ...
`-- tests
|-- __init__.py
|-- test_bar.py
`-- test_foo.py
and ``__init__.py`` contains::
from . import test_foo, test_bar
.. note:: test modules which are not imported from ``tests/__init__.py`` will
not be run
The test runner will simply run any test case, as described in the official
`unittest documentation`_, but Odoo provides a number of utilities and helpers
related to testing Odoo content (modules, mainly):
.. autoclass:: openerp.tests.common.TransactionCase
:members: browse_ref, ref
.. autoclass:: openerp.tests.common.SingleTransactionCase
:members: browse_ref, ref
By default, tests are run once right after the corresponding module has been
installed. Test cases can also be configured to run after all modules have
been installed, and not run right after the module installation:
.. autofunction:: openerp.tests.common.at_install
.. autofunction:: openerp.tests.common.post_install
The most common situation is to use
:class:`~openerp.tests.common.TransactionCase` and test a property of a of a
model in each method::
class TestModelA(common.TransactionCase):
def test_some_action(self):
record = self.env['model.a'].create({'field': 'value'})
record.some_action()
self.assertEqual(
record.field,
expected_field_value)
# other tests...
Running tests
-------------
Tests are automatically run when installing or updating modules if
:option:`--test-enable <odoo.py --test-enable>` was enabled when starting the
Odoo server.
As of Odoo 8, running tests outside of the install/update cycle is not
.. _unittest2: http://pypi.python.org/pypi/unittest2
.. _unittest documentation: https://docs.python.org/2/library/unittest.html

View File

@ -1,18 +1,16 @@
# -*- coding: utf-8 -*-
import time
import unittest2
import xmlrpclib
import openerp.tests.common
DB = openerp.tests.common.DB
class test_xmlrpc(openerp.tests.common.HttpCase):
at_install = False
post_install = True
def test_01_xmlrpc_login(self):
""" Try to login on the common service. """
uid = self.xmlrpc_common.login(DB, 'admin', 'admin')
self.assertTrue(uid == 1)
self.assertEqual(uid, 1)
def test_xmlrpc_ir_model_search(self):
""" Try a search on the object service. """
@ -22,12 +20,4 @@ class test_xmlrpc(openerp.tests.common.HttpCase):
ids = o.execute(DB, 1, 'admin', 'ir.model', 'search', [], {})
self.assertIsInstance(ids, list)
# This test was written to test the creation of a new RPC endpoint, not
# really for the EDI itself.
#def test_xmlrpc_import_edi_document(self):
# """ Try to call an EDI method. """
# msg_re = 'EDI Document is empty!'
# with self.assertRaisesRegexp(Exception, msg_re):
# self.proxy.edi_60.import_edi_document(DB, ADMIN_USER_ID, ADMIN_PASSWORD, {})
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -17,8 +17,6 @@ import unittest2
import urllib2
import xmlrpclib
from datetime import datetime, timedelta
from shutil import rmtree
from tempfile import mkdtemp
import werkzeug
@ -47,7 +45,8 @@ def at_install(flag):
whether the test should (``True``) or should not (``False``) run during
module installation.
By default, tests are run at install.
By default, tests are run right after installing the module, before
starting the installation of the next module.
"""
def decorator(obj):
obj.at_install = flag
@ -59,7 +58,8 @@ def post_install(flag):
specifying whether the test should or should not run after a set of
module installations.
By default, tests are *not* run after installation.
By default, tests are *not* run after installation of all modules in the
current installation set.
"""
def decorator(obj):
obj.post_install = flag
@ -78,10 +78,13 @@ class BaseCase(unittest2.TestCase):
return self.registry.cursor()
def ref(self, xid):
""" Returns database ID corresponding to a given identifier.
""" Returns database ID for the provided :term:`external identifier`,
shortcut for ``get_object_reference``
:param xid: fully-qualified record identifier, in the form ``module.identifier``
:raise: ValueError if not found
:param xid: fully-qualified :term:`external identifier`, in the form
:samp:`{module}.{identifier}`
:raise: ValueError if not found
:returns: registered id
"""
assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'"
module, xid = xid.split('.')
@ -89,10 +92,13 @@ class BaseCase(unittest2.TestCase):
return id
def browse_ref(self, xid):
""" Returns a browsable record for the given identifier.
""" Returns a record object for the provided
:term:`external identifier`
:param xid: fully-qualified record identifier, in the form ``module.identifier``
:raise: ValueError if not found
:param xid: fully-qualified :term:`external identifier`, in the form
:samp:`{module}.{identifier}`
:raise: ValueError if not found
:returns: :class:`~openerp.models.BaseModel`
"""
assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'"
module, xid = xid.split('.')
@ -100,15 +106,17 @@ class BaseCase(unittest2.TestCase):
class TransactionCase(BaseCase):
"""
Subclass of BaseCase with a single transaction, rolled-back at the end of
each test (method).
""" TestCase in which each test method is run in its own transaction,
and with its own cursor. The transaction is rolled back and the cursor
is closed after each test.
"""
def setUp(self):
self.registry = RegistryManager.get(DB)
#: current transaction's cursor
self.cr = self.cursor()
self.uid = openerp.SUPERUSER_ID
#: :class:`~openerp.api.Environment` for the current test case
self.env = api.Environment(self.cr, self.uid, {})
def tearDown(self):
@ -117,9 +125,9 @@ class TransactionCase(BaseCase):
class SingleTransactionCase(BaseCase):
"""
Subclass of BaseCase with a single transaction for the whole class,
rolled-back after all the tests.
""" TestCase in which all test methods are run in the same transaction,
the transaction is started with the first test method and rolled back at
the end of the last.
"""
@classmethod
@ -155,7 +163,7 @@ class RedirectHandler(urllib2.HTTPRedirectHandler):
https_response = http_response
class HttpCase(TransactionCase):
""" Transactionnal HTTP TestCase with url_open and phantomjs helpers.
""" Transactional HTTP TestCase with url_open and phantomjs helpers.
"""
def __init__(self, methodName='runTest'):