天天看點

如何高效的進行接口測試?【工具篇】

一、簡介

1、目前接口測試的現狀

如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

2、常用方案

如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

3、存在問題

  • 開發人員在 Swagger 定義好文檔後,接口調試的時候還需要去 Postman 再定義一遍。
  • 前端開發 Mock 資料的時候又要去 mockjs 定義一遍,還需要手動設定 Mock 規則。
  • 測試人員需要去 JMeter 再定義一遍。
  • 前端根據 mockjs Mock 出來的資料開發完,後端根據 Swagger 定義的接口文檔開發完,各自都試測試通過了,本以為可以馬上上線,結果一對接發現各種問題:

    1、開發過程中接口變更了,隻修改了 Swagger,但是沒有及時同步修改 mockjs。

    2、後端開發的接口資料類型和文檔不一緻,肉眼難以發現問題。

  • 同樣,測試在 JMeter 寫好的測試用例,真正運作的時候也會發現各種不一緻。
  • 時間久了,各種不一緻會越來越嚴重。

4. Apifox 神器出現

Apifox=Postman + Swagger + Mock + JMeter

Apifox 是 API 文檔、調試、Mock、測試一體化協作平台,定位Postman + Swagger + Mock + JMeter。通過一套系統、一份資料,解決多個系統之間的資料同步問題。隻要定義好 API 文檔,API 調試、API 資料 Mock、API 自動化測試就可以直接使用,無需再次定義;API 文檔和 API 開發調試使用同一個工具,API 調試完成後即可保證和 API 文檔定義完全一緻。高效、及時、準确!      
如何高效的進行接口測試?【工具篇】

接口文檔定義:Apifox 遵循 OpenApi 3.0 (原Swagger)、JSON Schema 規範的同時,提供了非常好用的可視化文檔管理功能,零學習成本,非常高效。

接口調試:Postman 有的功能,比如環境變量、預執行腳本、後執行腳本、Cookie/Session 全局共享 等功能,Apifox 都有,并且和 Postman 一樣高效好用。

資料 Mock:内置 Mock.js 規則引擎,非常友善 mock 出各種資料,并且可以在定義資料結構的同時寫好 mock 規則。支援添加“期望”,根據請求參數傳回不同 mock 資料。最重要的是 Apifox 零配置 即可 Mock 出非常人性化的資料,具體在本文後面介紹。

接口自動化測試:提供接口集合測試,可以通過選擇接口(或接口用例)快速建立測試集。目前接口自動化測試更多功能還在開發中,敬請期待!目标是: JMeter 有的功能基本都會有,并且要更好用。

5、Apifox 十大核心功能

如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

二、對比Postman

1、Apifox 腳本文法100%相容 Postman腳本文法,Postman 腳本可以無縫遷移到 Apifox

如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

2、使用方式

2.1、以下兩個環節可添加腳本:

在将請求發送到伺服器之前,使用前置腳本。
收到響應後,使用 後置腳本(斷言設定)。      
如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

2.2、PostMan加斷言在Pre-request script和Tests

以下兩個環節可添加腳本:

在将請求發送到伺服器之前,使用 Pre-request script
收到響應後,使用 Tests      
如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】
如何高效的進行接口測試?【工具篇】

編輯

Apifox一套接口文檔,接口資料格式能做到前後端開發、測試等人員同時共享,可以省去不少溝通成本,對于提高團隊協作還是有一定的幫助的。Apifox是一款綜合性比較強的工具,學習成本肯定是比postman高些,如果你僅僅是個人開發,對文檔、測試沒那麼高要求的,小而美的PostMan還是比較好的選擇,如果你是大型項目,多團隊協作,Apifox确實是一個不錯的選擇.

寫腳本的易用性PostMan強很多,隻不過Apifox可以相容PostMan腳本。

三、Apifox常用斷言使用示例

1、斷言請求傳回的結果是否正确

// pm.response.to.have
pm.test('傳回結果狀态碼為 200', function () {
    pm.response.to.have.status(200);
});
 
// pm.expect()
pm.test('目前為Mock環境', function () {  
  pm.expect(pm.environment.get('env')).to.equal('production');
});
 
 
// response assertions 
pm.test('傳回結果沒有錯誤', function () {
    pm.response.to.not.be.error;
    pm.response.to.have.jsonBody('');
    pm.response.to.not.have.jsonBody('error');
});
 
 
// pm.response.to.be*
pm.test('傳回結果沒有錯', function () {
    // assert that the status code is 200
    pm.response.to.be.ok; // info, success, redirection, clientError,  serverError, are other variants
    // assert that the response has a valid JSON body
    pm.response.to.be.withBody;
    pm.response.to.be.json; // this assertion also checks if a body  exists, so the above check is not needed
});      
如何高效的進行接口測試?【工具篇】

2、将請求傳回的結果資料寫入環境變量

// 擷取 JSON 格式的請求傳回資料
var jsonData = pm.response.json();
 
// 将 jsonData.token 的值寫入環境變量
pm.environment.set('token', jsonData.token);      
如何高效的進行接口測試?【工具篇】

3、檢查 response body 是否包含某個字元串

pm.test('Body matches string', function() {
  pm.expect(pm.response.text()).to.include('available');
});      
如何高效的進行接口測試?【工具篇】

4、檢查 response body 是否包含等于字元串

pm.test('Body is correct', function() {
  pm.response.to.have.body('response_body_string');
});      
如何高效的進行接口測試?【工具篇】

5、檢查 json 值

pm.test('Your test id', function() {
  var jsonData = pm.response.json();
  pm.expect(jsonData.data.id).to.eql("1");
});      
如何高效的進行接口測試?【工具篇】

6、檢查 header 是否有設定 Content-Type

pm.test('Content-Type header is present', function() {
  pm.response.to.have.header('Content-Type');
});      
如何高效的進行接口測試?【工具篇】

7、檢查請求響應耗時是否低于 200 毫秒

pm.test('Response time is less than 200ms', function() {
  pm.expect(pm.response.responseTime).to.be.below(200);
});      
如何高效的進行接口測試?【工具篇】

8、檢查 HTTP 狀态碼是否為 200

pm.test('Status code is 200', function() {
  pm.response.to.have.status(200);
});      
如何高效的進行接口測試?【工具篇】

9、檢查 HTTP 狀态碼名稱是否包含某個字元串

pm.test('Status code name has string', function () {
  pm.response.to.have.status('OK');
});      
如何高效的進行接口測試?【工具篇】

10、是否正确的 POST 請求狀态碼

pm.test('Successful POST request', function() {
  pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});      
如何高效的進行接口測試?【工具篇】

四、斷言庫的使用示例

Apifox 内置了ChaiJS作為斷言庫,以下是常用的斷言測試腳本示例,但并非全部示例,更多用法請參考文檔: ChaiJS expect BDD library

1、斷言目标字元串包含另一個字元串

pm.test('斷言目标字元串包含另一個字元串', function() {
  pm.expect('foobar').to.have.string('bar');
});      
如何高效的進行接口測試?【工具篇】

2、斷言目标嚴格等于(===)某值

const TEN = 10;
pm.test('Check if number is equal to 10', function() {
  pm.expect(TEN).to.equal(10);
});      
如何高效的進行接口測試?【工具篇】

如果設定了deep标記,則斷言目标深度等于value

pm.test('斷言目标深度等于提供的 JSON', function() {
  pm.expect(data1).to.deep.equal(data2);
});      
如何高效的進行接口測試?【工具篇】

注意:

設定deep标記,然後使用equal和property斷言。該标記可以讓其後的斷言不是比較對象本身,而是遞歸比較對象的鍵值對。

3、斷言深度等于某值,相當于deep.equal(value)的簡寫

pm.test('斷言目标深度等于提供的 JSON', function() {
  pm.expect(data1).to.deep.equal(data2);
});      
如何高效的進行接口測試?【工具篇】

4、斷言目前環境

pm.test('Check if environment is production', function() {
  pm.expect(pm.environment.get('env')).to.equal('production');
});      
如何高效的進行接口測試?【工具篇】

5、斷言資料類型

pm.test('Check if target is string', function() {
  pm.expect('Postman').to.be.a('string');
});
pm.test('Check if target is an object', function() {
  pm.expect({ a: 1 }).to.be.an('object');
});
pm.test('Check if target is undefined', function() {
  pm.expect(undefined).to.be.an('undefined');
});      
如何高效的進行接口測試?【工具篇】

注意:

推薦在做其他斷言前,先使用 .a 方法檢查模闆的資料類型。
資料類型是大小寫敏感的。      
如何高效的進行接口測試?【工具篇】

6、斷言是否為空

pm.test('Check if array is empty', function() {
  pm.expect([]).to.be.empty;
});
pm.test('Check if string is empty', function() {
  pm.expect('').to.be.empty;
});      
如何高效的進行接口測試?【工具篇】

還可以使用 .a方法檢查資料類型後,在斷言是否為空。

示例:

pm.test('Check if array is empty', function() {
          
  pm.expect([]).to.be.an('array').that.is.empty;

});      
如何高效的進行接口測試?【工具篇】

7、斷言目标對象的鍵值

pm.test('Check if object contains all provided keys', function() {
  pm.expect({ a: 1, b: 2 }).to.have.all.keys('a', 'b');
});
pm.test('Checking if object contains any ONE of the keys', function() {
  pm.expect({ a: 1, b: 2 }).to.have.any.keys('a', 'b');
});
pm.test('Check if object contains any NONE of the provided keys', function() {
  pm.expect({ a: 1, b: 2 }).to.not.have.any.keys('c', 'd');
});      
如何高效的進行接口測試?【工具篇】

8、斷言目标對象是否包含指定屬性

pm.test('Check if object contains the property', function() {
 
 pm.expect({ a: 1 }).to.have.property('a');

});      
如何高效的進行接口測試?【工具篇】

注意:

目标對象必須是 object、set、array 或 map。
如果 .keys 前面沒有 .all 或 .any,則預設為 .all。
由于隻有部分資料類型的目标對象可使用 .keys 方法,建議先用 .a方法斷言資料類型。

pm.test('Check if object contains all the keys', function() {
  pm.expect({ a: 1, b: 2 })
    .to.be.an('object')
    .that.has.all.keys('a', 'b');
});      
如何高效的進行接口測試?【工具篇】

9、斷言目标對象的 length

pm.test('Check the length of the target', function() {
  pm.expect('foo').to.have.lengthOf(3);
});
pm.test('Check the size of the target', function() {
  pm.expect([1, 2, 3]).to.have.lengthOf(2);
});      
如何高效的進行接口測試?【工具篇】

10、斷言目标對象的成員 (members)

pm.test('Check if the target has same members as the array set', function() {
      
  pm.expect([1, 2, 3]).to.have.members([2, 1, 3]);

});      
如何高效的進行接口測試?【工具篇】

注意:

預設情況下, .members 使用嚴格比較。
members 的順序不會影響結果。      
如何高效的進行接口測試?【工具篇】

11、斷言目标對象包含指定 item

pm.test('Check if the target array includes the number provided', function() {
  pm.expect([1, 2, 3]).to.include(2);
});
pm.test(
  'Check if the target object includes the properties provided',
  function() {
    pm.expect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, b: 2 });
  },
);      
如何高效的進行接口測試?【工具篇】

注意: 建議在 .include 前先使用 .a 方法判斷資料類型。

示例:

pm.test(
  'Check if the target is an array that includes the number specified',
  function() {
    pm.expect([1, 2, 3])
      .to.be.an('array')
      .that.includes(2);
  },
);      

繼續閱讀