Writing tests for your module using YAML

Odoo supports different ways of writing addon module tests, YAML tests, and Python tests. In this recipe, we will see how to write YAML tests for the my_module methods we wrote in Chapter 5, Basic Server Side Development, in the recipe Define Model methods and use the API decorators.

Getting ready

This recipe assumes you have an instance ready with the code for the my_module module defined in Chapter 3, Creating Odoo Modules, and the code from the Define Model methods and use the API decorators recipe in Chapter 5, Basic Server Side Development.

How to do it…

In order to write YAML unit tests for my_module, you need to follow these steps:

  1. Edit the __openerp__.py file of the module, and add the test's entry:
    {  # …
        'test': ['test/test_books.yml']
    }
    
  2. Create a test directory in my_module:
    $ mkdir test
    
  3. Create a file called test_books.yml in the directory. Add a test description at the top:
    -
      Test LibraryBook.change_state
    
  4. Add a step changing the current user to the demo user:
    -
      !context
        uid: 'base.user_demo'
    
  5. Add a test step creating a book:
    -
      create book in draft state
    -
      !record {model: library.book, id: testbook}:
        - name: Test Book
        - state: draft
    
  6. Add a step calling the change_state method:
    -
      call change_state to make book available
    -
      !python {model: library.book, id: testbook}: |
        self.change_state('available')
    
  7. Add a step checking the successful result of the call:
    -
      !assert {model: library.book, id: testbook, string: wrong state}:
        - state == 'available'
    
  8. Add a step calling the change_state method with a forbidden state:
    -
      try to call change_state to make book draft
    -
      !python {model: library.book, id: testbook}: |
        self.change_state('draft')
    -
      check the book is still available
    -
      !assert {model: library.book, id: testbook, string: wrong state}:
        - state == 'available'
    

How it works…

The YAML files we are using here are the same as the ones used to load data files (see Chapter 9, Module Data), except that they are included in the test key of the __openerp__.py rather than in the data key. We add that key in step 1. They are therefore processed only when running the tests (see the Running Server Tests recipe in this chapter).

Note

Traditionally, YAML tests are added to the test/ subdirectory of the addon module, while Python unit tests live in the tests/ subdirectory.

Step 3 adds a description at the top of the test file in a YAML test node. Mind the indentation of the text, after the - delimiting a node. This description will be printed in the test log (at log level DEBUG).

Step 4 uses a !context YAML node to change the evaluation context used in the test. The most common use of this node is to modify the user used to run the test from the administrator to someone else by assigning a string containing the XML ID of the user to uid.

Note

It is always good practice, when writing tests, to have them run with a specific user, and in any case not with the administrator; this user bypasses all the security checks, so this will hide issues in your security rules.

Step 5 creates some test data using a !record YAML node. The YAML attributes, between braces, give the name of the model to be used and the XML ID to use for the new record.

Note

In all the YAML files, pay attention to the spacing, as the syntax is quite stringent; you need a single space after the commas, a single space before the opening brace, and the trailing colon has to be just after the closing brace.

Step 6 uses a !python YAML node to execute some Python code. The attributes specify the model to be used and the XML ID of the record. Inside the block, self is a recordset of the specified model containing a single record with the supplied XML ID.

Note

YAML Syntax

Take note of the | character at the end of the !python node. It is used to denote a literal text node, in which whitespace is not processed. You need this for Python code where spacing is significant.

Inside the Python block, you may also use the following variables:

  • ref: This is a function returning a recordset from an XML ID passed as a string
  • time: This is the time module from the Python standard library
  • datetime: This is the datetime type from the datetime module of the Python standard library
  • timedelta: This is the timedelta type from the datetime module of the Python standard library

In step 7, we use an !assert YAML node to make assertions about the record. The attributes specify the model to use and on which XML ID the assertions must be checked. The string attribute is used in the error message if one of the checks in the node is not True.

See the following recipe, Run server tests, to see how to run the test.

There's more…

When !assert is not convenient for writing checks, for instance, if you don't have an XML ID for the record you want to check, you can use a !python block and the assert Python keyword. We could also rewrite the last check of the recipe like this:

-
  try to call change_state to make book draft, check this has no effect
-
  !python {model: library.book, id: testbook}: |
    self.change_state('draft')
    assert self.state == 'available', 'wrong state %s' % self.state
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.108.241