Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

First time I write the tests before the actual code. All fit in the same module.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from os.path import join as path_join
from xmlrpclib import Fault, ServerProxy


XMLRPC_URL = 'xmlrpc/2'


class Model(object):

    def __init__(self, host, db, uid, pwd, model):
        self._object_api = ServerProxy( path_join(host, XMLRPC_URL, 'object') )
        self._db = db
        self._uid = uid
        self._pwd = pwd
        self._model = model

    def _execute_kw(self, method, *args, **kwargs):
        return self._object_api.execute_kw(self._db, self._uid, self._pwd,
                                           self._model, method, args, kwargs)

    def execute(self, method, *args, **kwargs):
        """Execute a method, with provide args and kwargs."""
        return self._execute_kw(method, *args, **kwargs)

    def search(self, domain=None, **kwargs):
        """Returns a list of ids.

        kwargs: offset, limit, order, context, count
        """
        if domain is None:
            domain = []

        return self._execute_kw('search', domain, **kwargs)

    def search_count(self, domain=None, **kwargs):
        """Returns the number of records.

        kwargs: context
        """
        if domain is None:
            domain = []

        return self._execute_kw('search_count', domain, **kwargs)

    def search_read(self, domain=None, **kwargs):
        """Returns a list of dictionnaries, containing values.

        kwargs: fields, offset, limit, order, context
        """
        if domain is None:
            domain = []

        return self._execute_kw('search_read', domain, **kwargs)

    def create(self, vals, **kwargs):
        """Creates a new record, returns its database id.

        kwargs: context
        """
        return self._execute_kw('create', vals, **kwargs)

    def write(self, ids, vals, **kwargs):
        """Modify records.

        kwargs: context
        """
        return self._execute_kw('write', ids, vals, **kwargs)

    def unlink(self, ids, **kwargs):
        """Deletes records.

        kwargs: context
        """
        return self._execute_kw('unlink', ids, **kwargs)


class ObjectApi(object):

    def __init__(self, host, db, login, pwd):
        api_common = ServerProxy( path_join(host, XMLRPC_URL, 'common') )
        uid = api_common.authenticate(db, login, pwd, {})
        self._host = host
        self._db = db
        self._uid = uid
        self._pwd = pwd

    def get_model(self, model):
        return Model(self._host, self._db, self._uid, self._pwd, model)


#########
# TESTS #
#########


import unittest

TESTING_ARGS = ["http://localhost:8069", "demo", "admin", "admin"]

class TestOdooApi(unittest.TestCase):

    def setUp(self):
        obj_api = ObjectApi(*TESTING_ARGS)
        self.obj_api = obj_api
        ResUsers = obj_api.get_model('res.users')
        self.ResUsers = ResUsers
        self.johnsmith_id = ResUsers.create({ 'name': 'John Smith', 
                                              'login': 'johnsmith' })

    def tearDown(self):
        self.ResUsers.unlink([self.johnsmith_id])

    def test_search(self):
        # return type
        ids = self.ResUsers.search()
        self.assertIsInstance(ids, list)
        self.assertTrue(len(ids) > 0)

        # with domain
        ids = self.ResUsers.search([('login', '=', 'johnsmith')])
        self.assertTrue(ids)

        # with zero results
        ids = self.ResUsers.search([('login', '=', False)])
        self.assertIsInstance(ids, list)
        self.assertFalse(ids)

    def test_search_read(self):
        # return type
        records = self.ResUsers.search_read(fields=['name'])
        self.assertIsInstance(records, list)
        self.assertIsInstance(records[0], dict)
        self.assertTrue(len(records) > 0)

        # with domain
        records = self.ResUsers.search_read([('login', '=', 'johnsmith')], fields=['name'])
        self.assertEqual(records[0]['name'], 'John Smith')

        # with zero results
        records = self.ResUsers.search_read([('login', '=', False)])
        self.assertIsInstance(records, list)
        self.assertFalse(records)

    def test_search_count(self):
        # return type
        count = self.ResUsers.search_count()
        self.assertIsInstance(count, int)
        self.assertTrue(count > 0)

        # with domain
        count = self.ResUsers.search_count([('login', '=', 'johnsmith')])
        self.assertEqual(count, 1)

        # with zero results
        count = self.ResUsers.search_count([('login', '=', False)])
        self.assertIsInstance(count, int)
        self.assertEqual(count, 0)

    def test_create_unlink(self):
        user_id = self.ResUsers.create({ 'name': 'John Doe', 'login': 'johndoe' })
        self.assertTrue(user_id)

        # verify create
        records = self.ResUsers.search_read([('login', '=', 'johndoe')], fields=['name'])
        self.assertEqual(records[0]['name'], 'John Doe')

        self.ResUsers.unlink([user_id])

        # verify unlink
        count = self.ResUsers.search_count([('login', '=', 'johndoe')])
        self.assertEqual(count, 0)

    def test_write(self):
        self.ResUsers.write([self.johnsmith_id], { 'name': 'John Doe' })

        # verify write
        records = self.ResUsers.search_read([('login', '=', 'johnsmith')], fields=['name'])
        self.assertEqual(records[0]['name'], 'John Doe')

    def test_execute(self):
        # return type
        fields = self.ResUsers.execute('fields_get', 
                                       attributes=['string', 'help', 'type'])
        self.assertIsInstance(fields, dict)

        # non existing function
        # unfortunately, we can only catch the xmlrpclib.Fault exception,
        # and not the AttributeError raised on the server side
        with self.assertRaises(Fault) as cm:
            self.ResUsers.execute('function_that_will_raise_an_error')


if __name__ == '__main__':
    """Odoo api, by VimeXcom.

    Running this module from the command line will test it, assuming:

    1. you have a local Odoo up and running with:
        - host:     http:localhost:8069
        - database: demo
        - login:    admin
        - password: admin

    2. the database is just installed with demo data, and nothing was modified

    Import it with Python from a terminal or a script to use it on your own server.
    """

    unittest.main()

Are the tests relevant ? Should I put the tests in a separate module ?

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.