刚刚做完一个项目,由于这是一个方案项目,而不是产品,所以各种准备很不充分,很多公司的能力不能复用,整个团队又都是新员工,而且有部分实习生,匆忙上马,今天对我的自动化框架做一个回溯
自动化测试框架的选择上,我选择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、检查已经收到具体的邮件