干貨 | 一改測試步驟代碼就全寫?為什么不試試用 Yaml實現(xiàn)數(shù)據(jù)驅(qū)動?

理念與同“UI自動化測試框架”中的“測試步驟的數(shù)據(jù)驅(qū)動”相同,接口中的測試步驟的數(shù)據(jù)驅(qū)動就是將接口的參數(shù)(比如 method、url、param等)封裝到 yaml 文件中管理。當測試步驟發(fā)生改變,只需要修改 yaml 文件中的配置即可。
數(shù)據(jù)驅(qū)動就是數(shù)據(jù)的改變從而驅(qū)動自動化測試的執(zhí)行,最終引起測試結(jié)果的改變。簡單來說,就是參數(shù)化的應用。數(shù)據(jù)量小的測試用例可以使用代碼的參數(shù)化來實現(xiàn)數(shù)據(jù)驅(qū)動,數(shù)據(jù)量大的情況下建議使用一種結(jié)構(gòu)化的文件(例如yaml,json等)來對數(shù)據(jù)進行存儲,然后在測試用例中讀取這些數(shù)據(jù)。
原理與前面章節(jié)“UI自動化測試框架”中的“測試數(shù)據(jù)的數(shù)據(jù)驅(qū)動”大同小異。依然使用?@pytest.mark.parametrize?裝飾器來進行參數(shù)化,使用參數(shù)化來實現(xiàn)數(shù)據(jù)驅(qū)動。 通過參數(shù)化的方式,分別判斷id為2,3的部門的parentid為1:
import pytest?
class TestDepartment:
??
?department = Department()
??
?@pytest.mark.parametrize("id", [2, 3])
?
?def test_department_list(self, id):
?
? ? ?r = self.department.list(id)
? ?
? ?assert self.department.jsonpath(expr="$..parentid")[0] == 1
上面的代碼首先使用?@pytest.mark.parametrize?裝飾器,傳遞了兩組數(shù)據(jù),測試結(jié)果顯示有兩條測試用例被執(zhí)行,而不是一條測試用例。也就是 pytest 會將兩組測試數(shù)據(jù)自動生成兩個對應的測試用例并執(zhí)行,生成兩條測試結(jié)果。
當測試數(shù)據(jù)量大的情況下,可以考慮把數(shù)據(jù)存儲在結(jié)構(gòu)化的文件中。從文件中讀取出代碼中所需要格式的數(shù)據(jù),傳遞到測試用例中執(zhí)行。本次實戰(zhàn)以YAML進行演示。YAML以使用動態(tài)字段進行結(jié)構(gòu)化,它以數(shù)據(jù)為中心,比 excel、csv、Json、XML 等更適合做數(shù)據(jù)驅(qū)動。
將上面參數(shù)化的兩組數(shù)據(jù)存儲到 yaml 文件中,創(chuàng)建一個data/department_list.yml文件,代碼如下:
-2?
-3
上面的代碼定義了一個 yaml 格式的數(shù)據(jù)文件department_list.yml,文件中定義了一個列表,列表中有兩個數(shù)據(jù),最后生成的是這樣的數(shù)據(jù)格式:[1,2]。將測試用例中參數(shù)化的數(shù)據(jù)改造成從 department_list.yml 文件中讀取,代碼如下:
class TestDepartment:?
? ?department = Department()
?
?@pytest.mark.parametrize("id", \
? ?yaml.safe_load(open("../data/department_list.yml")))
?
??def test_department_list(self, id):
?
? ? ?r = self.department.list(id)
??
? ? ?assert self.department.jsonpath(expr="$..parentid")[0] == 1
上面的代碼,只需要使用yaml.safe_load()方法,讀取department_list.yml文件中的數(shù)據(jù),分別傳入到用例 test_department_list() 方法中完成輸入與結(jié)果的驗證。
實際工作中,對于環(huán)境的切換和配置,為了便于維護,通常不會使用硬編碼的形式完成。在“多環(huán)境下的接口測試”章節(jié)中已經(jīng)介紹了,如何將環(huán)境的切換作為一個可配置的選項。本章節(jié)會把這部分內(nèi)容進行重構(gòu),使用數(shù)據(jù)驅(qū)動的方式完成多環(huán)境的配置。
根據(jù)“多環(huán)境下的接口測試”章節(jié),將此章節(jié)中的環(huán)境配置部分改為數(shù)據(jù)驅(qū)動的模式 代碼如下:
#把host修改為ip,并附加host header
env={
? ?
"docker.testing-studio.com": {
? ??
? ?"dev": "127.0.0.1",
?
? ? ?"test": "1.1.1.2"
??
?},
??
?"default": "dev"?
}?
data["url"]=str(data["url"]).replace(
?
?"docker.testing-studio.com",
??
?env["docker.testing-studio.com"][env["default"]]?
)?
data["headers"]["Host"]="docker.testing-studio.com"
依然以yaml為示例,將所有的環(huán)境配置信息放到 env.yml 文件中。如果怕出錯,可以先使用yaml.safe_dump(env)將dict格式的代碼轉(zhuǎn)換為yaml。 如下所示,打印出來的,就是成功轉(zhuǎn)換yaml格式的配置信息:
def test_send(self):?
? ?env={
??
? ? ?"docker.testing-studio.com": {
?
? ? ? ? ?"dev": "127.0.0.1",
??
? ? ? ? ?"test": "1.1.1.2"
??
? ? ?},
??
? ? ?"default": "dev"
?
?}
?
??yaml2 = yaml.safe_dump(env)
??
?print("")
?
??print(yaml2)
將打印出來的內(nèi)容粘貼到 env.yml 文件中: env.yml
docker.testing-studio.com:?
?dev: "127.0.0.1"?
?test: "1.1.1.2"
?
level: 4?
default:?
?"dev"
將環(huán)境準備中的代碼稍作修改,把env變量從一個典型dict改為,使用yaml.safe_load讀取 env.yml:
# 把host修改為ip,并附加host header?
env = yaml.safe_load(open("./env.yml"))?
data["url"] = str(data["url"]).\
??
?replace("docker.testing-studio.com",
?
? env["docker.testing-studio.com"][env["default"]])?
data["headers"]["Host"] = "docker.testing-studio.com"
如此一來,就可以實現(xiàn)使用數(shù)據(jù)驅(qū)動的方式,通過修改 env.yml 文件來直接修改配置信息。