【odoo14】第十八章、自動化測試

  • 2021 年 3 月 12 日
  • 筆記

當我們開發大型應用的時候,通過自動化測試可以大幅提高應用的健壯性。每年,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)[ //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
  1. 添加tests/test_book_state.py文件
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')
  1. 運行測試用例
./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包。詳細了解見 //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()裝飾器,並在所有模組完成安裝後執行
from odoo.tests.common import TransactionCase, tagged

@tagged('-at_install', 'post_install')
class TestBookState(TransactionCase):
···
  1. 運行測試用例
./odoo-bin -c server.conf -i my_library --test-enable
  1. 檢查服務日誌,顯示如下:
... 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中內容
    });
});
  1. 添加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: '<form string="Books">' +
            '<group>' +
            '<field name="name"/>' +
            '<field name="color" widget="int_color"/>' +
            '</group>' +
            '</form>',
        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();
});
  1. 在/views/template.xml註冊測試文件
<template id="qunit_suite" name="colorpicker test" inherit_id="web.qunit_suite">
    <xpath expr="." position="inside">
        <script type="text/javascript" src="/my_library/static/tests/ colorpicker_tests.js" />
    </xpath>
</template>

運行測試用例

./odoo-bin -c server.conf -i my_library,web --test-enable

檢查日誌

... INFO test odoo.addons.web.tests.test_js.WebSuite: console log: "Color Picker Tests" passed 2 tests.

原理

在odoo中,JavaScript測試用例添加在/static/tests目錄中。步驟1,我們新增了colorpicker_tests.js文件。我們引入了formView及test_utils。因為我們創建的ini_color小部件是作用於form視圖的,因此我們還需要引入web.FormView。
web.test_utils為我們提供了構建js測試用例的實體。如果你不了解js的引入機制,可參考第十四章”擴展CSS及JavaScript”。
odoo的客戶端測試用例是通過QUit框架實現了,它是用於JS單元測試的JQuery框架。參考//qunitjs.com/。beforeEach函數會運行測試用例前執行,可用於初始化測試數據。函數由QUit框架提供。
我們在beforeEach函數中初始化了一些數據。客戶端測試用例是運行在一個獨立(mock)的環境中,它並不與資料庫進行交互。因此,我們需要創建一些測試數據。在內部,odoo創建了虛擬環境模擬RPC,this.data模式資料庫。this.data中的keys相當於資料庫中表,values相當於表中的欄位及行。在我們的例子中,我們添加了book的表,book表有兩個欄位name(char)及color(integer)。在這,我們可以使用所有的欄位類型,比如,{string:”M2oField”, type:”many2one”, relation:”partner”}。我們在records中添加了兩條記錄。
下一步,我們藉助Quit.test函數創建了測試用例。函數的第一個參數是string類型,用於描述測試用例的用途。第二個參數是具體測試用例程式碼邏輯的函數。函數由QUnit框架調用,assert實例作為參數傳遞到函數體內。在我們的例子中,我們在assert.expect函數中傳入了測試用例的個數。我們一共有兩個測試用例,因此我們傳入2。
我們計劃測試編輯模式下的int_color小部件。所以我們通過testUtils.createView創建了編輯模式下的form視圖。createView接收不同參數:

  • View: 我們創建的視圖。
  • model: 視圖作用於的模型的名稱。
  • data: 模擬數據。
  • arch: 視圖的定義內容。
  • res_id: 展示的記錄的ID。該選項作用於form視圖。在我們的案例中,form視圖展示book 1的數據,因為res_id為1。

在使用int_color小部件創建表單視圖之後,我們添加了兩個測試用例。第一個測試用例用於檢查UI上彩色藥片的數量,第二個測試用例用於檢查藥片在單擊後是否被正確激活。我們從斷言的QUnit框架的效用中得到了嚴格的函數。如果前兩個參數匹配,則strictEqual函數通過測試用例。如果它們不匹配,則測試用例將失敗。

更多

還有一些assert函數可以用於QUnit測試用例,比如assert.deepEqual,assert.ok,assert.notOk。要了解有關QUnit的更多資訊,請參閱//qunitjs.com/上的文檔。

添加嚮導的測試用例

現在您已經看到了Python和JavaScript測試用例。它們都在一個孤立的環境中工作,它們彼此之間不相互作用。為了測試JavaScript和Python程式碼之間的集成,使用了嚮導測試用例。

準備

對於本節,我們將繼續使用上一節中的my_library模組。我們將添加一個巡迴測試用例來檢查圖書模型的流程。另外,確保您已經安裝了web_tour模組,或者已經將web_tour模組依賴項添加到清單中。

步驟

按照以下步驟添加圖書的嚮導測試用例:

  1. 添加一個/static/src/js/my_library_tour.js文件:
odoo.define('my_library.tour', function (require) {
    "use strict";
    var core = require('web.core');
    var tour = require('web_tour.tour');
    var _t = core._t;
    tour.register('library_tour', {
        url: "/web",
        test: true,
        rainbowManMessage: _t("Congrats, you have listed a book."),
        sequence: 5,
    }, [tour.stepUtils.showAppsMenuItem(), // Place step 3 here
    ]);
});
  1. 添加測試步驟
{
    trigger: '.o_app[data-menu-xmlid="my_library.library_ base_menu"]',
    content: _t('Manage books and authors in <b>Library app</b>.'),
    position: 'right'
}, {
    trigger: '.o_list_button_add',
    content: _t("Let's create new book."),
    position: 'bottom',
}, {
    trigger: 'input[name="name"]',
    extra_trigger: '.o_form_editable',
    content: _t('Set the book title'),
    position: 'right',
    run: function (actions) {
        actions.text('Test Book');
    },
}, {
    trigger: '.o_form_button_save',
    content: _t('Save this book record'),
    position: 'bottom',
}
  1. 添加到test資源
<template id="assets_tests" name="Library Assets Tests" inherit_id="web.assets_tests">
    <xpath expr="." position="inside">
        <script type="text/javascript" src="/my_library/ static/tests/my_library_tour.js" />
    </xpath>
</template>
  1. 添加一個/tests/test_tour.py文件,通過HttpCase運行tour,如下所示:
from odoo.tests.common
import HttpCase, tagged class TestBookUI(HttpCase):
    @tagged('post_install', '-at_install') 
    def test_01_book_tour(self):
    """Books UI tour test case"""
    self.browser_js("/web",
        "odoo.__DEBUG__.services['web_tour.tour']. run('library_tour')",
        "odoo.__DEBUG__.services['web_tour.tour']. tours.library_tour.ready",
        login = "admin")

運行測試用例

./odoo-bin -c server.conf -i my_library --test-enable

運行日誌如下:

...INFO test odoo.addons.my_library.tests.test_tour.TestBookUI: console log: Tour library_tour succeeded

原理

為了創建tour測試用例,您需要首先創建UI tour。如果你想了解更多關於UI tours的資訊,請參考第15章「Web客戶端開發」中的通過嚮導提升交互感一節。
步驟1,我們用library_tour註冊了一個新的tour。
步驟2,我們為嚮導測試用例添加了步驟。
與之前的嚮導案例相比,這裡有兩個主要變化。首先,我們為嚮導定義添加了一個test=true參數;其次,我們添加了一個額外的屬性,run。在run函數中,您必須編寫邏輯來執行通常由用戶執行的操作。例如,在嚮導的第四步中,我們要求用戶輸入書名。
為了自動化這個步驟,我們添加了一個run函數來設置title欄位中的值。run函數將操作實用程式作為參數傳遞。這提供了一些執行基本操作的快捷方式。最重要的問題如下:

  • actions.click(element): 點擊元素
  • actions.dblclick(element): 雙擊元素
  • actions.tripleclick(element): 三擊元素
  • actions.text(string): 設置input的值
  • actions.drag_and_drop(to, element):拖放元素
  • actions.keydown(keyCodes, element): 在元素上觸發特定的按鍵事件
  • actions.auto(): 默認動作。當在tour步驟中沒有傳遞run函數時,將執行actions.auto()。這通常會單擊步驟中觸發的元素。這裡唯一的例外是輸入元素。如果觸發的是input,那麼tour將在輸入中設置默認值Test。這就是為什麼我們不需要向所有步驟添加run函數。
    另外,如果默認操作不夠,您也可以手動執行整個操作。在下一個步驟中,我們想要為顏色選擇器設置一個值。注意,我們使用的是手動操作,因為默認值在這裡不起作用。因此,我們使用基本的jQuery程式碼添加了run方法來單擊顏色選擇器的第三個顏色圓點。在這裡,可通過this.$archor屬性獲取需觸發的元素。
    默認情況下,註冊的嚮導將提高終端用戶的交互體驗。為了測試它們,你需要在Headless Chrome中運行它們。為此,您需要使用HttpCase觸發測試用例。這提供了browser_ js方法,該方法打開URL並執行作為第二個參數傳遞的命令。如下所示:
odoo.__DEBUG__.services['web_tour.tour'].run('library_tour')

在我們的示例中,嚮導測試用例的名稱將作為browser_js的第一個參數。隨後的參數待執行的測試用用例,最後一個參數是執行測試用例用戶名。

運行客戶端側的測試用用例

odoo提供了通過UI運行客戶端測試用例的方法,我們可以看到測試用例每一步的執行情況。

步驟

我們可以通過UI運行QUit和嚮導測試用例。我們可以激活開發者模式,查看通過UI執行的選項。

通過UI運行QUit測試用例

點擊BUG圖標,選擇Run JS Tests,如下:

這會打開QUit實例,並逐個運行測試用例,如下圖。默認,僅展示測試失敗的用例。如果想顯示所有的測試用例,取消Hide passed tests選項。

通過UI運行嚮導測試

點擊BUG圖標,選擇Start Tour,如下:

將展示嚮導測試用例的列表,我們可點擊後面的start啟動相應的測試用例:

如果您啟用了測試資產模式,那麼測試之旅只會顯示在列表中。如果在列表中沒有找到library_tour,請確保已激活測試資產模式。

原理

QUnit的UI是由QUnit框架本身提供的。在這裡,您可以為模組篩選測試用例。您甚至可以為一個模組運行一個測試用例。通過UI,您可以看到每個測試用例的進度,並且可以深入到測試用例的每個步驟。在內部,Odoo只是在Headless Chrome打開相同的URL。
點擊Run tours選項將顯示可用的tours列表。通過點擊列表上的播放按鈕,您可以運行嚮導測試用例。注意,當嚮導通過命令行選項運行時,它將在回滾事務中運行,因此在嚮導成功後,通過嚮導所做的更改將被回滾。但是,當tour從UI運行時,它的工作方式就像用戶正在操作它一樣,這意味著tour所做的更改不會回滾並停留在那裡,所以要小心使用這個選項。

調試測試端側的測試用例

開發複雜的客戶端測試用例是件非常頭痛的事。本節,我們將學習如何調試客戶端測試用例,如何運行其中一個測試用例。

準備

步驟

  1. 用QUit.onlg替換/static/tests/colorpicker_tests.js中的QUit.test測試方法:
QUnit.only('int_color field test cases', function (assert) {
  1. 在createView中添加debug參數如下:
var form = testUtils.createView({ 
	View: FormView,
	model: 'book',
	data: this.data,
	arch: '<form string="Books">' +
		'<group>' +
		'<field name="name"/>' +
		'<field name="color" widget="int_color"/>' +
		'</group>' +
		'</form>', 
	res_id: 1,
	debug:true
});

點擊 Run JS Tests:

原理

步驟1,我們用QUnit.only替換了QUnit.test。這將只運行這個測試用例。在測試用例的開發過程中,這可以節省時間。注意,使用QUnit.only將會終止通過命令行選項運行的測試用例。這隻能用於調試或測試,並且只能在從UI打開測試用例時使用,所以不要忘記在開發完成後將其替換為QUnit.test。
在我們的QUnit測試用例示例中,我們創建了表單視圖來測試int_ color小部件。如果您在UI中運行QUnit測試用例,您將了解到您不能在UI中看到創建的表單視圖。在QUnit套件的UI中,您只能看到日誌。這使得開發QUnit測試用例非常困難。為了解決這個問題,在createView函數中使用了debug參數。在步驟2中,我們在createView函數中添加了debug: true。這將在瀏覽器中顯示test form視圖。在這裡,您可以通過瀏覽器調試器定位文檔對象模型(Document Object Model, DOM)元素。

警告
在測試用例的最後,我們通過destroy()方法銷毀視圖。如果您已經銷毀了視圖,那麼您將無法在UI中看到表單視圖,因此為了在瀏覽器中看到它,請在開發期間刪除這一行。這將幫助您調試測試用例。

為失敗的測試用例生成影片或螢幕截圖

Odoo使用headless CHrome。這開啟了新的可能性。從Odoo 12開始,您可以錄製失敗的測試用例的影片,也可以對失敗的測試用例進行截屏。

步驟

為測試用例錄製影片需要一個ffmpeg包。

  1. 安裝包
apt-get install ffmpeg
  1. 要生成影片或螢幕截圖,您需要提供一個目錄位置來存儲影片或螢幕截圖。
  2. 如果你想生成一個測試用例的截屏(影片),使用——截屏命令,如下:
./odoo-bin -c server.conf -i my_library --test-enable --screencasts=/home/pga/odoo_test/
  1. 如果你想生成一個測試用例的截圖,使用——screenshosts命令,如下:
./odoo-bin -c server.conf -i my_library --test-enable --screenshots=/home/pga/odoo_test/

原理

為了為失敗的測試案例生成截屏/截屏,您需要使用保存影片或影像文件的路徑運行伺服器。當您運行測試用例時,如果測試用例失敗了,Odoo將在給定目錄中保存失敗測試用例的截圖/影片。
為了生成測試用例的影片,Odoo使用了ffmpeg包。如果您沒有在伺服器上安裝這個包,那麼它將只保存一個失敗的測試用例的截圖。在安裝這個包之後,您將能夠看到任何失敗的測試用例的mp4文件。

小貼士
為測試用例生成影片會佔用磁碟上更多的空間,所以請謹慎使用此選項,並且只在確實需要時使用。

請記住,螢幕截圖和影片只會為失敗的測試用例生成,所以如果您想要測試它們,您需要編寫一個失敗的測試用例。

為測試填充隨機數據

到目前為止,我們已經看到了用於檢測業務邏輯中的錯誤或bug的測試用例。然而,有時我們需要用大量的數據來測試我們的開發。生成大量數據可能是一項乏味的工作。Odoo提供了一套工具,可以幫助您為模型生成大量隨機數據。在本節,我們將使用populate命令為library.book模型生成測試數據。

準備

對於本節,我們將繼續使用上一節的my_library模組。我們將添加_populate_factories方法,它將用於生成測試數據。

步驟

  1. 在my_library模組中添加populate文件夾,添加__init__.py文件。
from . import library_data
  1. 添加my_library/populate/library_data.py文件:
from odoo import models
from odoo.tools import populate


class BookData(models.Model):
    _inherit = "library.book"
    _populate_sizes = {"small": 10, "medium": 100, "large": 500}

    def _populate_factories(self):
        return [
            ("name", populate.constant("Book no {counter}")),
        ]
  1. 運行命令
./odoo-bin populate -–models=library.book –-size=medium -c server.conf -i my_library

這將為圖書生成100個單位的數據。生成數據後,流程將被終止。要查看該書的數據,運行不帶填充參數的命令。

原理

步驟1,新增生成數據文件目錄。
步驟2,添加生成數據程式碼。使用populate_factories生成隨機數據。_populate_factories方法返回模型欄位的工廠,這些工廠將用於生成隨機數據。模型具有必需的name欄位,因此在我們的示例中,我們返回了name欄位的生成器。這個生成器將用於為圖書記錄生成隨機數據。我們已經使用了populate.constant;當我們在數據生成過程中進行迭代時,這將生成不同的名稱。
除了populate.constant,Odoo提供了其他幾個生成器來填充數據,如下:

  • populate.randomize(list):從給定的列表返回隨機元素
  • populate.cartesian(list): 與randomize類似,但儘可能保所列表中所有的內容。
  • populate.constant(str): 用於生成格式化字元串。還可以傳遞formatter參數來格式化值。默認情況下,格式化程式是一個字元串格式函數。
  • populate.compute(function): 當您想要根據您的函數計算一個值時使用。
  • populate.randint(a, b): 用於在a和b參數之間生成一個隨機數。

另一個重要的屬性是_populate_sizes。基於–size參數,表示想要生成的數據的數量。
步驟3,我們生成了圖書的模型。為了生成測試數據,我們需要使用–size和–model參數。odoo將使用_populate方法生成隨機記錄。_populate方法調用_populate_factories方法生成隨機數據。

小貼士
如果多次運行populate命令,數據也將生成多次。小心使用這一點非常重要:如果在生產資料庫中運行該命令,它將在生產資料庫中生成測試數據。這是你要避免的。

更多

有時,您也希望生成關係數據。例如,對於書籍,您可能還希望創建作者或租借記錄。要管理這樣的記錄,可以使用_populate_dependencies屬性:

class BookData(models.Model):
	_inherit = 'library.book'
	_populate_sizes = {'small': 10, 'medium': 100, 'large': 500}
	_populate_dependencies = ['res.users', 'res.company']

這將在填充當前模型之前填充依賴項數據。一旦完成,你可以通過populated_models註冊表訪問已填充的數據:

company_ids = self.env.registry.populated_models['res.company']

這裡給出的行將為您提供在為當前模型生成測試數據之前填充的公司列表。