摘要:本文介紹了一種針對關系型數據庫的復雜計算代碼邏輯測試方法,該方法借助關系型數據庫提供的存儲過程服務,可以在不依賴代碼邏輯的情況下,直接編寫自動驗證用例,并保存整個計算流程的中間計算結果,提供簡單可依賴運算正確性質量保證。
1 引言
在許多報表和統計類產品中,存在大量的復雜計算功能,這些公式往往有數十步的計算過程,上萬條數據統計記錄,以及跨多個關系型數據庫的數據依賴,甚至是多種語言的混合實現。更棘手的是:往往為了節省數據存儲資源,數據庫不存儲這些復雜計算邏輯的中間結果,而是直接存儲最終計算結果,為前端提供數據。
在運營產品“盤古”系統中,為了衡量一個銷售人員近期的業績情況,要經過一系列的統計和計算為每個銷售人員打一個綜合評分,根據綜合評分對銷售人員分配銷售任務,整個公式如下(具體業務參數和公式內涵與本文主題無關,不再冗述):
上面列舉的計算還不包括大量的查詢、排序、求最大值和最小值、求平均值等邏輯運算。在持久層的設計中,從原始的數據記錄到最終的得分,中間沒有存儲任何的計算過程中間值,這點設計上沒有問題,任何數據型系統都應該在不影響性能的情況下盡量節約存儲空間。但是,復雜的運算導致了功能實現的軟件質量風險,也給QA設計相應的測試用例帶來的一定困難,下文將詳細介紹,該類問題的測試解決方案。
2 針對復雜計算功能的測試方法
對于此類復雜計算的功能測試,一般采用以下兩種方式進行測試:
(一) 手工用例核算的測試方法。賬單、財務報表等系統的測試,QA很多采用這種手工核算的測試方法,對每一個計算項目進行手工計算核對,以此來保證代碼邏輯的計算正確性。但是這種愚公移山的辦法,用在上述這種沒有計算過程中間值的情況下,就十分不可靠而又低效了。第一,對于萬級別以上的數據查詢、排序,求最大值、最小值和平均值都是不可能完成的任務;第二,即使我們結合SQL語句進行查詢、排序等邏輯運算,計算結果經過上述10個公式的手工計算難以保證用例計算的正確性;第三,手工計算效率太低且成功率沒有保障,每次升級后,回歸測試人力開銷太大。
(二) 基于單元測試框架的測試方法。這種方法是對各個邏輯接口進行插樁,根據條件分支通過等價類劃分和排列組合設計各種條件組合用例來進行測試。這種方式復用性強,用例可長期維護和自動化回歸測試,是種較好的解決方案。但是,對于一些數據依賴性強的系統,需要大量準備測試數據,且這些數據互相之間有邏輯關聯,數據構造帶來了很大的工作量,并且還要對數據本身進行驗證,降低了測試效率。
3基于存儲過程的測試方法
上述兩種方案為目前針對復雜計算功能所最常采用的三種方法,各有長短優劣。在盤古系統相關模塊的測試中,結合了手工核算的手工用例和基于單元測試框架的自動化用例的測試思想,采用了一種基于存儲過程的自動測試結合手工核算的方法,實現的基本思路如下:
Step 1. 將復雜的數學計算邏輯拆分成若干個計算片段,保證每個計算片段都可以較容易的計算出來,每個計算片段生成一個中間值。
Step 2. 在測試環境中,如表1所示,構建一張測試數據表,除ID外,為每個計算片段設置一個表字段,用于存儲每個記錄的計算片段中間值。
Step 3. 按照Step 1拆分的計算片段邏輯,直接使用數據庫存儲過程實現整個計算過程,數據查詢、排序,求最大值、最小值和平均值等運算都可以方便的使用數據庫提供的接口,且存儲過程支持變量和游標,邏輯實現起來十分簡便。
Step 4. 測試執行時,流程如圖1所示,先執行被測功能代碼邏輯,再基于同一個數據源執行存儲過程的測試用例,最后對比測試表最終計算結果和被測功能代碼邏輯的計算結果。如果出現測試用例和代碼邏輯計算不一致的情況,QA可根據計算過程,方便的進行手工核對,定位出錯點時測試用例還是代碼邏輯。若用例出錯,及時修正測試用例;若測試用例沒有出錯,則可以根據計算過程的中間值,結合debug工具,定位代碼邏輯的bug點。
這種基于存儲過程的測試方式總結下來有以下優勢:
(一) 與基于單元測試框架的方法相比,實現起來簡單、輕量、高效。直接面向數據庫進行操作,不依賴原有代碼邏輯和第三方框架,開發用例代碼量小,。
(二) 在測試表中留下計算全過程,方便錯誤的跟蹤。
(三) 與手工核算的方法相比,本測試方法QA時間開銷主要在測試設計階段,測試執行時間短,且便于維護,方便自動化回歸測試。
由于盤古項目的計算流程較為復雜且需要許多業務相關知識,這里為舉一個簡化的模擬場景來說明本文所述基于存儲過程的測試方法。表2為原始記錄數據表(tb_os_log),記錄了銷售人員工作拜訪日志,
表3為銷售人員得分表(tb_os_point),這個表已經預先存入參加評分的銷售ID,
下面兩個公式(5)是從原始記錄到實際得分的計算公式,
其中, 為在 到 時間段內銷售人員拜訪任務總量, 為銷售人員的成交訂單數量, 為轉化率, 為銷售人員中的最高轉化率, 為銷售人員中的最低轉化率, 為最終銷售人員的得分。被測計算功能是將tb_os_log通過上述數學計算得到結果,并存入tb_os_point表的total_point字段。
測試時,首先設計并創建測試表(tb_os_test),表4為測試表的各字段說明,is_pass字段為0本條數據通過測試,is_pass字段為1本條數據測試不通過。
原文轉自:http://www.anti-gravitydesign.com