Навигация

Оглавление

Versions

This is the documentation for older versions of Odoo (formerly OpenERP).

See the new Odoo user documentation.

See the new Odoo technical documentation.

3   Рекомендации по автоматическому тестированию с использованием YAML

Примечание

См. также раздел YAML Data Serialization

Это рекомендации по автоматическому тестированию для менеджеров продукта и разработчиков.

3.1   Синтаксис

Write scenarios using the YAML syntax, not the "cucumber" syntax, so that we can directly integrate these tests in OpenERP modules (and implement them afterwards).

3.2   Тесты запускаются на стороне сервера

Поскольку тесты запускаются на стороне сервера, не стоит писать код, подобный

# wrong
* Given I am logged in as admin user with proper password
* module pos is installed

Пользователь — по умолчанию admin, так что писать это в каждом тесте — избыточно. И вместо слов о том, что "я проверил, установлен ли модуль pos", просто укажите название модуля, над которым проводится тест. Первая строка могла бы быть в этом случае "module: pos".

3.3   Будьте предсказуемы в постановке цели тестирования

Используйте функциональные термины вместо объектов

  • Это не достаточно хорошо:

    I will test the manufacturing order
    
  • Пример хорошего введения:

    In order to test the CRM in OpenERP, I will do a customer qualification
    process that starts with a fist contact with a customer(a lead),
    which will be converted to a business opportunity and a partner.
    
# wrong
*In caldav testing of creation of calendar as Admin

# better
*In order to test the calendar synchronisation with mobile phones and
outlook, I will test the caldav interface for meetings.


# wrong:
In order to test the manufacturing order process and modules As an
administrator I want to see if the features work correctly.

# better:
  In order to test the manufacturing of products, I will test the
  features of the manufacturing order document: consume raw materials,
  produce finished goods, scrap some products and split in production
  lots.

# wrong:
Testing of Document for ftp server is running and being connected or
not
# better:
  In order to test the document management system, I will try different
  operation on the FTP interface, and check their impacts on OpenERP's
  documents.

3.4   Избегайте использования данных, которые пользователь может изменить до запуска теста

# wrong (mrp):
Then My manufacturing order turned into 'Waiting for goods' state.
And one picking was also generated for my manufacturing order:
'INT/00001'.

Это не очень хорошая проверка. Кто знает, будет он 'INT/0001' или например последовательно 'INT/0002'? Потому что пользователь мог создать внутреннюю комплектацию перед установкой модуля MRP.

# wrong (pos):
I press new record from toolbar.
Some default values are filled automatically like:
Company>Tinysprl,Journal>x Sales Journal

Вы не можете быть уверены, что компания действительно 'Tiny SPRL'. Пользователь мог настроить свою собственную, так что верный тест выглядеть так: "The company is set by default to the company of the admin user."

Позаботтесь об этих зависимостях данных, потому что они могут обрушить тест просто из-за изменения демонстрационных данных пользователем до запуска теста.

Вы можете положиться на демонстрационные данные модуля, в котором располагаете ваш тест. Но если данные создаются другим модулем — найдите способ работать непосредственно с идентификаторами или создайте свои демо-данные.

3.5   Описывайте в тестах то, что можно легко проверить с помощью YAML

Например, почтовый шлюз. Вы не можете написать так:

First I have made one fetchmail rc script using the proper syntax
with specific email server and address information and used crm.lead
as model Then I run the fetchmail command like: fetchmail -f <created
rc file name> The script should exit successfully

Потому что вы не можете настроить для этого теста учётную запись pop.

Я бы написал так:

I have a list of different emails with different encoding and
different kind of attachments stored in the directory test/emails.
I test to pass all these documents through the mailgateway script:
  something like:
    for each email file:
      call the script with stdin<this email file

Если возможно — используйте прямой вызов python, избегая os.system.

Что касается FTP, YAML позволяет протестировать его напрямую, подключив модуль FTP-клиента Python прямо в коде YAML:

import ftplib

3.6   Не полагайтесь на демонсрационные данные, если пользователь может их изменить

Плохой пример:

When I pressed 'Confirm Production' button. Then I could see the Finished Products into Products to Consume with quantity 10.00.

Then My manufacturing order turned into 'Waiting for goods' state. And one picking was also generated for my manufacturing order: 'INT/00001'.

And the following values appeared in the Products to Consume

product_id

product_qty

product_uom

location_id

||

||

[CPU_GEN] Regular processor config

10.00

PCE

Запасы (Stock)

||

||

[HDD1] HDD Seagate 7200.8 80GB

10.00

PCE

Запасы (Stock)

||

||

[TOW1] ATX Mid-size Tower

10.00

PCE

Запасы (Stock)

||

||

[MOU] Mouse

10.00

PCE

Запасы (Stock)

||

||

[KEYA] Keyboard -AZERTY

10.00

PCE

Запасы (Stock)

||

||

For such an example, I would have created a few products and a bom in the test scenario. And test the manufacturing order on these test data.

3.7   Не проверяйте полный текст исключения

Then I got the following error message:

xmlrpclib.Fault: <Fault warning -- Error:

    Couldn't find bill of material for product: 'Traceback (most recent call last):
    File in dispatch
    result = ExportService.getService(service_name).dispatch(method, auth, params)
     File "/home/uco/workspace/Trunk/openobject-server/bin/service/web_services.py", line 587, in dispatch
     res = fn(db, uid, *params)
     File "/home/uco/workspace/Trunk/openobject-server/bin/osv/osv.py", line 64, in wrapper
     self.abortResponse(1, inst.name, inst.exc_type, inst.value)
     File "/home/uco/workspace/Trunk/openobject-server/bin/netsvc.py", line 66, in abortResponse
     raise Exception("%s -- %s\\n\\n%s"%(origin, description, details))
    Exception: warning -- Error

    Couldn\'t find bill of material for product\n'>

Simply do::

  And it should generate an exception to say that he do not find a BoM
  defined for this product.

3.8   Будьте более функциональны. Поясняйте, что пользователь должен сделать, а не куда он должен нажимать

# wrong:
I press new record from toolbar of lead's view
Some default values are filled automatically like: priority>Normal,user_id>Administrator, state>Draft
Then I give some values for lead:
|name|section_id|partner_name|phone|mobile|
|Carrie Helle|Sales Department|Stonage IT|(855) 924-4364|(333) 715-1450|
Then I press the save button from toolbar
The lead is created successfully

No need to write the all the data of the form in the english text (phone, mobile, ...). These data will be written in the final YAML, when you implement the test. A better final YAML for the above example should look like this:

-
 As I met a new customer in a fair, I create a new lead "Stonage IT"
 to record his data.
-
 !record {model:rcrm.lead, id:partner_carrie}
   name: Stonage IT
   contact_name: Carrie Helle
   phone: (855) 924-4364
   mobile: (333) 715-1450
-
  I check that the state field is set automatically by default.
-
  !assert {model:crm.lead, id:partner_carrie} state

3.9   В тестах можно использовать вызовы "onchange" для симуляции клиентского интерфейса

  • I create a new sale order by filling the partner. I want addresses to be filled up by the onchange call but I still need to provide dummy addresses (required fields) to allow the record to be created.

  • !record {model: sale.order, id: my_order}:

    partner_id: base.res_partner_asus pricelist_id: product.list0 partner_order_id: base.main_address partner_invoice_id: base.main_address partner_shipping_id: base.main_address

  • I then call the onchange method and update the record with the returned value.

  • !python {model: sale.order}: |

    my_order = self.browse(cr, uid, ref('my_order')) value = my_order.onchange_partner_id(my_order['partner_id']).get('value', {}) my_order.write(value)