近期准備優先做接口測試的覆蓋,為此需要開發一個測試框架,經過思考,這次依然想做點兒不一樣的東西。
- 接口測試是比較講究效率的,測試人員會希望很快能得到結果反饋,然而接口的數量一般都很多,而且會越來越多,所以提高執行效率很有必要
- 接口測試的用例其實也可以用來兼做簡單的壓力測試,而壓力測試需要並發
- 接口測試的用例有很多重復的東西,測試人員應該只需要關注接口測試的設計,這些重復勞動最好自動化來做
- pytest和allure太好用了,新框架要集成它們
- 接口測試的用例應該盡量簡潔,最好用yaml,這樣數據能直接映射為請求數據,寫起用例來跟做填空題一樣,便於向沒有自動化經驗的成員推廣 加上我對Python的協程很感興趣,也學了一段時間,一直希望學以致用,所以http請求我決定用aiohttp來實現。 但是pytest是不支持事件循環的,如果想把它們結合還需要一番功夫。於是繼續思考,思考的結果是其實我可以把整個事情分為兩部分。 第一部分,讀取yaml測試用例,http請求測試接口,收集測試數據。 第二部分,根據測試數據,動態生成pytest認可的測試用例,然后執行,生成測試報告。 這樣一來,兩者就能完美結合了,也完美符合我所做的設想。想法既定,接着 就是實現了。
第一部分(整個過程都要求是異步非阻塞的)
讀取yaml測試用例
一份簡單的用例模板我是這樣設計的,這樣的好處是,參數名和aiohttp.ClientSession().request(method,url,**kwargs)是直接對應上的,我可以不費力氣的直接傳給請求方法,避免各種轉換,簡潔優雅,表達力又強。
args: - post - /xxx/add kwargs: - caseName: 新增xxx data: name: ${gen_uid(10)} validator: - json: successed: True
異步讀取文件可以使用aiofiles這個第三方庫,yaml_load是一個協程,可以保證主進程讀取yaml測試用例時不被阻塞,通過await yaml_load()
便能獲取測試用例的數據
async def yaml_load(dir='', file=''): """ 異步讀取yaml文件,並轉義其中的特殊值 :param file: :return: """ if dir: file = os.path.join(dir, file) async with aiofiles.open(file, 'r', encoding='utf-8', errors='ignore') as f: data = await f.read() data = yaml.load(data) # 匹配函數調用形式的語法 pattern_function = re.compile(r'^\${([A-Za-z_]+\w*\(.*\))}$') pattern_function2 = re.compile(r'^\${(.*)}$') # 匹配取默認值的語法 pattern_function3 = re.compile(r'^\$\((.*)\)$') def my_iter(data): """ 遞歸測試用例,根據不同數據類型做相應處理,將模板語法轉化為正常值 :param data: :return: """ if isinstance(data, (list, tuple)): for index, _data in enumerate(data): data[index] = my_iter(_data) or _data elif isinstance(data, dict): for k, v in data.items(): data[k] = my_iter(v) or v elif isinstance(data, (str, bytes)): m = pattern_function.match(data) if not m: m = pattern_function2.match(data) if m: return eval(m.group(1)) if not m: m = pattern_function3.match(data) if m: K, k = m.group(1).split(':') return bxmat.default_values.get(K).