當前位置:
首頁 > 最新 > 約定大於配置:ApiTestEngine 實現熱載入機制

約定大於配置:ApiTestEngine 實現熱載入機制

背景描述

在中編寫測試用例時,我們有時需要定義全局的變數,或者引用外部函數實現一些動態的計算邏輯。當前採用的方式是:

若需定義全局的參數變數,則要在的中,使用定義變數;

若需引用外部函數,則要在的中,使用導入指定的模塊。

雖然這種方式提供了極大的靈活性,但是對於用戶來說可能會顯得比較複雜。另外一方面,這種方式也會造成大量重複的情況。

例如,對於變數來說,假如我們的項目中存在100個測試場景,而每個場景中都需要將用戶賬號()作為全局變數來使用,那麼在現有模式下,我們只能在這100個文件的中都採用如下方式定義一遍:

同樣的,對於外部函數來說,假如我們項目的100個測試場景都需要用到生成隨機字元串的函數(),那麼我們也不得不在這100個文件的中都導入一次該函數所在的模塊(假設相對於工作目錄的路徑為)。

由此可見,當測試場景越來越多以後,要維護好全局變數和外部函數,必定會是一個很大的工作量。

那麼,如果既要能引用公共的變數和函數,又要減少重複的定義和導入,那要怎麼做呢?

pytest 的 conftest.py

前段時間在接觸時,看到支持的插件機制,這是一種在測試文件中可以實現模塊自動發現和熱載入的機制。具體地,只要是在文件目錄存在命名為的文件,裡面定義的函數都會在運行過程中被導入,並可被測試用例進行調用。同時,存在優先順序策略,從測試用例所在目錄到系統根目錄的整個路徑中,越靠近測試用例的優先順序越高。

其實這也是採用了()的思想。是一種軟體設計範式,旨在減少軟體開發人員需做決定的數量,在遵從約定的過程中就不自覺地沿用了最佳工程實踐。我個人也是比較喜歡這種方式的,所以在設計的時候,也借鑒了一些類似的思想。

受到該啟發,我想也可以採用類似的思想,採用自動熱載入的機制,解決背景描述中存在的重複定義和引用的問題。

既然是,那麼我們首先就得定一個默認的模塊名,類似於的。

這就是。

debugtalk.py 的命名由來

為啥會採用這個命名呢?

其實當時在想這個名字的時候也是耗費了很多心思,畢竟是要遵從的思想,因此在設計這個約定的命名時就格外謹慎,但始終沒有想到一個既合適又滿意的。

在我看來,這個命名應該至少滿足如下兩個條件:

唯一性強

簡單易記

首先,約定的模塊名應該具有較強的唯一性和較高的區分度,是用戶通常都不會採用的命名;否則,可能就會出現測試用例在運行過程中,熱載入時導入預期之外的模塊。

但也不能僅僅為了具有區分度,就使用一個很長或者毫無意義的字元串作為模塊名;畢竟還是要給用戶使用的,總不能每次寫用例時還要去查看下文檔吧;所以命名簡單易記便於用戶使用也很重要。

也是因為這兩個有點互相矛盾的原則,讓我在設計命名時很是糾結。最終在拉同事討論良久而無果的時候,同事說,不如就命名為得了。

仔細一想,這命名還真符合要求。在唯一性方面,採用在、、等搜索引擎中採用精確匹配,基本沒有無關信息,這樣在後續遇到問題時,也容易搜索到已有的解決方案;而在簡單易記方面,相信這個命名也不會太複雜。

當然,只是作為框架默認載入的模塊名,如果你不喜歡,也可以進行配置修改。

熱載入機制實現原理

然後,再來講解下熱載入機制的實現。

其實原理也不複雜,從背景描述可以看出,我們期望實現的需求主要有兩點:

自動發現函數模塊,並且具有優先順序策略;

將函數模塊中的變數和函數導入到當前框架運行的內存空間。

將這兩點與測試用例引擎的實現機制結合起來,在運行過程中的熱載入機制應該就如下圖所示。

這個流程圖對熱載入機制描述得已經足夠清晰了,我再針對其中的幾個點進行說明:

1、在初始化測試用例集(testset)的時候,除了將中和指定的變數和函數導入外,還會默認導入模塊。之所以這麼做,是因為對於大多數系統可能都會用到一些通用的函數,例如獲取當前時間戳()、生成隨機字元串()等。與其在每個項目中都單獨去實現這些函數,不如就將其添加到框架中作為默認支持的函數(相當於框架層面的),這樣大家在項目中就不需要再重複做這些基礎性工作了。

2、在框架中,存在測試用例()和測試用例集()兩個層面的作用域,兩者的界限十分明確。這樣設計的目的在於,我們既可以實現用例集層面的變數和函數的定義和導入,也可以保障各個用例之間的獨立性,不至於出現作用域相互污染的情況。具體地,作用域在用例集初始化時定義或導入的變數和函數,會存儲在用例集層面的作用域;而在運行每條測試用例時,會先繼承()用例集層面的作用域,如果存在同名的變數或函數定義,則會對用例集層面的變數和函數進行覆蓋,同時用例集層面的變數和函數也並不會被修改。

3、從熱載入的順序可以看出,查找變數或函數的順序是從測試用例所在目錄開始,沿著父路徑逐層往上,直到系統的根目錄。因此,我們可以利用這個優先順序原則來組織我們的用例和依賴的函數模塊。例如,我們可以將不同模塊的測試用例集文件放在不同的文件夾下:針對各個模塊獨有的依賴函數和變數,可以放置在對應文件夾的文件中;而整個項目公共的函數和變數,就可以放置到項目文件夾的中。

文件組織結構如下所示:

這其中還有一點需要格外注意。因為我們在框架運行過程中需要將作為函數模塊進行導入,因此我們首先要保障滿足模塊的要求,也就是在對應的文件夾中要包含文件。

如果對熱載入機制的實現感興趣,可直接閱讀框架源碼,重點只需查看中的三個函數:

search_conf_item(start_path, item_type, item_name)

get_imported_module_from_file(file_path)

filter_module(module, filter_type)

測試用例編寫方式的變化

在新增之後,編寫測試用例的方式發生一些改變(優化),主要包括三點:

導入模塊的關鍵詞改名為(原名為);

不再需要顯式指定導入的模塊路徑,變更為熱載入機制自動發現;

模塊中的變數也會被導入,公共變數可放置在模塊中,而不再必須通過定義。

考慮到兼容性問題,框架升級的同時也保留了對原有測試用例編寫方式的支持,因此框架升級對已有測試用例的正常運行也不會造成影響。不過,我還是強烈建議大家採用最新的用例編寫方式,充分利用熱載入機制帶來的便利。

寫在最後

現在回過頭來看的演進歷程,以及之前寫的關於設計方面的文章,會發現當初的確是有一些考慮不周全的地方。也許這也是編程的樂趣所在吧,在前行的道路中,總會有新的感悟和新的收穫,迭代優化的過程,就彷彿是在打磨一件藝術品。

這種感覺,甚好!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 DebugTalk 的精彩文章:

ApiTestEngine 集成 Locust 實現更好的性能測試體驗

TAG:DebugTalk |