自動化測試中,測試數據與腳本分離以及參數化方法

構建測試知識體系,歡迎關注python

測試數據與測試腳本分離,對測試腳本進行參數化
shell


正文字數1535數據庫

前面兩篇分別介紹了兩種測試函數參數化的方法。json

Pytest如何對測試函數進行參數化
api

使用Pytest的Hook函數進行測試參數化原來這麼方便
數組

這篇文章,咱們來看看如何將數據和腳本分離,而且還可以實現參數化。微信

測試數據和測試代碼在實際的測試工做中,每每是分開存放的,利於測試數據和測試腳本的分開來維護。好比,爲測試用例添加幾組新的測試數據,只須要修改測試數據文件,測試代碼不須要動;若是是測試用例增長了新的校驗點,只須要修改測試腳本,不須要修改測試數據文件。app


01編輯器

函數

準備測試數據


如今在data/目錄下建立一個用於存放測試數據的Yaml文件test_in_theaters.yaml,內容以下:

---tests:- case: 驗證響應中start和count與請求中的參數一致 input: method: GET path: /v2/movie/in_theaters headers: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 params: apikey: 0df993c66c0c636e29ecbb5344252a4a start: 0 count: 10 expected: response: title: 正在上映的電影-上海 count: 10 start: 0- case: 驗證響應中title"正在上映的電影-北京" input: method: GET path: /v2/movie/in_theaters headers: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 params: apikey: 0df993c66c0c636e29ecbb5344252a4a start: 1 count: 5 expected: response: title: 正在上映的電影-北京 count: 5 start: 1

熟悉Yaml格式的同窗,應該很容易看懂上面測試數據文件的內容。這個測試數據文件中,有一個數組tests,裏面包含的是兩條完整的測試數據。一個完整的測試數據由三部分組成:

  1. case,表示測試用例名稱。

  2. input,表示輸入參數。

  3. expected,表示預期結果。

上面的input輸入參數,是一個http請求對象,包含了被測接口的全部參數,包括請求方法、請求路徑、請求頭、請求參數。expected表示預期結果,上面的測試數據中,只列出了對請求響應的預期值,實際測試中,還能夠列出對數據庫的預期值。


02

編寫測試腳本


新建一個測試腳本test_paramtrize_by_data_driven.py,內容以下:

import pytest
class TestDataDriven: @pytest.mark.datafile('data/test_in_theaters.yaml') # 相對於項目根目錄的相對路徑 def test_data_driven(self, parameters): print(parameters['input']) print(parameters['expected'])

首先看一下測試函數,在測試函數上方使用了一個叫作datafile的marker來爲測試函數提供數據。測試數據的路徑是相對於項目根路徑的相對路徑,這裏表示的是測試數據是在項目的根路徑下data目錄中的test_in_theaters.yaml。測試函數經過parameters這個fixture拿到測試數據內容。


03

實現pytest_generate_tests Hook


上面測試腳本使用測試數據的方法,是在tests/conftest.py文件中的pytest_generate_tests函數中實現的。

import yamlimport json
def pytest_generate_tests(metafunc): ids = [] markers = metafunc.definition.own_markers for marker in markers: if marker.name == 'datafile': # 讀取外數據 test_data_path = os.path.join(metafunc.config.rootdir, marker.args[0]) # 拼接測試數據路徑 with open(test_data_path) as f: ext = os.path.splitext(test_data_path)[-1] if ext in ['.yaml', '.yml']: test_data = yaml.safe_load(f) elif ext == '.json': test_data = json.load(f) else: raise TypeError('datafile must be yaml or json,root must be tests') if "parameters" in metafunc.fixturenames: # 用外部數據進行參數化 for data in test_data['tests']: # 用test_data中的case做爲測試用例名稱 ids.append(data['case']) # 用test_data這個列表對parameters進行參數化。        metafunc.parametrize("parameters", test_data['tests'], ids=ids, scope="function")

metafunc.definition.own_markers能夠讀取到測試函數中全部的marker,若是存在datafile這個marker,表示須要從外部讀取測試數據,測試數據能夠YAML格式也能夠是Json格式。若是測試函數的metafunc.fixturenames中含有parameters這個fixture函數,就用外部測試數據對它進行參數化。


04

參數化套路


有了pytest_generate_tests這個Hook函數後,對測試函數進行參數化須要作三個改動:

  • 在data目錄下新加一個YAML或者Json格式文件。文件內容格式參考上面的例子。

  • 指定測試數據文件的路徑@pytest.mark.datafile('data/test_in_theaters.yaml')

  • 給測試數據提供一個叫作 parameters的fixture

如今,整個項目的目錄結構應該是以下所示:

$ tree.├── Pipfile├── Pipfile.lock├── data│ └── test_in_theaters.yaml├── tests│ └── conftest.py│ └── test_data_driven.py


05

總結


本文實現測試腳本和測試數據的分離的核心,仍是實現了Hook函數,在Hook函數中讀取測試數據文件,並對測試函數的fixture進行參數化。



本文分享自微信公衆號 - 明說軟件測試(liuchunmingnet)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索