【odoo14】第十八章、自動化測試
阿新 • • 發佈:2021-03-13
當我們開發大型應用的時候,通過自動化測試可以大幅提高應用的健壯性。每年,odoo都會發布新版本,自動化測試對於應用的迴歸測試非常有幫助。幸運的是,odoo框架有不同自動化測試用例。odoo主要包括三種測試方案:
* Python test case: 用於測試Python的業務邏輯測試
* JavaScript Qunit test: 用於測試JavaScript的實現
* Tours: 用於測試Python和JavaScript的互動情況
本章包含:
* 新增python測試用例
* 執行python測試用例
* 為客戶端側的測試用例配置(Headless Chrome)
* 新增客戶端側的QUnit測試用例
* 新增嚮導的測試用例
* 執行客戶端側的測試用用例
* 除錯測試端側的測試用例
* 為失敗的測試用例生成視訊或螢幕截圖
* 為測試填充隨機資料
# 技術需求
本章,我們將詳細討論測試用例的情況。為了能覆蓋所有的應用場景,我們建立了一個新的模型。模型如下:
```
class LibraryBook(models.Model):
_name = 'library.book'
name = fields.Char('Title', required=True)
date_release = fields.Date('Release Date')
author_ids = fields.Many2many('res.partner',
string='Authors')
state = fields.Selection(
[('draft', 'Not Available'), ('available', 'Available'), ('lost', 'Lost')],
'State', default="draft") color = fields.Integer()
def make_available(self):
self.write({'state': 'available'})
def make_lost(self):
self.write({'state': 'lost'})
```
對於JavaScript的測試用例,我們將使用第十五章中"建立使用者小部件"一節中的int_color小部件。
你可以在 (github)[ https://github.com/PacktPublishing/Odoo-14-Development-Cookbook-Fourth-Edition/tree/master/Chapter18/00_initial_module]
# 新增python測試用例
Python的測試用例用於測試業務邏輯的可用性。第五章,“伺服器側開發-基礎篇”,我們瞭解瞭如何調整現有業務邏輯。由於對現有模型的修改有可能會破壞原有的邏輯,測試就顯得尤為重要。在本節,我們將建立用於驗證改變圖書狀態的業務邏輯。
## 準備
## 步驟
1. 新增檔案tests/\_\_init__.py
```
from . import test_book_state
```
2. 新增tests/test_book_state.py檔案
```python
from odoo.tests.common import TransactionCase
class TestBookState(TransactionCase):
def setUp(self, *args, **kwargs):
super(TestBookState, self).setUp(*args, **kwargs)
self.test_book = self.env['library.book'].create({'name': 'Book 1'})
def test_button_available(self):
'''Make available button'''
self.test_book.make_available()
self.assertEqual( self.test_book.state, 'available', 'Book state should be changed to available')
def test_button_lost(self):
'''Make lost button'''
self.test_book.make_lost()
self.assertEqual( self.test_book.state, 'lost', 'Book state should be changed to lost')
```
3. 執行測試用例
```
./odoo-bin -c server.conf -i my_library --test-enable
```
檢視執行日誌,測試用例資訊如下
```
... INFO test odoo.addons.my_library.tests.test_ book_state: Starting TestBookState.test_button_available ...
... INFO test odoo.addons.my_library.tests.test_book_state: Starting TestBookState.test_button_lost ...
... INFO test odoo.modules.loading: Module my_library loaded in 0.79s (incl. 0.12s test), 179 queries (+10 test)
```
如果報錯,"INFO"》》"ERROR"。
## 原理
在odoo中,測試用例新增在tests/目錄。odoo將自動識別該目錄並執行測試用例。
> 注意
> 我們需要在tests/\_\_init__.py檔案中新增我們的測試用例。
Odoo中使用了python的unittest包。詳細瞭解見 https://docs.python.org/3.5/library/ unittest.html。odoo通過對unittest的簡單封裝,實現了多個非常有幫助的類,可用於簡化測試用例。在我們的例子中,我們使用了TransactionCase。現在TransactionCase可在單獨的食物中執行測試用例。在測試用例執行成功後,將會回滾。意味著,下一個測試用例也將在初始化的環境下執行。
以test_開頭的類方法將被認為是測試用例。在我們的例子中,我們添加了兩個測試用例。可用於檢查圖書的狀態。self.assertEqual方法可用於檢查測試用例是否執行正常。
> 重要資訊
> setUp()方法將在每一個測試用例前執行,因此在本節,我們添加了兩個測試用例,因此setUp()將呼叫兩次。TransactionCase將負責在每次測試用例執行完後進行回滾。
## 更多
測試單元中還提供瞭如下測試類:
* SingleTransactionCase: 所有的測試用例將在一個事務中執行,因此第一個測試用例中對記錄的修改將體現在第二個測試用例中。所有的測試用例執行完成後再進行回滾。
* SavepointCase: 測試用例將執行在特定的場景下(對記錄進行修改後save point,然後測試用例在此基礎上進行測試)。這可確保在進行大型的測試時,可快速的生成測試資料。我們可通過setUpClass()類進行生產測試資料。
# 執行python測試用例
當我們在啟動odoo例項時傳入--test-enabled,測試用例將在模組完成安裝後立刻執行。如果你想在所有的模組完成安裝後再執行,或者僅想執行某一個模組的測試用例,可通過tagged()裝飾器實現。本章,我們將介紹如何使用該裝飾器。
## 準備
## 步驟
1. 新增tagged()裝飾器,並在所有模組完成安裝後執行
```python
from odoo.tests.common import TransactionCase, tagged
@tagged('-at_install', 'post_install')
class TestBookState(TransactionCase):
···
```
2. 執行測試用例
```
./odoo-bin -c server.conf -i my_library --test-enable
```
3. 檢查服務日誌,顯示如下:
```
... INFO book odoo.modules.loading: 9 modules loaded in 1.87s, 177 queries (+0 extra)
... INFO book odoo.modules.loading: Modules loaded.
... INFO book odoo.service.server: Starting post tests
... INFO book odoo.addons.my_library.tests.test_book_ state: Starting TestBookState.test_button_available ...
... INFO book odoo.addons.my_library.tests.test_book_ state: Starting TestBookState.test_button_lost ...
... INFO book odoo.service.server: 2 post-tests in 0.14s, 10 queries
```
如上顯示在所有模組完成安裝後(post_install)執行測試用例。
## 原理
預設,測試用例被標記為*standard, at_install及模組的名稱*。因此,如果你並沒有使用tagged裝飾器,將預設是如上標識。
在我們的案例中,我們希望在安裝所有模組之後執行測試用例。為此,我們向TestBookState類添加了一個tagged()裝飾器。預設情況下,測試用例具有at_install標記。由於這個標記,您的測試用例將在模組安裝後立即執行;它不會等待其他模組被安裝。我們不希望這樣,所以為了刪除at_install標記,我們向標記函式添加了-at_install。以-為字首的標籤將刪除該標籤。
通過向tagged()函式新增-at_install,我們在模組安裝後停止了測試用例的執行。由於我們沒有在這裡指定任何其他標記,測試用例將不會執行。
因此,我們添加了一個post_install標記。這個標記指定測試用例需要在所有模組安裝完成後執行。
如您所見,預設情況下,所有的測試用例都是用標準標記標記的。Odoo將執行所有用標準標籤標記的測試用例,以防您不想一直執行特定的測試用例,而只想在被請求時執行測試用例。要做到這一點,你需要通過在tagged()裝飾器中新增-standard來移除standard標籤,你需要新增一個像這樣的自定義標籤:
```
@tagged('-standard', 'my_custom_tag')
class TestClass(TransactionCase):
···
```
在使用--test-enable時所有非標的測試用例將不會執行。可通過--test-tags=name執行目標測試用例,如下:
```
./odoo-bin -c server.conf -i my_library --test-tags=my_custom_ tag
```
## 更多
在測試用例的開發過程中,只為一個模組執行測試用例是很重要的。預設情況下,模組的技術名稱是作為標記新增的,因此可以使用模組的技術名稱和--test-tags選項。例如,如果你想為my_library模組執行測試用例,那麼你可以這樣執行伺服器:
```
./odoo-bin -c server.conf -i my_library --test-tags=my_library
```
這裡給出的命令將執行my_library模組中測試用例,但是它仍然會根據at_install和post_install選項來決定順序。
# 為客戶端側的測試用例配置Headless Chrome
Odoo使用Headless Chrome來執行JavaScript測試用例和tour測試用例。Headless Chrome是一種不需要完整UI就可以執行Chrome的方法。這樣,我們就可以在與終端使用者相同的環境中執行JavaScript測試用例。在這個食譜中,我們將安裝Headless Chrome和其他包來執行JavaScript測試用例。
## 步驟
您將需要安裝Chrome來啟用JavaScript測試用例。對於模組的開發,我們主要使用桌面作業系統。因此,如果你的系統上安裝了Chrome瀏覽器,那麼就不需要單獨安裝。您可以使用桌面Chrome執行客戶端測試用例。請確保您的Chrome版本高於Chrome 59。Odoo也支援Chromium瀏覽器。
> 小貼士
> Headless Chrome客戶端測試用例在macOS和Linux上執行良好,但Odoo不支援Windows上的Headless Chrome測試用例。
當您想要在生產伺服器或伺服器作業系統上執行測試用例時,情況會略有變化。伺服器作業系統沒有GUI,所以你需要安裝不同的Chrome。如果你使用的是基於debian的作業系統,你可以使用以下命令安裝Chromium:
```
apt-get install chromium-browser
```
> 重要資訊
> Ubuntu 18.04伺服器版預設沒有啟用universe儲存庫。因此,有可能安裝鉻瀏覽器將顯示安裝候選錯誤。要修復此錯誤,可以使用以下命令啟用universe儲存庫:sudo add-apt-repository universe。
Odoo還支援WebSockets用於JavaScript測試用例。為此,Odoo使用websocket客戶端Python庫。要安裝它,使用以下命令:
```
pip3 install websocket-client
```
## 原理
Odoo使用無頭瀏覽器進行JavaScript測試用例。這背後的原因是它在後臺執行測試用例,所以它也可以在伺服器作業系統上執行。Headless Chrome更喜歡在後臺執行Chrome瀏覽器,而不需要開啟GUI瀏覽器。Odoo在後臺開啟一個Chrome標籤,並開始執行測試用例。它還使用jQuery的QUnit來進行JavaScript測試用例。在接下來的幾個食譜中,我們將為自定義JavaScript小部件建立一個QUnit測試用例。
對於測試用例,Odoo在一個單獨的程序中打開了Headless Chrome,所以為了找到在這個程序中執行的測試用例的狀態,Odoo伺服器使用WebSockets。websocket-client Python庫用於管理WebSockets,以便從Odoo伺服器與Chrome通訊。
# 新增客戶端側的QUnit測試用例
在Odoo中,建立新的領域或檢視是非常簡單的。只需幾行XML,就可以定義一個新的檢視。然而,在底層,它使用了大量的JavaScript。在客戶端修改/新增新特性是複雜的,可能會破壞一些東西。大多數客戶端問題不會被注意到,因為大多數錯誤只顯示在控制檯中。因此,在Odoo中使用QUnit測試用例來檢查不同JavaScript元件的正確性。
## 準備
## 步驟
按照以下步驟向int_color小部件新增JavaScript測試用例:
1. 新增/static/tests/colorpicker_tests.js
```
odoo.define('colorpicker_tests', function(require){
'use strict';
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
Qunit.module('Color Picker Tests',{
beforeEach: function(){
this.data = {
book: {
fields: {
name: {string:"Name", type:"char"},
color: {string:"color", type:"integer"},
},
records: [
{id:1, name:'Book 1', color: 1},
{id:2, name:'Book 2', color: 3}
]
}
};
}
}, function(){
// 步驟2中內容
});
});
```
2. 新增QUnit測試用例:
```
QUnit.only('int_color field test cases', async function (assert) {
assert.expect(2);
var form = await testUtils.createView({
View: FormView,
model: 'book',
data: this.data,
arch: '' +
'' +
'',
res_id: 1,
});
await testUtils.form.clickEdit(form);
assert.strictEqual(form.$('.o_int_colorpicker .o_ color_pill').length, 10, "colorpicker should have 10 pills");
await testUtils.dom.click(form.$('.o_int_colorpicker .o_color_pill:eq(5)'));
assert.strictEqual(form.$('.o_int_colorpicker .o_ color_5').hasClass('active'), true,
"click on pill should make pill active");
form.destroy();
});
```
3. 在/views/template.xml註冊測試文