Base classes for functional and load testing of OpenERP with Funkload
This package provides the OpenERPTestCase class, subclassing FunkloadTestCase with methods tailored for OpenERP functionnal and load testing through the XML-RPC or JSON-RPC APIs.
It features login and user management facilities, and pythonic encapsulation of API calls through the *ModelProxy classes.
For a detailed example, see the included test_sales_order.py test case.
Basic user handling
Funkload can create if needed users with given groups and login as them. Note how groups are specified as fully qualified references from ir.model.data:
from anybox.funkload.openerp import OpenERPTestCase class MyTestCase(OpenERPTestCase): def test_01_makeuser(self): self.login('admin', 'admin') self.ensure_user('spam', 'spampassword', ['base.group_sale_manager']) def test_02_my_usecase(self): self.login('spam', 'spampassword') ...
It is a common practice to use a test case to prepare the database. fl-run-test loads them in alphabetical order.
User handling through Funkload’s credential server
Funkload provides an external and optional credentials server. This is a facility that you are in no way forced to use.
The principle is to serve logins, passwords, and groups, loaded from separate external users.txt and groups.txt files. Groups in that sense are thought as groups of users, which is a slightly different philosophy as OpenERP’s but it doesn’t matter much.
OpenERPTestCase provides a login method that selects an user from the wished group from the credential server:
def test_my_usecase(self): self.login_as_group('base.group_sale_manager') # now test some scenario
Of course that means that the names of groups must also be consistent in groups.txt.. See the provided users.txt and groups.txt files.
There is also a method ensure_credential_server_users() that creates all wished users with the appropriate groups.
The principle is to get a ModelProxy instance, that’ll encapsulate all regular (so-called ORM) calls:
def test_my_usecase(self): """First list all customers, then...""" self.login('user', 'password') res_partner = self.model('res.partner') res_partner.model.search([('customer', '=', 'True')], description="Search customers")
The description will end up as request title in the Funkload bench report
The ModelProxy instances provided by the model() method can also perform workflow’s trigger validate:
def test_my_usecase(self): # some preparations, then confirm Sale Order #1234 model = self.model('sale.order') model.workflow('order_confirm')(1234, description="Confirm Sale Order")
As before, the description if for the bench report.
As of version 0.2, OpenERPTestCase provides helpers for JSON-RPC sessions (similar to those a browser would initiate) and calls.
The sessions are totally independent from XML-RPC ones. You need to perform a separate login operation:
Then you can get a JsonModelProxy, and access to ORM methods (in some cases this may behave slightly differently than XML-RPC):
model = self.model('sale.order', rpc='json') model.search([('customer', '=', 'True')], description="Search customers")
fields = ('name', 'street', 'city', 'zip') model.search_read([('customer', '=', True)], fields, description="Fetch customer addresses")
Actually, that was the only web-specific method currently available. More will presumably appear in the forthcoming releases.
this JSON-RPC OpenERP implementation currently supports OpenERP v7.0 only. API changes are scheduled for later OpenERP versions (thanks to Anthony Lesuisse for pointing that out).
The OpenERPTestCase class has the ref() method, to retrieve an object id from the reference code, as in XML or YML files, namely from ir.model.data:
def test_my_usecase(self): product_id = self.ref('product.product', 'stock',
The very simple wrapping provided by ModelProxy is inspired by the OpenObject library.
Tips for benchmarking
Randomize as much as you can. Notably, you must avoid repeated logins with the same user : this spawns database conflicts, putting some test runs in error state, but also making them very fast, hence making you stats unusable.
Anything that’s in setUp() is outside of performance measurements. See how the provided test_sales_orders preloads available customers and sellable products once for all for each virtual user.
Version 0.2 (2013-07-01)
- launchpad #1196284: allow specification of an environment variable as db_name
- launchpad #1195416: pass keyword arguments to OpenERP server methods
- launchpad #1196243: basic JSON-RPC support
Version 0.1 (2012-07-15)