五、自動執行測試
阿新 • • 發佈:2022-05-25
json檔案是一個特殊格式的文字檔案
- json是一種語法, 用來表達一些資料的
- json檔案的內容就是用json表達的一些資料
- json的語法格式類似於python字典, 由大括號包裹, 有鍵,每個鍵對應一個值
{
"name":"tom",
"age":30
}
json讀json檔案
import json
open讀的方式開啟json檔案
dict1 = json.load(開啟檔案物件) # 把json檔案的內容讀取到python的字典dict1中
close關閉已經開啟的json檔案
# 讀取a.json檔案, 顯示鍵"age"對應的值 import json file = open("a.json", "r", encoding="utf-8") dict1 = json.load(file) # 把json檔案的內容, 轉化成一個python的字典 file.close() print(dict1["age"])
a.json
{
"name":"tom",
"age":30
}
寫json檔案
import json
open用寫的方式開啟檔案
json.dump(字典, open開啟的檔案物件, ensure_ascii=False) ensure_ascii=False中文不轉義
關閉檔案
import json file = open("a.json", "w", encoding="utf-8") dict1 = {"name":"劉備", "height":1.75} json.dump(dict1, file, ensure_ascii=False) # ensure_ascii=False 中文不轉義 file.close()
pytest
pytest自動執行測試用例
- 測試用例所在的模組(py)命名一定要採用識別符號的命名規則
- 一個測試用例就是一個方法
- 方法名習慣test開頭
- 方法所在的類習慣Test開頭, 並採用大駝峰命名法
import pytest
if __name__ == "__main__":
pytest.main(["-s", "測試用例所在的py檔名", "其他的測試用例所在的檔案.py"])
# "-s"作用是, 如果沒有-s測試用例中的print將不會輸出任何內容
# m1.py
# 被測試的函式
def my_sum(a, b):
return a + b
# m2.py 存放測試用例 # 測試m1.py中的my_sum函式是否正確 from m1 import my_sum ''' 測試用例 測試資料, 一個實參為4, 一個實參為2, 預期結果為6 ''' # 一個測試用例就是一個方法, 所以一定先要定義一個類 class TestFunc: # 存放測試用例的類, 業內習慣Test開頭, 並且採用大駝峰命名法 # 類當中的方法就是測試用例 def test_01(self): # 這個方法就是測試用例, 名字習慣以小寫test開頭 result = my_sum(4, 2) if result == 6: print("測試通過") else: print("測試失敗") def test_02(self): result = my_sum(1, 2) if result == 3: print("測試通過") else: print("測試失敗")
# m3.py 存放測試用例
class TestM:
def test_01(self):
print("我是TestM中的測試用例test_01")
- pytest中執行測試用例的程式碼
import pytest
if __name__ == "__main__":
pytest.main(["-s", "m2.py", "m3.py"]) #"-s"的意思是執行測試用例的時候, 顯示print的輸出, "m2.py"測試用例所在的檔名
斷言
- 用程式碼判斷測試用例執行是否通過
assert 條件 # 條件成立, 代表斷言通過, 否則代表斷言不通過
# m2.py 存放測試用例
# 測試m1.py中的my_sum函式是否正確
from m1 import my_sum
'''
測試用例
測試資料, 一個實參為4, 一個實參為2, 預期結果為6
'''
# 一個測試用例就是一個方法, 所以一定先要定義一個類
class TestFunc: # 存放測試用例的類, 業內習慣Test開頭, 並且採用大駝峰命名法
# 類當中的方法就是測試用例
def test_01(self): # 這個方法就是測試用例, 名字習慣以小寫test開頭
result = my_sum(4, 2)
assert result == 6 # result是實際執行結果, 6是預期結果, 實際結果與預期結果相同, 斷言通過
def test_02(self):
result = my_sum(1, 2)
assert result == 3
if __name__ == "__main__":
TestFunc().test_01() # 把TestFunc這個類例項化後,直接呼叫test_01方法
'''
t = TestFunc()
t.test_01()
'''
# m3.py 存放測試用例
class TestM:
def test_01(self):
assert True # 這個測試用例永遠不會失敗
setup和teardown
- 測試用例所在的類可以定義兩個方法, 一個是setup, 一個是teardown
- 如果一個類中有多個測試用例, 每個測試用例執行前會自動呼叫setup方法, 每個測試用例執行完成後會自動呼叫teardown方法
# m2.py 存放測試用例
# 測試m1.py中的my_sum函式是否正確
from m1 import my_sum
'''
測試用例
測試資料, 一個實參為4, 一個實參為2, 預期結果為6
'''
# 一個測試用例就是一個方法, 所以一定先要定義一個類
class TestFunc: # 存放測試用例的類, 業內習慣Test開頭, 並且採用大駝峰命名法
# 類當中的方法就是測試用例
def test_01(self): # 這個方法就是測試用例, 名字習慣以小寫test開頭
result = my_sum(4, 2)
assert result == 6 # result是實際執行結果, 6是預期結果, 實際結果與預期結果相同, 斷言通過
def test_02(self):
result = my_sum(1, 2)
assert result == 3
def setup(self):
print("setup方法給呼叫了")
def teardown(self):
print("teardown方法給調動了")
if __name__ == "__main__":
TestFunc().test_01() # 把TestFunc這個類例項化後,直接呼叫test_01方法
'''
t = TestFunc()
t.test_01()
'''
setup_class和teardown_class
- 一個類中不管有多少測試用例, 所有測試用例執行前, 自動呼叫一次setup_class, 所以測試用例執行完成後自動呼叫一次teardown_class
# m2.py 存放測試用例
# 測試m1.py中的my_sum函式是否正確
from m1 import my_sum
'''
測試用例
測試資料, 一個實參為4, 一個實參為2, 預期結果為6
'''
# 一個測試用例就是一個方法, 所以一定先要定義一個類
class TestFunc: # 存放測試用例的類, 業內習慣Test開頭, 並且採用大駝峰命名法
# 類當中的方法就是測試用例
def test_01(self): # 這個方法就是測試用例, 名字習慣以小寫test開頭
result = my_sum(4, 2)
assert result == 6 # result是實際執行結果, 6是預期結果, 實際結果與預期結果相同, 斷言通過
def test_02(self):
result = my_sum(1, 2)
assert result == 3
def setup(self):
print("setup方法給呼叫了")
def teardown(self):
print("teardown方法給調動了")
def setup_class(self):
print("setup_class方法給呼叫了")
def teardown_class(self):
print("teardown_class方法給調動了")
if __name__ == "__main__":
TestFunc().test_01() # 把TestFunc這個類例項化後,直接呼叫test_01方法
'''
t = TestFunc()
t.test_01()
'''
引數化
- 多個測試用例, 程式碼完全相同, 只有測試資料與預期結果不同, 使用引數化後可以去掉冗餘程式碼
import pytest
# 在要使用引數化的方法前
@pytest.mark.parametrize("形參的說明", [(形參對應的實參), (形參對應的實參), (....)])
def 測試用例(self, 和形參的說明裡一樣的具體形參):
pass
[裡有幾個元組, 被引數化的方法就會自動執行幾次]
# m4.py 存放測試用例
# 測試m1.py中的my_sum函式是否正確
import pytest
from m1 import my_sum
'''
測試用例1
測試資料, 一個實參為4, 一個實參為2, 預期結果為6
測試用例2
測試資料, 一個實參為1, 一個實參為2, 預期結果為3
測試用例3
測試資料, 一個實參為10, 一個實參為1, 預期結果為11
'''
class TestFunc:
@pytest.mark.parametrize("a, b, expect", [(4, 2, 6), (1, 2, 3), (10, 1, 11)])
def test_01(self, a, b, expect): # a和b代表調動my_sum提供的實參, expect代表預期結果
result = my_sum(a, b)
assert result == expect
生成html版本測試報告
import pytest
if __name__ == "__main__":
pytest.main(["-s", "--html=a.html", "m4.py"]) #"-s"的意思是執行測試用例的時候, 顯示print的輸出, "m2.py"測試用例所在的檔名
pytest.ini配置檔案
- pytest.ini配置檔案一定要在專案目錄裡, 不能在任何一個包裡
[pytest]
addopts = -s --html=a.html
testpaths = ./
python_files = m*.py
python_classes = Test*
python_functions = test*
- 第一行必須為[pytest]
- 第二行, -s代表執行測試用例的時候, 可以顯示print的輸出結果, --html=a.html 生成測試報告的檔名
- 第三行: 在哪個包裡查詢測試用例所在的py檔案
- 第四行: 測試用例所在的py檔名, 支援萬用字元 m*.py查詢所有以m開頭, .py結尾的檔案
- 第五行: 測試用例所在的類名必須以Test開頭
- 第六行: 測試用例的方法名必須以test開頭
import pytest
if __name__ == "__main__":
pytest.main() # 啟用pytest.ini配置檔案, 來執行測試用例