標籤:
最近在做一個restful API的項目,項目測試主要是發送HTTP請求(GET,POST,DELETE,PUT等),並檢查返回結果。
以往我們測試都是先寫測試案例,通常是一個EXECEL表格。這裡面會寫好每個測試例的輸入,測試步驟和期望結果。然後再根據每個測試例的通過情況,更新另一個EXECEL中對應測試例的測試結果(通過or失敗,還有一些備忘資訊等。)
測試人員需要寫好測試例,並用一個HTTP工具對每個測試例進行測試,並人工檢查返回結果,決定測試例的成功與失敗。這樣的結果就是,每次代碼發布後有改動,或有bug修改,都要人工的過一遍所有測試例,相當煩瑣。
其實對於這種HTTP性質的項目,如果測試的商務邏輯性不是很強,還是相對容易實現自動化測試的。所以做了一個自動化測試的工具,這個工具的目標是:
1.定義一個內部DSL(特定領域語言),方便不懂編碼的測試人員編寫測試例的輸入和期望結果。
2.自動遍曆EXECEL中的每個測試例,將輸入轉換為HTTP請求並發送。
3.用期望結果對HTTP響應檢查,決定測試的結果並更新EXCEL。
鑒於這個工具的這些特點,用RUBY實現實在是再合適不過了。因為RUBY強大的元編程能力很容易自訂一種DSL,而且這種DSL比較簡潔。另外,RUBY十分靈活,可以滿足我們的要求。
首先,我們來實現輸入部分。輸入我定義為下面的形式:
POST :url=>"http://www.baidu.com",:name=>"bob" ,:body=>‘{"data":["key":"value"]}‘
這表明要進行一個POST測試,然後以key,value的形式給出請求需要攜帶的參數,body部分我們用json格式。這些參數可以是http請求中的header,body等部分的內容。
我們代碼要做的就是定義一個POST方法,然後在這個方法裡把這些參數儲存起來。用於後面轉換為具體的HTTP請求並發送。所以,我們可以定義幾個方法,分別表示POST,GET,DELETE等HTTP請求,並把這個請求的參數記錄下來。可能你會想到下面的Ruby代碼:
def POST(*args)
@testCase = {}
@testCase[:request] = “POST”
@testCase[:params] = args[0]
end
由於這些方法的代碼都幾乎一樣,所以我們可以用類宏的方法實現這些方法的定義。削減相似代碼,這也是Ruby最擅長的。
最終的代碼如下,分別是main.rb主程式部分,和一個用於實作類別宏的模組http_method_macro.rb
main.rb:
require_relative ‘../autoHttpTest/class_macro/http_method_macro‘
class << self
include HttpClassMacroModule
http_method :GET
http_method :POST
http_method :DELETE
http_method :PUT
end
POST :url=>"http://www.baidu.com",:name=>"Bob"
p @testCase
../autoHttpTest/class_macro/http_method_macro.rb:
module HttpClassMacroModule
def self.included(base)
base.extend HttpClassMacros
end
module HttpClassMacros
def http_method(name)
define_method(name) do |*args|
@testCase = {}
@testCase[:params] = args[0]
@testCase[:request] = name.to_s
end
end
end
end
首先,定義一個模組HttpClassMacroModule,包含這個模組的類將會有一個類方法http_method,稱之為類宏http_method。這樣包含這個模組的類就可以用這個類宏定義GET,POST等執行個體方法,而且這些方法的代碼只有一份。
然後,在main.rb裡,包含上面定義的模組(注意這個模組是在main對象的單例類中包含的)。然後再給main對象的單例類定義執行個體方法GET,POST,DELETE,PUT。這樣在main對象中就可以使用這些方法了。
最後,作為測試,我們用
POST :url=>"http://www.baidu.com",:name=>"Bob"
p @testCase
這段代碼測試。程式運行結果如下:
{:params=>{:url=>"http://www.baidu.com", :name=>"Bob"}, :request=>"POST"}
Process finished with exit code 0
這樣,我們就實現了一種DSL,用這種DSL可以讓測試人員方便的輸寫測試案例的輸入部分,我們也可以記錄下輸入,方便以後轉換成HTTP請求進行測試。
今天先講這些,下一節我們將進一步完善這個工具,在程式裡將輸入轉換為具體的HTTP請求並發送。
Ruby實現Http自動化測試(一)----------類宏