MockServer的測試思想與實現(下篇)

2021-09-21 19:39:54 字數 4769 閱讀 8218

mockserver的技術實現 

目前,筆者已經用python實現了乙個基於socket介面的mock server並在測試中進行了一定的應用,實現中利用了一些python的語言特性、一點rpc技術和一點dsl的技巧。 

乙個case 

下面先看乙個實際的case,case加入了許額外的注釋,以解釋這段**的意義 (case的格式為一種可嵌入python**的dsl指令碼)

case ds返回結果異常測試

begin

group_id=55

__exec__=begin

python mock_execute(r.strip())

python request(host='',port=$,=$,=$,time=$,='',cached=$,cache_flag='')

endcase 測試 1

begin

mock_data=begin

mock.on(

large_than(192),

).do(

send_back(

am_head_t(1,0,(c_uint32*2)(100,100),sizeof(ds_qres_head_t)+12+32),

ds_qres_head_t(0,1,1,32,12,),

2,4,

"show",

47,3,4,12,

123,"hello,world!"

),clear_buf(),

clear_mock(),

)end

endcase 測試 2

begin

…………

end……

…………

……end

上面的**中,request的函式的功能是將各引數拼裝成乙個http請求傳送給被測系統並接收返回的結果。而mock_execute也就是對 mock server的呼叫了。 

下面就看看這個mock server是如讓上面的case得以執行的 

核心** 

首先看mock server中的主體**,該**基於python中的threadingtcpserver,如下: 

self.stop   self.server.stop:

buf=self.sock.recv(4096)

buf:

time.sleep(0.1)

self.buffer+=buf

mock mockrequesthandler.mocks:

mock(self):

這段**可以看作是程式的主迴圈,它不斷的從socket讀取**,然後呼叫mock物件,觸發其中定義的行為。乙個mock物件定義了乙個行為,程式充許一次定義的多個mock,也有使得程式可以模擬比較複雜的行為了。 

下面再看看mock物件裡面是如何定義的 

(

x,y:x y,

( f:f(handler),self.on_list),

true

):'',self.on_list,self.do_list

( f:f(handler),self.do_list)

true

false

這裡用到了一點兒函式式程式設計的技巧,在on_list中儲存了當前mock的觸發條件,do_list中則儲存了當前mock要執行的操作,這段**的就意思就是當所有的觸發條件都滿足時,就順序執行操作列表的中的操作,否則就退出。 

上面兩段**就構成了mock server的核心邏輯。 

條件與結果 

接下來我們看看on_list和do_list裡面到底是什麼,以前面的case中用到的large_than和send_back為例,它們的原始定義如下所示: 

@mock_action

large_than(handler,size):

(handler.buffer)>=size

@mock_action

send_back(handler,data):

handler.sock.sendall(data)

可以看到,它們的第一引數都是handler,它代表了當前請求處理器的例項,包含以下幾個基本的成員:

對照 核心** 中的主迴圈,這裡的handler就是迴圈中的self,這樣就不難明白這幾個成員的作用了。 

在on_list和do_list中儲存就是對這些函式的「間接」引用。那什麼是間接引用呢? 

回頭看前面cae中的**: 

mock.on(

large_than(192),

).do(

send_back(

am_head_t( …………)

看以看到這裡並沒有給large_than和send_back傳入handler引數,而且,熟悉python語法的人也會發現,這是對函式的呼叫,而不是對函式物件本身的引用,最終on方法得到的引數應該是large_than執行完的結果,不是large_than這個函式物件。說了這麼多,好像很混亂的樣子,其實密秘就在

@mock_action
中,這個是python中的函式修飾器,它本身也是乙個函式,接受乙個函式物件為引數,返回乙個新的函式物件,來看看mock_action的定義: 

mock_action(f):

factor(*args):

action= h:f(h,*args)

action.__name__=f.__name__+''

action

factor.is_mock_action=true

factor.__name__=f.__name__+''

factor

它實際上對是原始的函式進行一次封裝,有點類似函式式程式設計中的高階函式,簡單來說就是將開始那段函式定義的**等價於下面的**: 

large_than(size):

large_than_func(handler):

(handler.buffer)>=size

large_than_func

send_back(data):

send_back_func(handler):

handler.sock.sendall(data)

send_back_func

當然也可以在定義mock行為時寫成這樣: 

mock.on(

handler:large_than(handler,192)

).do(

handler:send_back(handler, …… )

不過這個就有點兒太難看了。 

行為描述 

前面說了好多mock裡存什麼,現看看這此東西是怎麼存進去的,來一段更有代表性的**: 

mock.on(

any_package(),

large_than(32),

).do(

send_back(''),

clear_buf(),

).on(

got(''),

).do(

close_sock(),

).on(

got(''),

).do(

stop_server(),

)

每一組on|do呼叫都定義了乙個新的mock,上面的**中定義了三個mock,那麼如何能保證on|do能成對出現,且不符合約定時能丟擲異常呢? 

其實上面的**可看作是一段dsl的**,我們在python的語法基礎上,新增了on/do兩個關鍵字,並做了一定的語法限定。而在**中實現on和 do時也進行相應的處理,以保證語法約定的正確性。 

通過上面的**就限制了do必須出現on後面,否則會提示mock物件不支援do方法。同時如果只有on沒有do,也不會建立新的mock。 

遠端呼叫 

現在,我們的mock server已經可以啟動執行了,但必須且只能在啟動時指定mock行為,也就是說還不能動態更新配置。 

接下來就該rpc登場了,rpc是遠端過程呼叫的簡稱,這裡的遠端指的是不同的程序,可能是同一臺機器上的,也可能是位於不同機器上的,它們之間可以通過某種pic(程序間通訊)協議傳遞資訊,比如socket。而rpc就是對pic協議的再封裝,把資訊傳送/接收的過程變成更簡單易用的函式呼叫過程。 

本例中使用python的第三方擴充套件庫rpyc來實現rpc,這樣就可以在case中動態的修改mock server的形為了。 

execute (code,service_name=''):

conn=get_online_connectiones(service_name)[-1]

conn.root.execute(code)

=='':

execute(r)

()

在最開始的case中的mock_exectue函式,實際上就是對這裡的execute的再包裝而已。

綜述 總結一下我們所實現的這個mock server的特點: 

相比之傳統定義上的stub server, mock server拋棄了死板的配置檔案,將要行為描述與介面實現分離,更利於**的復用,進一步簡化樁程式的開發成本。

(全文完)

【本文首發於:

效能測試的思想

幾個主要的術語 效能測試的方法 1 驗收效能測試 通過模擬生產執行的業務壓力量和使用場景組合,測試系統的效能是否滿足生產效能要求,這種測試方法就是要在特定的執行條件下驗證系統的能力狀態。2 負載測試 在被測系統上不斷增加壓力,直到效能指標 如響應時間 超過預定指標或者某種資源使用已經達到飽和狀態。3...

乙個簡單的mock server

在前後端分離的專案中,前端無需等後端介面提供了才除錯,後端無需等第三方介面提供了才除錯,基於 契約 可以通過mock server實現除錯,下面是乙個簡單的mock server,通過python的flask框架實現,獲取所有使用者 獲取指定使用者 非法字元 改進mock test.py from ...

測試總體思想

1.對於需求有更改的這種情況來說 測試計畫的編制是為了框定測試範圍。第一步要整理好需求中提到的點 第二步要把需求修改的關聯到的點圈定出來。在測試用例的設計中優先順序應該是這樣的 i.業務流程的測試 畫出業務流程圖。在這個過程中如果能附帶些功能點就帶上 ii.功能用例 iii.公共用例 2.對於完全新...