淺談pytest+HttpRunner如何展開介面測試

數棧DTinsight發表於2021-10-25

數棧是—站式大資料開發平臺,我們在github和gitee上有一個有趣的開源專案:FlinkX,FlinkX是一個基於Flink的批流統一的資料同步工具,既可以採集靜態的資料,也可以採集實時變化的資料,是全域、異構、批流一體的資料同步引擎。大家喜歡的話請給我們點個star!star!star!

github開源專案:

gitee開源專案:https://gitee.com/dtstack_dev_0/flinkx

有興趣的話,歡迎大家加入我們的交流社群:30537511(釘釘群)


| 作者:石瀟


軟體測試有多種多樣的方法和技術,可以從不同角度對它們進行分類。其中,根據軟體生命週期,針對不同的測試物件與目標,可將測試過程分為4個階段:單元測試、整合測試、系統測試和驗收測試。本文著重介紹瞭如何借用pytest與httprunner進行介面自動化測試。


一、 什麼是介面測試

In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information. The exchange can be between software, computer hardware, peripheral devices, humans, and combinations of these.

根據wiki中的定義,介面是一個共享的邊界,計算機系統的多個獨立元件透過它交換資訊。這些資訊的交換可以基於軟體、硬體、外部裝置、人和它們之間的組合。根據上述定義,可以面向軟體、硬體、互動裝置等展開介面測試。軟體的介面測試是面向獨立元件之間介面的一種測試,主要用於檢測內外部系統及內部各子系統之間的互動點。測試的重點在於檢查邏輯正確性、互動依賴性、資料正確性。


二、 引入自動化背景

基於以下幾個情況,數棧引入自動化測試,以期提高測試效率,保障交付產品質量。

  • 產品迭代迅速

目前數棧產品已經迭代至Release4.3版本。每過幾個月進行一次產品release更新讓迴歸測試的工作量持續上升。介面自動化測試可以很好的減少迴歸工作量。

  • 應用系統日趨複雜

數棧目前自研8款產品和多個外掛,產品之間的互動與產品-外掛之間的互動日趨複雜。客觀現實帶來了更大的測試風險,測試消耗成本越來越高,花費的時間也越來越長。介面自動化測試可以提高測試效率。

  • 部署環境多樣

作為一款面向大資料的產品,除了開源的Hadoop,還需要適配TDH、CDH、HDP等其他引擎。同時,各種客戶的POC環境也需要大量人力支援。


三、 自動化技術選型

介面測試可以使用的工具有很多,Postman、Jmeter、REST-Assured、SoapUI、httpclient等等。數棧產品使用的是HttpRunner這個框架。相比較於前幾類工具,它具有以下特點:

  • 簡單易用

雖然前幾款工具中有圖形化介面可以讓人直觀的進行操作,但HttpRunner以“關鍵字”的優勢可以讓QA快速的上手框架,對程式碼能力要求低。根據對應的關鍵字填入相應的值,即可生成一條測試用例。

  • 可擴充套件性強

HttpRunner的V3版本支援了pytest,可以方便的藉助pytest外掛解決介面測試中遇到的問題,如資料驅動、引數化等。jUnit雖然也具有擴充套件性強的特點,但是Java語言對於QA來說太重,且學習成本比HttpRunner更高。 

  • 易於整合CI

HttpRunner支援CLI命令,可以方便的接入Jenkins、Gitlab CI等工具。

  •  錄製回放

透過Charles、Fiddler等工具將請求到處為.har檔案,然後透過HttpRunner提供的命令,就可以將.har檔案轉換成json/yaml檔案。

數棧產品曾使用過Jmeter作為介面自動化工具。Jmeter擁有視覺化圖形介面,透過拖動元件資訊就可完成用例編排,方便QA使用。但是Jmeter的內建函式不能滿足於複雜的數棧產品,雖然可以選擇beanshell來寫工具指令碼,但其難以除錯,第三方包管理困難等問題使編寫效率低下。同時Jmeter容易出現編碼混亂、日誌不易於檢視等問題。


HttpRunner作為一款優秀的開源框架,在GitHub上擁有2.6k star,集簡單易用、擴充套件性強、易於整合、錄製回放等特性於一體,相比較於Jmeter更適用於數棧自動化實踐。


四、 自動化測試用例

數棧整體自動化測試架構如下圖所示。從上到下可分為使用者層、配置層、用例層、資料來源。使用者可以透過Docker映象、Pipeline、定時任務來觸發自動化任務。執行的結果記錄到禪道,然後透過接入自研的EasyV進行展示。配置檔案分為兩類:一類是應用系統資訊,如業務資料庫資訊、域名、賬號密碼等;另一類是資料來源資訊,用於用例的執行,現在支援的資料來源有MySQL、Oracle、Kafka、HBase等等。從業務層面分,可以分為8個產品,每個產品編寫各自的用例;從執行層面分,可分為介面測試和場景測試。若選擇介面測試,則會執行所有產品的介面測試用例。下面拿介面測試用例進行舉例說明。



一條介面測試用例可分為兩部分:配置和測試步驟。先來看配置。


config = (
        Config("測試建立專案介面")
            .variables(
            **{
                "cookie": Cookie().get_cookie(),
                "url": api.aiworks.aiworks_api.AiworksApi.create_project.value,
                "tenant_name": ENV_CONF.uic.tenant_name,
                "project_name": project_name
            }
        )
            .base_url(ENV_CONF.base_url.rdos)
    )


首先第一個遇到的問題就是獲取cookie。基本上介面都需要cookie或者token校驗才能呼叫,因此將獲取cookie的方法抽象提取成一個get_cookie(),避免了每個用例寫一遍登陸。這個方法就屬於架構圖中預置函式的模組。url、tenant_name、project_name三個變數是後續測試步驟中所需要用到的變數值,這些都預先在variables中定義好。其中還可以看到有AiworksApi、ENV_CONF這幾個檔案。AiworksApi是所有Aiwork產品的介面列舉類,對介面內容進行管理;ENV_CONF包含了整個自動化專案的配置資訊,是一個配置檔案,屬於配置層。


teststeps = [
        Step(
          RunRequest("開始請求建立專案介面")
            .post("$url")
            .with_headers(**{"cookie": "$cookie"})
        .with_json(
            {
                    "enableCycleSchedule": "$enableCycleSchedule",
                     "isSwitchJupyter": "$isSwitchJupyter",
                     "projectAlias": "$projectAlias",
                     "projectDesc": "$projectDesc",
                     "projectEngineList": "$projectEngineList",
                     "projectName": "$projectName",
                     "switchGpu": "$switchGpu"
                }
        )
            .validate()
            .assert_equal("status_code", 200)
            .assert_equal("body.code", "$code")
            .assert_contains("body.message", "$message")
            .teardown_hook("${delete_project()}")
        )
    ]

然後在測試步驟部分,整個teststeps由Step陣列構成。可以看到建立專案這個介面只有一個Step,整個Step分為post、with_headers、with_json、validate、teardown_hooke5個部分組成。其中,with_json中key-value鍵值對的值全都是引用的方式來取得,而不是寫死的固定值。這樣就可以將用例與資料區分開來。而具體的值則透過@pytest.mark.parameterize這個裝飾器傳入,params裡定義了這個用例所需的所有欄位值。整體用例編寫思路為“用例與資料分離”,避免修改測試用例需要改動大量的程式碼。

@pytest.mark.parametrize("params", params)
    def test_start(self, params):
        super().test_start(params)

所以整體來看,HttpRunner框架提供了一個用例模版--由多個關鍵字組成,使用者只需要將模版中的內容填充完整,就可以完成一條用例的編寫。


五、自動化成果

自2021年4月自動化立項以來,已編寫超過900條用例,8個子產品介面覆蓋率平均達到60%以上。每日透過Jenkins構建定時任務,在持續整合環境對最新的程式碼進行自動化測試。同時,自動化測試接入了測試環境、客戶環境中使用。在提供環境資訊完備的情況下,可以在一天內接入自動化,並執行得出報告給到QA,大大減少了迴歸工作量,從原先3-4周的時間縮短到1-2周完成。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69995740/viewspace-2839145/,如需轉載,請註明出處,否則將追究法律責任。

相關文章