剛剛做完一個項目,由於這是一個方案項目,而不是產品,所以各種准備很不充分,很多公司的能力不能復用,整個團隊又都是新員工,而且有部分實習生,匆忙上馬,今天對我的自動化框架做一個回溯
自動化測試框架的選擇上,我選擇pytest框架,下面是我的示例文件,不是我真正的自動化用例,主要為了給剛入門的小伙伴指引
一、測試項目目錄設計
lib目錄:存放我的公共的方法
log目錄:存放我的測試案例的日志路徑
report目錄:存放的pytest的執行報告
test_case目錄:存放真正要執行的案例
testfile目錄:存放我的測試文件
conftest.py文件:pytest的文件,具體可以看我的前一篇博客:https://www.cnblogs.com/bainianminguo/p/14338222.html
python.ini文件:pytest的配置文件,具體可以看我的前一篇博客:https://www.cnblogs.com/bainianminguo/p/13773717.html
run_case.py文件:是執行自動化案例的入口文件
二、pytest的案例如何設計
1、入口函數:run_case.py
# -*- coding: utf-8 -*- import pytest import os if __name__ == '__main__': pytest.main(["-v","-s","--html=./report/report.html" ])
2、pytest的配置文件:pytest.ini
[pytest] ;addopts=-s --html=report.html --reruns 3 --reruns-delay 2 ;--html=./report/report.html addopts=-s testpaths = test_case python_files = test_*.py python_classes = Test_* python_functions = test_* markers = level1 level2 level3 bvt
3、全局共享配置文件:conftest.py文件
# -*- coding:utf-8 -*- import pytest from lib import basefunc @pytest.fixture(scope="function",autouse=True) def setup_function(): print("執行conftest文件") basefunc.delfile() yield print("執行conftest文件") basefunc.delfile()
我的conftest文件中的scope=“function”,autouse=True,所以是每個測試函數都會執行這個函數
yield前面的代碼是函數執行前執行的,yield后面的代碼是是函數執行后需要執行的代碼
4、lib目錄下,存儲我的公共的方法,包括一些日志模塊等
logobj.py
# Auther Bob # --*--coding:utf-8--*-- import logging import os # z注冊一個全局的日志對象 class GetLogObj(object): basepath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),"log") def __init__(self,filename): self.path = os.path.join(GetLogObj.basepath,filename+".txt") def log(self): log_obj = logging.getLogger("administrator") log_obj.setLevel(logging.DEBUG) # 注冊一個打印到文件的日志對象 fh = logging.FileHandler(self.path) fh.setLevel(logging.DEBUG) # 設定日志打印的格式 log_format = logging.Formatter("%(name)s %(message)s %(levelno)s %(thread)d %(process)d %(asctime)s", datefmt='%m/%d/%Y:%H:%M:%S %p') # 在打印到文件的日志對象中應用日志格式 fh.setFormatter(log_format) # 將打印到屏幕和日志的對象注冊到全局的日志對象中 log_obj.addHandler(fh) return log_obj
basefunc.py
# -*- coding:utf-8 -*- import os import time def addfile(filename): file = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),'testfile',filename + "_" + str(time.time())) with open(file,mode="a") as f: for i in range(1,200): f.write(str(i)) f.write("\n") def getfile(): file = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'testfile') filelist = [] for file in os.listdir(file): filelist.append(file) if "__init__.py" in filelist: filelist.remove("__init__.py") return filelist def delfile(): basefile = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'testfile') for file in os.listdir(basefile): abspath = os.path.join(basefile,file) os.remove(abspath)
5、test_case目錄:這里是我的核心的測試代碼
6、pytest的知識點1:給案例打標簽
在真正的實戰中,這里主要是區分案例執行的優先級
7、pytest知識點2:斷言
在真正的實戰中,斷言是必不可缺少的,沒有斷言的測試案例不是一個真正的測試案例,是沒有靈魂的
7、pytest知識點3:函數的前置條件和后置條件
def setup(self): print("測試文件1:添加資產::函數級別::前置條件") def teardown(self): print("測試文件1:添加資產::函數級別::后置條件")
這個只對當前的測試文件生效,setup是執行測試函數前執行,teardown在執行測試函數后執行
8、pytest知識點4:類的前置條件和后置條件
def setup_class(self): print("測試文件1:添加資產::類::前置條件") def teardown_class(self): print("測試文件1:添加資產::類::后置條件")
這個只對當前的測試文件生效,setup_class是執行這個類前執行,tear_down是執行類后執行
9、pytest知識點5:序列化參數
@pytest.mark.level2 @pytest.mark.parametrize("filename", ["cui1", "cui2", "cui3", "cui4"]) def test_add_asset_002(self,filename): time.sleep(2) flag = False basefunc.addfile(filename) for i in basefunc.getfile(): if filename in i: flag = True l_obj.log().info("給{filename}文件中添加文件成功".format(filename = filename)) if not flag: l_obj.log().error("給{filename}文件中添加文件失敗".format(filename = filename)) filelist = basefunc.getfile() assert len(filelist) == 1
這里通過@pytest.mark.parametrize去傳參數給測試函數,這里傳了4個參數,相當於是4個測試案例
三、jenkins結合pytest框架執行測試案例
1、設置執行周期
2、設置執行任務入口
3、查看jenkins配置生效
四、jenkins的郵件配置
1、需要安裝一個插件:Email Extension Plugin
2、jenkins全局配置
這里要配置Jenkins的發件人的郵箱地址
這里的密碼可不是登陸的密碼,而是是在這里,大家千萬要注意
3、項目內配置,大家主要圈紅的地方
五、測試
1、點擊build now
2、查看控制台輸出日志
3、檢查已經收到具體的郵件