Lego-美團點評接口自動化測試實踐

Lego-美團點評接口自動化測試實踐

2018-02-07html

轉自:Lego-美團點評接口自動化測試實踐前端

目錄java

1、概述
  1.1 接口自動化概述
  1.2 提升ROI
    針對「減小投入成本」
    針對「增長使用率」
  1.3 Lego的組成
2、腳本設計
  2.1 Lego的作法
  2.2 測試腳本
  2.3 配置文件
    使用SQL最大的好處就是靈活
    多標籤時,能夠分組展現
    報告更美觀豐富
    支持多團隊
3、用例設計
  3.1 一些思考
    通用
    校驗
    健壯
    易用
  3.2 Lego接口自動化測試用例
  3.3 參數化
    「參數化」實例
    「參數化」的場景
  3.4 先後置動做
    「先後置動做」實例
    Q & A
  3.5 執行各部分
    測試發起
    數據 / 環境準備
    測試執行
    檢查點校驗
    測試結果
    後期優化
4、網站功能
  4.1 站點開發
  4.2 總體組成
  4.3 使用-平常維護
    Step 1
    Step 2
    Step 3
  4.4 用例編輯
  4.5 在線調試
  4.6 用例生成工具
  4.7 執行結果分析
  4.8 敗緣由跟蹤 
  4.9 代碼覆蓋率分析 
  4.10 用例優化方向
  4.11 收集反饋/學習
5、總結mysql

 

自動化測試平臺目標:git

  1. 便於建立、維護、評估、組織用例
  2. 便於執行(篩選執行用例、執行調度(當即、定時、週期性)、執行順序、併發執行)
  3. 便於對執行結果校驗、分析、問題定位
  4. 便於統計(經過率、覆蓋率、工做量、用例和bug分佈、趨勢)
    測試報告(不一樣的形式:網頁、Excel、pdf,報告模版、配置,報告合併)
    測試報表(不一樣時間,不一樣被測模塊)
  5. 便於部署(測試環境SIT、UAT,準發佈環境/預生產環境,生產環境)

自動化測試平臺問題:github

  1. 平臺中,用例依賴在執行中如何解決,如何併發執行?
  2. 如何分類、組織用例(按功能模塊、按測試階段、按重要性、按依賴、按用例設計方法)?

 

1、概述


 返回web

1.1 接口自動化概述

衆所周知,接口自動化測試有着以下特色:正則表達式

  • 低投入,高產出。
  • 比較容易實現自動化。
  • 和UI自動化測試相比更加穩定。

如何作好一個接口自動化測試項目呢?sql

我認爲,一個「好的」自動化測試項目,須要從「時間」「人力」「收益」這三個方面出發,作好「取捨」。數據庫

不能因爲被測系統發生一些變動,就致使花費了幾個小時的自動化腳本沒法執行。同時,咱們須要看到「收益」,不能爲了總想看到100%的成功,而少作或者不作校驗,可是校驗多了維護成本必定會增多,可能天天都須要進行大量的維護。

因此作好這三個方面的平衡並不容易,常常能看到作自動化的同窗,作到最後就本末倒置了。 

1.2 提升ROI

想要提升ROI(Return On Investment,投資回報率),咱們必須從兩方面入手:

  1. 減小投入成本。
  2. 增長使用率。

 

針對「減小投入成本」

咱們須要作到:

  • 減小工具開發的成本。儘量的減小開發工具的時間、工具維護的時間,儘量使用公司已有的,或是業界成熟的工具或組件。
  • 減小用例錄入成本。簡化測試用例錄入的成本,儘量多的提示,若是能夠,開發一些批量生成測試用例的工具。
  • 減小用例維護成本。減小用例維護成本,儘可能只用在頁面上作簡單的輸入便可完成維護動做,而不是進行大量的代碼操做。
  • 減小用例優化成本。當團隊作用例優化時,能夠經過一些統計數據,進行有針對性、有目的性的用例優化。

 

針對「增長使用率」

咱們須要作到:

  • 手工也能用。不僅是進行接口自動化測試,也能夠徹底用在手工測試上。
  • 人人能用。每個須要使用測試的人,包括一些非技術人員均可以使用。
  • 當工具用。將一些接口用例當成工具使用,好比「生成訂單」工具,「查找表單數據」工具。
  • 天天測試。進行每日構建測試。
  • 開發的在構建以後也能觸發測試。開發將被測系統構建後,能自動觸發接口自動化測試腳本,進行測試。

因此,我這邊開發了Lego接口測試平臺,來實現我對自動測試想法的一些實踐。先簡單瀏覽一下網站,瞭解一下大概是個什麼樣的工具。

首頁:
image

用例維護頁面:
image

自動化用例列表:
image

在線執行結果:
image

用例數量統計:
image

 

1.3 Lego的組成

Lego接口測試解決方案是由兩部分組成的,一個就是剛剛看到的「網站」,另外一個部分就是「腳本」。

下面就開始進行「腳本設計」部分的介紹。 

2、腳本設計


 返回

2.1 Lego的作法

Lego接口自動化測試腳本部分,使用很常見的Jenkins+TestNG的結構。

image

相信看到這樣的模型並不陌生,由於不少的測試都是這樣的組成方式。

將自動化測試用例存儲至MySQL數據庫中,作成比較常見的「數據驅動」作法。

不少團隊也是使用這樣的結構來進行接口自動化,沿用的話,那在之後的「推廣」中,學習和遷移成本低都會比較低。 

2.2 測試腳本

首先來簡單看一下目前的腳本代碼:

public class TestPigeon { String sql; int team_id = -1; @Parameters({"sql", "team_id"}) @BeforeClass() public void beforeClass(String sql, int team_id) { this.sql = sql; this.team_id = team_id; ResultRecorder.cleanInfo(); } /** * XML中的SQL決定了執行什麼用例, 執行多少條用例, SQL的搜索結果爲須要測試的測試用例 */ @DataProvider(name = "testData") private Iterator<Object[]> getData() throws SQLException, ClassNotFoundException { return new DataProvider_forDB(TestConfig.DB_IP, TestConfig.DB_PORT, TestConfig.DB_BASE_NAME,TestConfig.DB_USERNAME, TestConfig.DB_PASSWORD, sql); } @Test(dataProvider = "testData") public void test(Map<String, String> data) { new ExecPigeonTest().execTestCase(data, false); } @AfterMethod public void afterMethod(ITestResult result, Object[] objs) {...} @AfterClass public void consoleLog() {...} }

image

有一種作法我一直不提倡,就是把測試用例直接寫在Java文件中。這樣作會帶來不少問題:修改測試用例須要改動大量的代碼;代碼也不便於交接給其餘同窗,由於每一個人都有本身的編碼風格和用例設計風格,這樣交接,最後都會變成由下一個同窗所有推翻重寫一遍;若是測試平臺更換,沒法作用例數據的遷移,只能手動的一條條從新輸入。

因此「測試數據」與「腳本」分離是很是有必要的。

網上不少的範例是使用的Excel進行的數據驅動,我這裏爲何改用MySQL而不使用Excel了呢?

在公司,咱們的腳本和代碼都是提交至公司的Git代碼倉庫,若是使用Excel……很顯然不方便平常常常修改測試用例的狀況。使用MySQL數據庫就沒有這樣的煩惱了,因爲數據與腳本的分離,只需對數據進行修改便可,腳本每次會在數據庫中讀取最新的用例數據進行測試。同時,還能夠防止一些操做代碼時的誤操做。

這裏再附上一段我本身寫的DataProvider_forDB方法,方便其餘同窗使用在本身的腳本上:

import java.sql.*; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * 數據源 數據庫 * * @author yongda.chen */
public class DataProvider_forDB implements Iterator<Object[]> { ResultSet rs; ResultSetMetaData rd; public DataProvider_forDB(String ip, String port, String baseName, String userName, String password, String sql) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url = String.format("jdbc:mysql://%s:%s/%s", ip, port, baseName); Connection conn = DriverManager.getConnection(url, userName, password); Statement createStatement = conn.createStatement(); rs = createStatement.executeQuery(sql); rd = rs.getMetaData(); } @Override public boolean hasNext() { boolean flag = false; try { flag = rs.next(); } catch (SQLException e) { e.printStackTrace(); } return flag; } @Override public Object[] next() { Map<String, String> data = new HashMap<String, String>(); try { for (int i = 1; i <= rd.getColumnCount(); i++) { data.put(rd.getColumnName(i), rs.getString(i)); } } catch (SQLException e) { e.printStackTrace(); } Object r[] = new Object[1]; r[0] = data; return r; } @Override public void remove() { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } 

2.3 配置文件

上面圖中提到了「配置文件」,下面就來簡單看一下這個XML配置文件的腳本:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Pigeon Api測試" parallel="false">

    <test name="xxx-xxx-service">
        <parameter name="sql" value="SELECT * FROM API_PigeonCases WHERE team_id=2 AND isRun=1 AND service='xxx-xxx-service' AND env='beta';"/>
        <classes>
            <class name="com.dp.lego.test.TestPigeon"/>
        </classes>
    </test>

    <listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter"/>
        <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
    </listeners>
</suite>

image

對照上圖來解釋一下配置文件:

  • SQL的話,這裏的SQL主要決定了選取哪些測試用例進行測試。
  • 一個標籤,就表明一組測試,能夠寫多個標籤。
  • 「listener」是爲了最後可以生成一個ReportNG的報告。
  • Jenkins來實現每日構建,可使用Maven插件,經過命令來選擇須要執行的XML配置。

 

這樣作有什麼好處呢?

使用SQL最大的好處就是靈活

image

如上面的這個例子,在數據庫中會查詢出下面這56條測試用例,那麼這個標籤就會對這56條用例進行逐一測試。

 

多標籤時,能夠分組展現

image

使用多個標籤來區分用例,最大的好處就是也能在最後的報告上,達到一個分組展現的效果。

 

報告更美觀豐富

image

因爲使用了ReportNG進行報告的打印,因此報告的展現要比TestNG自帶的報告要更加美觀、而且能自定義展現樣式,點開能看到詳細的執行過程。

image

若是有執行失敗的用例,一般報錯的用例會在最上方優先展現。 

支持多團隊

image

當兩個團隊開始使用時,爲了方便維護,將基礎部分抽出,各個團隊的腳本都依賴這個Base包,而且將Base包版本置爲「SNAPSHOT版本」。使用「SNAPSHOT版本」的好處是,以後我對Lego更新,各個業務組並不須要對腳本作任何改動就能及時更新。

 

當更多的團隊開始使用後,比較直觀的看的話是這個樣子的:

image

每一個團隊的腳本都依賴於個人這個Base包,因此最後,各個業務團隊的腳本就變成了下面的這個樣子:

image

能夠看到,使用了Lego以後:

  • 沒有了Java文件,只有XML文件
  • xml中只須要配置SQL。
  • 執行和調試也很方便。
  • 能夠右鍵直接執行想要執行的測試配置。
  • 可使用maven命令執行測試:
    • mvn clean test -U -Dxml=xmlFileName 。
    • 經過參數來選擇須要執行的xml文件。
  • 也可使用Jenkins來實現定時構建測試。

因爲,全部測試用例都在數據庫因此這段腳本基本不須要改動了,減小了大量的腳本代碼量。

有些同窗要問,有時候編寫一條接口測試用例不僅是請求一下接口就行,可能還須要寫一些數據庫操做啊,一些參數可能還得本身寫一些方法才能獲取到啊之類的,那不code怎麼處理呢?

下面就進入「用例設計」,我將介紹我如何經過統一的用例模板來解決這些問題。 

3、用例設計


 返回

3.1 一些思考

我在作接口自動化設計的時候,會思考通用、校驗、健壯、易用這幾點。 

通用

  • 簡單、方便
    • 用例數據與腳本分離,簡單、方便。
    • 免去上傳腳本的動做,能避免不少沒必要要的錯誤和維護時間。
    • 便於維護。
  • 模板化
    • 抽象出通用的模板,可快速拓展。
    • 數據結構一致,便於批量操做。
    • 專人維護、減小多團隊間的重複開發工做。
    • 因爲使用了統一的模板,那各組之間即可交流、學習、作有效的對比分析。
    • 若是之後這個平臺再也不使用,或者有更好的平臺,可快速遷移。
  • 可統計、可拓展
    • 可統計、可開發工具;如:用例數統計,某服務下有多少條用例等。
    • 可開發用例維護工具。
    • 可開發批量生成工具。 

校驗

在寫自動化腳本的時候,都會想「細緻」,而後「寫不少」的檢查點;但當「校驗點」多的時候,又會由於不少緣由形成執行失敗。因此咱們的設計,須要在保證充足的檢查點的狀況下,還要儘量減小誤報。

  • 充足的檢查點
    • 能夠檢查出被測服務更多的缺陷。
  • 儘可能少的誤報
    • 能夠減小不少的人工檢查和維護的時間人力成本。
  • 還要
    • 簡單、易讀。
    • 最好使用一些公式就能實現本身想要的驗證。
    • 通用、靈活、多樣。
    • 甚至能夠用在其餘項目的檢查上,減小學習成本。 

健壯

執行測試的過程當中,不免會報失敗,執行失敗可能的緣由有不少,簡單分爲4類:

image

  • 被測系統出錯,這部分實際上是咱們但願看到的,由於這說明咱們的自動化測試真正地發現了一個Bug,用例發揮了它的價值,因此,這是咱們但願看到的。
  • 測試工具出錯,這部分實際上是咱們不但願看到的,由於很大可能咱們今天的自動化至關於白跑了。
  • 測試數據錯誤,這是咱們要避免的,既然數據容易失效,那我在設計測試平臺的時候,就須要考慮若是將全部的數據跑「活」,而不是隻寫「死」。
  • 不可抗力,這部分是咱們也很無奈的,可是這樣的狀況不多發生。

那針對上面的狀況:

  • 參數數據失效
    • 支持實時去數據庫查詢。
    • 支持批量查。
  • IP進場發生變動
    • 自動更新IP。
  • 靈活、可複用
    • 支持批量維護。
    • 接口測試執行前生成一些數據。
    • 接口執行完成後銷燬一些數據。
    • 支持參數使用另外一條測試用例的返回結果。
    • 支持一些請求參數實時生成,如token等數據,從而減小數據失效的問題。

經過這些手段,提升測試用例的健壯性,讓每一條自動化測試用例都能很好的完成測試任務,真正發揮出一條測試用例的價值。 

易用

  • 簡單
    • 功能強大,但要人人會用。
    • 非技術人員也要會用。
  • 減小代碼操做
    • 讓自動化開發人員注意力能更多的放在用例自己,而不是浪費在可有可無的開發工做上面。
  • 還要
    • 配置能複用。
    • 通用、易學。
    • 一些數據能自動生成。 

3.2 Lego接口自動化測試用例

說了這麼多,那咱們來看一下一條Lego接口測試用例的樣子。

一條Lego自動用例執行順序大概是以下圖這樣:

image

簡單區分一下各個部分,能夠看到:

image

那上面圖中提到了兩個名詞:

  • 「參數化」
  • 「先後置動做」

下面會先對這兩個名詞作一個簡單的介紹。 

3.3 參數化

好比一個請求須要用到的參數。

{
    "sync": false, "cityId": 1, "source": 0, "userId": 1234, "productId": 00004321 } 

這個例子中有個參數"productId": 00004321,而因爲測試的環境中,表單00004321極可能一些狀態已經發生了改變,甚至表單已經刪除,致使接口請求的失敗,那麼這時候,就很適合對"productId": 00004321進行參數化,好比寫成這樣:

{
    "sync": false,
    "cityId": 1,
    "source": 0,
    "userId": 1234,
    "productId": ${myProductId}
}

因此對「參數化」簡單的理解就是:

經過一些操做,將一個「值」替換掉測試用例裏的一個「替代字符」

${myProductId} 的值能夠經過配置獲取到:

  • Key-Value
    • 配置 Value=00004321。
  • SQL獲取
    • 執行一個select語句來實時查詢獲得可用ID。
  • 已有測試用例
    • 某個接口接口測試用例的返回結果。

 

「參數化」實例

下面咱們來看一個「參數化」的實例:

(1) 首先咱們在參數化維護頁面中新建一個參數化,shopdealid

image

經過配置咱們能夠看到這個參數的值,是執行了一條SQL後,取用執行結果中DealID字段的值。

(2) 在用例中,將須要這個表單號的地方用${shopdealid}替代。

image

那在編寫測試用例的時候,你們能夠看一下這個放大的圖片,在這裏的ProductID的值並非硬代碼一個固定的表單號,而是選擇了剛纔配置的參數化數據。

(3) 執行結果中,${shopdealid} 變爲實時查詢數據庫的來的一個真實的表單號。

image

從結果中能夠看到,咱們的這個參數被替換成了一個有效的值,而這個值就是咱們剛剛配置的那個SQL實時查詢而來的。 

「參數化」的場景

多個測試用例使用同一個參數進行測試

如50條測試用例都使用同一個id做爲參數進行測試,這時候咱們須要變動這個id。

無參數化時:

  • 須要修改50次,即每條測試用例中的id都得進行修改。
  • 可能會有遺漏。
    有參數化時:
  • id部分用 ${myID} 替代。
  • 須要修改的話,在「參數化維護」頁面中維護 ${myID}這條數據就能夠。修改一次,全部使用${myID}的用例都配置完成。

 

測試數據過時致使測試用例執行失敗

如一條用例參數須要傳入token,可是Token會由於時間問題而致使過時,這時候用例就失敗了。

無參數化時:

  • 常常修改Token,或是寫一段id轉Token的代碼。
  • 方法可能會重複編寫。
  • 多個團隊之間可能實現方式也不一樣。

有參數化時:

  • 使用參數化工具,Lego統一管理。
  • 維護一個參數化 如:${測試用Token} = id:123

 

數據庫獲取有效測試數據

參數中須要傳入DealId做爲參數,寫死參數的話,若是這個DealId被修改引發失效,那這條測試用例就會執行失敗。

不使用Lego時:

  • 測試環境中,一個訂單時常會由於測試須要被修改數據,致使單號失效,最後致使自動化失敗。
  • 編寫相關代碼來作好數據準備工做。
  • 在代碼中編寫讀取數據庫的方法獲取某些內容。

在Lego上的方案:

  • 使用參數化,實時獲取sql結果,查詢出一條符合條件的dealId來實現。
  • 使用參數化,調用寫好的「生成訂單」接口用例實現,拿單號來實現。
  • 先後置動做,插入一條知足條件的數據。 

3.4 先後置動做

「先後置動做」的概念就比較好理解了:

在接口請求以前(或以後),執行一些操做

目前先後置動做支持6種類型:

  • 數據庫SQL執行
    • 有時候在執行接口請求前,爲了保證數據可用,可能須要在數據庫中插入或刪除一條信息,這時候就可使用先後置動做裏的「執行SQL語句」類型,來編寫在接口請求前(後)的 Insert 和 Delete 語句。
  • 已有測試用例執行
    • 好比當前測試用例的請求參數,須要使用另外一條測試用例的返回結果,這時候就可使用「執行測試用例」類型,寫上Lego上某條測試用例的ID編號,就能夠在當前用例接口請求前(後)執行這條測試用例。
    • 先後置動做中測試用例的返回結果能夠用於當前用例的參數,對測試用例返回結果內容的獲取上,也支持JsonPath和正則表達式兩種方式。
  • MQ消息發送
    • 在接口請求前(後)發送MQ消息。
  • HTTP請求
  • 等待時間
  • 自定義的Java方法
    • 若是上面的方法還知足不了需求,還能夠根據本身的須要,編寫本身的Java方法。
    • 能夠在Lego-Kit項目中,編寫本身須要的Java方法,選擇「執行Java方法」,經過反射實現自定義Java方法的執行。

這裏的SQL同時支持Select操做,這裏其實也是作了一些小的設計,會將查詢出來的所有的結果,放入到這個全局Map中。

好比查詢一條SQL獲得下表中的結果:

id    name       age       number   
0 張三 18 1122
1 李四 30 3344

那咱們可使用下面左邊的表達式,獲得對應的結果:

  • ${pre.name} ---- 獲得 「張三」å
  • ${pre.age} ---- 獲得 18
  • ${pre.number} ---- 獲得 1122

也能夠用:

  • ${pre.name[0]} ---- 獲得 「張三」
  • ${pre.age[0]} ---- 獲得 18
  • ${pre.number[0]} ---- 獲得 1122
  • ${pre.name[1]} ---- 獲得 「李四」
  • ${pre.age[1]} ---- 獲得 30
  • ${pre.number[1]} ---- 獲得 3344

這樣的設計,更加幫助在用例設計時,提供數據準備的操做。 

「先後置動做」實例

(1) 首先咱們在先後置維護頁面中新建一個動做,獲取庫存上限未賣光團單 。

image

這個配置也是能夠支持在線調試的,在調試中,能夠看到可使用的參數化:

image

(2) 在測試用例中的前置動做,添加獲取庫存上限未賣光團單 。

image

這樣就能夠在整個測試用例中,使用${pre.ProductID},來替換掉原有的數據信息。

(3) 最後請求接口,返回了執行成功 。

image

Q & A

Q:那若是一樣是獲取三個參數,使用3個「參數化的Select操做」和使用1個「前置動做的Select操做」又有什麼不一樣呢?

A: 不一樣在於執行時間上。
好比,咱們查詢最新的有效團單的「單號」「下單人」和「手機號」三個字段。
使用3個「參數化的Select操做」:可能當執行${單號}的時候獲得的訂單號是「10001」,可是當執行到${下單人}的時候,可能有誰又下了一單,可能取到的下單人變成了「10002」的「李四」而不是「10001」的「張三」了,最後可能「單號」「下單人」和「手機號」三個字段去的數據並不是同一行的數據。
而使用「前置動做的Select操做」:就能夠避免上面的問題,由於全部字段的數據是一次性查詢出來的,就不會出現錯位的狀況。

Q : 那「參數化的Select操做」和「前置動做的Select操做」這樣不一樣的取值時機又有什麼好用之處呢?

A : 因爲「前置動做」必定是接口請求前執行,「參數化」必定是用到的時候才執行這樣的特性。
因此在檢查點中,若是要驗證一個數據庫字段在通過接口調用後發生了變動,那使用「前置動做」和「參數化」同時去查詢這個字段,而後進行比較,不一致就說明發生了變化。
因此根據使用場景,選擇合適的參數化方式,很重要,選擇對了,能大大提高測試用例的測試數據健壯性。 

3.5 執行各部分

回到一開始的流程圖,能夠按照一類一類來看執行過程。 

測試發起

image

測試發起基本仍是使用的Jenkins,穩定、成熟、簡單、公司工具組支持,也支持從Lego的Web頁面進行執行操做。 

數據 / 環境準備

image

使用 @DataProvider 的方式,從DB數據庫中讀取測試用例,逐一執行進行測試。 

測試執行

image

在正式執行測試用例以前,會先進行一波參數替換的動做,在調用接口以後,還會執行一次參數替換動做。

image

參數替換後會進行前置動做的執行,而後在調用接口以後還會執行測試後動做,最後執行後置動做。

image

接口請求這部分就沒什麼好說的了,就是經過接口請求的參數,請求對應的接口,拿到返回結果。

這裏的話是爲了方便通用,因此要求返回的結果都是使用的String類型。這樣作最大的好處就是。好比說我如今有一種新的接口類型須要接入。那隻須要寫一個方法可以請求到這個接口,而且拿到String類型的返回結果,就能夠很快將新的接口類型接入Lego測試平臺進行接口測試。 

檢查點校驗

image

檢查點部分是一條自動化測試用例的精髓,一條自動化測試用例是否能真正的發揮它的測試功能,就是看QA對這條測試用例的檢查點編寫是否作了良好設計。在Lego平臺上,目前我擁有的檢查點有6種不一樣的類型。

  • 異常檢查點
    • 當返回結果爲異常時,則會報錯。
    • 可是有時候爲了作異常測試,能夠將這個檢查點關掉。
  • 不爲空檢查點
    • 顧名思義,當出現""、"[]"、"{}"、null 這樣的的結果,都會報錯。也能夠根據本身用例的實際狀況關閉。
  • 包含檢查點
  • 不包含檢查點
    • 「包含」和「不包含」檢查點是將接口的返回結果做爲一個String類型來看,檢查全部返回內容中是否「包含」或「不包含」指定的內容。
  • 數據庫參數檢查點
    • 顧名思義,不作過多的解釋了。
  • JsonPath檢查點
    • 這是我在Lego上設計的最具備特點的一種檢查點類型。

JsonPath的基本寫法是{JsonPath語法}==value

JsonPath的語法和XPath的語法差很少,都是根據路徑的方法找值。這裏也是主要是針對返回結果爲JSON數據的結果,進行檢查。

具體的JsonPath語法能夠參考:https://github.com/json-path/JsonPath

說完了"JsonPath的語法",如今說一下"JsonPath檢查點的語法""JsonPath檢查點的語法"是我本身想的,主要針對如下幾種數據類型進行校驗:

 

(1) 字符串類型結果檢驗

  • 等於:==
  • 不等於:!==
  • 包含:=
  • 不包含:!=

例如:

  • {$.[1].name}==aa:檢查返回的JSON中第2個JSON的name字段是否等於aa。
  • {$..type}=='14':檢查返回的JSON中每個JSON的name字段是否等於aa。
  • {$.[1].type}==14 && {$.[1].orderId}==106712:一條用例中多個檢查用&&鏈接。
  • {$..orderId}!==12:檢查返回的JSON中每一個JSON的orderId字段是否不等於12。
  • {$..type}=1:檢查返回的JSON中每一個JSON的type字段是否包含1。
  • {$.[1].type}!=chenyongda:檢查返回的JSON中第2個JSON的type字段是否不包含chenyongda。

 

(2) 數值校驗

  • 等於:=
  • 大於:>
  • 大於等於:>=
  • 小於:<
  • 小於等於:<=

例如:

  • {$.[0].value}<5:檢查返回的JSON中第1個JSON的value字段的列表是否小於3。
  • {$.[1].value}>4:檢查返回的JSON中第2個JSON的value字段的列表是否大於4。

 

(3) List結果檢驗

  • list長度:.length
  • list包含:.contains(param)
  • list成員:.get(index)

例如:

  • {$..value}.length=3:檢查返回的JSON中每一個JSON的value字段的列表是否等於3。
  • {$.[0].value}.length<5:檢查返回的JSON中第1個JSON的value字段的列表是否小於3。
  • {$.[1].value}.length>4:檢查返回的JSON中第2個JSON的value字段的列表是否大於4。
  • {$..value}.contains('222'):檢查返回的JSON中每一個JSON的value字段的列表是否包含222字符串。
  • {$.[0].value}.contains(1426867200000):檢查返回的JSON中第1個JSON的value字段的列表是否包含1426867200000。
  • {$.[0].value}.get(0)=='222':檢查返回的JSON中第1個JSON的value字段的列表中第1個內容是否等於222。
  • {$..value}.get(2)='22':檢查返回的JSON中每一個JSON的value字段的列表中第3個內容是否包含22。

 

(4) 時間類型處理

時間戳轉日期時間字符串:.todate

例如:

  • {$..beginDate}.todate==2015-12-31 23:59:59:檢查返回的JSON中beginDate這個時間戳轉換成日期後是否等於2015-12-31 23:59:59。

 

當JsonPath返回的結果是列表的形式時

檢查點 檢查點等號左邊 指望值 驗證效果
{$.value}=="good" ['good', 'good', 'bad', 'good'] "good" 做爲4個檢查點,會拿列表裏的每一個對象逐一和「指望值」進行檢驗,每一次對比都是一個獨立的檢查點。
{$.value}==["good"] ['good', 'good', 'bad', 'good'] ["good"] 做爲1個檢查點,做爲一個總體作全量比對。
{$.value}==['a', 'b'] [['a', 'b'],['a', 'b'],['a', 'b', 'c']] ['a', 'b'] 做爲3個檢查點,道理和1同樣,列表中的數據分別和指望值作比較。

 

除此以外,還有很是多的花樣玩法

JsonPath中的檢查支持「參數化」和「先後置動做」,因此會看到不少如:

{$.param}='${param}' && {$.param}==${pre.param}

這樣的檢查點:

「參數化」和「先後置動做」也支持遞歸配置,這些都是爲了可以讓接口自動化測試用例寫的更加靈活好用。 

測試結果

image

使用ReportNG能夠打印出很漂亮的報告。

報告會自定義一些高亮等展現方式,只須要在ReportNG使用前加上下面的語句,就能夠支持「輸出逃逸」,可以使用HTML標籤自定義輸出樣式。

 System.setProperty("org.uncommons.reportng.escape-output", "false");

後期優化

image

當使用Jenkins執行後,經過Jenkins API 、和Base包中的一些方法,定時獲取測試結果,落數據庫,提供生成統計圖表用。 

4、網站功能


 返回

4.1 站點開發

既然打算作工具平臺了,就得設計方方面面,惋惜人手和時間上的不足,只能我一人利用下班時間進行開發。也算是擔任了Lego平臺的產品、後端開發、前端開發、運維和測試等各類角色。

Jenkins+TestNG+ReportNG+我本身開發的基本接口自動化測試Base jar包,基本上沒什麼太大難度。可是站點這塊,在來美團點評以前,還真沒開發過這樣的工具平臺,這個算是個人第一個帶Web界面的工具。邊Google邊作,沒想到不久還真的架起來了一個簡易版本。

使用 Servlet + Jsp 進行開發,前端框架使用Bootstrap,前端數據使用jstl,數據庫使用MySQL,服務器使用的公司的一臺Beta環境Docker虛擬機,域名是申請的公司內網域名,並開通北京上海兩側內網訪問權限。

功能上基本都是要知足的,界面上,雖然作不到驚豔吧,可是絕對不能醜,功能知足,可是長得一副80年代的界面,我本身都會嫌棄去使用它,因此界面上我仍是花了一些時間去調整和設計。熟練之後就快多了。 

4.2 總體組成

image

目前Lego由五個不一樣的項目組成,分別是「測試腳本」、「Lego-web頁面項目」、「用於執行接口測試的base包」、「小工具集合Lego-kit」和「lego-job」,經過上圖能夠看出各項目間的依賴關係。

細化各個項目的功能,就是下圖:

image

簡單來講,網站部分和腳本是分離的,中間的紐帶是數據庫。因此,沒有網站,腳本執行一點問題也沒有;一樣的,網站的操做,和腳本也沒有關係。 

4.3 使用-平常維護

Step 1

image

天天上班來會收到這樣的測試郵件,經過郵件能知道昨晚執行的狀況。若是有報錯,能夠點擊「詳細報告連接」,跳轉到在線報告。 

Step 2

image

在現報告能夠直接看到執行報錯的信息,而後點擊「LEGO維護傳送門」,能夠跳轉到Lego站點上,進行用例維護。 

Step 3

跳轉到站點上之後,能夠直接展現出該條測試用例的全部信息。定位,維護、保存,維護用例,能夠點擊「執行」查看維護後的執行結果,維護好後「保存」便可。

僅僅3步,1~2分鐘便可完成對一條執行失敗的用例進行定位、調試和維護動做。 

4.4 用例編輯

image

經過頁面,咱們就能夠對一條測試用例進行:

  • 新建
  • 複製
  • 編輯
  • 刪除
  • 是否放入每日構建中進行測試 

4.5 在線調試

image

lego-web項目一樣的使用base進行的用例執行,因此執行結果和打印都與腳本執行的一致的。 

4.6 用例生成工具

爲了更方便的寫用例,針對部分接口開發了一鍵批量生成用例的小工具。 

4.7 執行結果分析

經過Jenkins接口、Base包中基礎Test方法,將結果收集到數據庫,便於各組對測試結果進行分析。

image

這是天天執行後成功率走勢圖:

image

也能夠按月進行統計,生成統計的圖表,幫助各個團隊進行月報數據收集和統計。 

4.8 失敗緣由跟蹤

有了能直觀看到測試結果的圖表,就會想要跟蹤失敗緣由。

image

因此在成功率數據的右邊,會有這樣的跟蹤失敗緣由的入口,也能夠很直觀地看到哪一些失敗的緣由尚未被跟蹤。點開後能夠對失敗緣由進行記錄。

image

最後會有生成圖表,能夠很清晰地看到失敗緣由以及失敗類型的佔比。 

4.9 代碼覆蓋率分析

結合Jacoco,咱們能夠對接口自動化的代碼覆蓋率進行分析。

image

在多臺Slave機器上配置Jacoco仍是比較複雜的,因此能夠開發覆蓋率配置輔助工具來幫助測試同窗,提升效率。

image

 

4.10 用例優化方向

除了上面的圖表,還會給用例優化提供方向。

image
經過用例數量統計的圖表,咱們能夠知道哪些服務用例還比較少,哪些環境的用例還比較少,能夠比較有針對性的進行測試用例的補充。

image
經過失敗緣由的圖表,咱們能夠改善本身用例中的「參數化」和「先後置動做」的使用,增長測試用例的健壯性。

image
經過線上接口調用量排序的圖表。咱們能夠有效的知道優先維護哪些服務的測試用例,經過表格中,咱們能夠看到,哪些服務已經覆蓋了測試用例,哪些沒有被覆蓋, 給各組的QA制定用例開發計劃,提供參考。

image
同時在維護接口自動化測試的時候,都會看到用例評分的狀況,來協助QA提升用例編寫的質量。 

4.11 收集反饋/學習

還作了「需求白板」,用來收集使用者的需求和Bug。除此以外,Lego平臺已經不僅是一個接口測試的平臺,還可讓想學習開發的QA領任務,學習一些開發技巧,提升本身的代碼能力。 

5、總結

    1. 爲了減小開發成本,使用比較常見的Jenkins+TestNG的腳本形式。
    2. 爲了簡化code操做,使用DB進行測試用例存儲,並抽象出用例摸版。
    3. 爲了減低新建用例成本,開發「用例維護頁面」和「一鍵生成」等工具。
    4. 爲了減低維護成本,加跳轉連接,維護一條用例成本在幾分鐘內。
    5. 爲了增長用例健壯性,設計了「參數化」、「先後置動做」等靈活的參數替換。
    6. 爲了易用和兼容,統一「返回結果」類型,統一「檢查點」的使用。
    7. 爲了接口自動化用例設計提供方向,結合Jacoco作代碼覆蓋率統計,並開發相關配置工具
    8. 爲了便於分析數據,從DOM、CAT、Jenkins上爬各類數據,在頁面上用圖表展現。
    9. 爲了優化用例,提供「用例打分」、「線上調用量排行」等數據進行輔助。
相關文章
相關標籤/搜索