在上一份工作中,我有一部分工作是在維護一套接口自動化測試,這一篇文章,我來介紹這套接口自動化框架的設計思路。
我們來看一個簡單的PHP實現的超簡單的接口。
...
//報名驗證
private function apply_verify() {
$raid = $this->input->get_post('raid');
$mid = $this->input->get_post('mid');
if (!$raid || !$mid) {
$this->ret_json(10021, '參數錯誤');
}
$this->load->model('enlist_model');
$result = $this->enlist_model->get_enlist_by_raid_mid($raid, $mid, true);
if (!empty($result)) {
$this->ret_json(10101, '你已經報過名');
}
}
說明:
- 首先,它是一個POST接口。它需要兩個參數:raid 和 mid。
- 然后,判斷raid 和 mid 是否為空,為空返回:參數錯誤。
- 最后,調用 enlist_model 模型,通過
get_enlist_by_raid_mid
方法查詢是否為空,如果不為空返回:你已經報過名了。
接下來要做的事情不是寫用例,而是構造一條已經報名的數據。
創建 xx_enlist_test_data.php
文件
array(
'table_name'=>'xx_enlist',
'data'=>array(
array('eid'=>1,'raid'=>99,'mid'=>150,'phone'=>'01234567890'),
)
)
當自動化在執行之前,會先到數據庫的 xx_enlist
表插入這條數據,為什么要初始化數據?當然是為了保證接口測試用例的穩定性。比如,我在調用接口時,傳入 raid=99, mid=150
。如果數據庫是表空的?那么,用例肯定失敗了!如何保證這條用每次運行 100% 成功呢?當然是每次執行之前再對應的表中初始化這么一條數據了!
定義的數據怎么插入到數據庫中,當然是有一層解析的,將上面的數據庫轉成一條SQL語句執行。上面的數據當然比原生的一條插入SQL語句好寫。
最后,才是開始寫用例。創建interface_enlist_test.php
測試文件。
class Interface_enlist_test extends InterfaceTestCase
{
//初始化數據
public function db_fixtures()
{
return array(
array(
'data_file' => 'xx_enlist_test_data.php',
'truncate' => true
),
);
}
/*
* 報名驗證
* raid不傳
*/
public function test_post_enlist_raid_null()
{
$result = $this -> request('enlist/apply_verify',array(),array('mid'=>150));
$this->assertEquals($result['status'],'10021');
$this->assertEquals($result['message'],"參數錯誤");
}
/*
* 報名驗證
* mid不傳
*/
public function test_post_enlist_mid_null()
{
$result = $this -> request('enlist/apply_verify',array(),array('raid'=>99));
$this->assertEquals($result['status'],'10021');
$this->assertEquals($result['message'],"參數錯誤");
}
/*
* 報名驗證
* 用戶已報名
*/
public function test_post_enlist_verify_success()
{
$result = $this -> request('enlist/apply_verify',array(),array('raid'=>99, 'mid'=>150));
$this->assertEquals($result['status'],'10101');
$this->assertEquals($result['message'],"你已經報過名");
}
}
這里的用例我就做過多解釋了。調用接口寫斷言。
答疑環節
我知道你們大概會有哪些疑問,接下來,我將試着解答這些疑問。
1、我怎么知道接口調用了哪些表?
首先你要懂PHP編程,然后熟悉Web開發框架,申請代碼查看權限,閱讀接口處理邏輯,自然就知道接口調用哪些表。
2、看不懂開發代碼怎么辦?
學唄!我當年也不是一下子就看懂PHP代碼的,前后也學了兩三個月。
3、往數據庫里面插入測試數據,有重復的怎么辦?
我們當時的設計是,框架在運行時會自動化的修改被測試的接口項目將數據庫指到我本地,也就是說我本地有一個跟測試環境一模一樣的數據庫,每次在插入數據之前先清空表。
要保證本地數據庫的表結構和測試環境是一樣的。這其實也不難,開發如果改到表會上傳SQL腳本,我只需要在本地數據庫執行一下就行了。
4、這樣做接口測試有什么好處?
- 首先,接口用例超級穩定,穩定是自動化測試的 大敵 ,做過自動化的同學知道我在說什么。在保證數據的基礎上,如果用例失敗了, 100% 是接口邏輯被改動到了。
- 不依賴接口文檔,有幾個公司的接口文檔是非常詳細,且及時維護的?我這種方式不需要接口文檔。
- 不
盲測
,盲測就是把接口的參數,每個類型試一遍,然后再排列組合,如果你不知道接口要調用哪個表的哪個字段來判斷條件,那么這種盲測依然覆蓋不到接口的所有處理邏輯。- 當然更裝X(玩笑~!),實際情況是你測試接口的水平即全面又深入,比只會用 postman 盲測的同學厲害多了。
- 反向促進接口代碼質量,因為的接口用例編寫是基於閱讀接口代碼的,有一個新來的PHP開發被我叫到面前幾次,並直接指出對方的代碼邏輯錯誤之后(分分鍾教他怎么做開發,哈哈!),它的接口提測質量一下子提高了許多。
5、這樣做接口測試的缺點是什么?
- 不適合所有團隊,不是每個測試都懂開發代碼的,比如,我們現在的接口用GO,如果我現在想達到無障礙閱讀GO接口代碼,也需要較高的學習成本。
- 不適合大型項目,我之前之所以可在這么玩,主要也是因為PHP項目不大,如果是一個大型項目的話就不適合了,在微服務的架構下,你甚至很難理清一個接口的調用關系。
不過,我仍然認為這是一個優秀的接口測試工程師應該努力的方法。接口測試平台解決的只是測試效率問題,如何把一個接口測好?當然是理解好需求,並有能力閱讀接口處理邏輯,設計出有效和全面的接口用例。
其實,這篇文章所傳達的思想,我在《Web接口開發與自動化測試--基於Python語言》一書都有介紹,只是換了個語言和框架而已。