import xlrdfrom xlrd import xldate_as_tupleimport datetime
class ExcelData(object): ‘’’ xlrd中单元格的数据类型 数字一律按浮点型输出,日期输出成一串小数,布尔型输出0或1,所以我们必须在程序中做判断处理转换 成我们想要的数据类型 0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error ‘’’ def init(self, data_path, sheetname=“Sheet1”): #定义一个属性接收文件路径 self.data_path = data_path # 定义一个属性接收工作表名称 self.sheetname = sheetname # 使用xlrd模块打开excel表读取数据 self.data = xlrd.open_workbook(self.data_path) # 根据工作表的名称获取工作表中的内容 self.table = self.data.sheet_by_name(self.sheetname) # 根据工作表的索引获取工作表的内容 # self.table = self.data.sheet_by_name(0) # 获取第一行所有内容,如果括号中1就是第二行,这点跟列表索引类似 self.keys = self.table.row_values(0) # 获取工作表的有效行数 self.rowNum = self.table.nrows # 获取工作表的有效列数 self.colNum = self.table.ncols
定义一个读取excel表的方法 def readExcel(self): # 定义一个空列表 datas = [] for i in range(1, self.rowNum): # 定义一个空字典 sheet_data = {} for j in range(self.colNum): # 获取单元格数据类型 c_type = self.table.cell(i,j).ctype # 获取单元格数据 c_cell = self.table.cell_value(i, j) if c_type == 2 and c_cell % 1 == 0: # 如果是整形 c_cell = int(c_cell) elif c_type == 3: # 转成datetime对象 date = datetime.datetime(*xldate_as_tuple(c_cell, 0)) c_cell = date.strftime(‘%Y/%d/%m %H:%M:%S’) elif c_type == 4: c_cell = True if c_cell == 1 else False sheet_data[self.keys[j]] = c_cell # 循环每一个有效的单元格,将字段与值对应存储到字典中 # 字典的key就是excel表中每列第一行的字段 # sheet_data[self.keys[j]] = self.table.row_values(i)[j] # 再将字典追加到列表中 datas.append(sheet_data) # 返回从excel中获取到的数据:以列表存字典的形式返回 return datas
if name == “main”: data_path = “…\resources\test_http_data.xls” sheetname = “Sheet1” get_data = ExcelData(data_path, sheetname) datas = get_data.readExcel() print(datas)
4.3 测试用例代码编写
testcases文件夹下编写测试用例:
test_caoliao_http_get_interface.py内容:
import loggingimport allure
import pytestfrom utils.http_utils import HttpUtilsfrom utils.read_jsonfile_utils import ReadJsonFileUtilsfrom config.global_config import CAOLIAO_HTTP_GET_HOST
@pytest.mark.httptest@allure.feature(“草料二维码get请求测试”)class TestHttpInterface: # 获取文件相对路径 data_file_path = ReadJsonFileUtils.get_data_path(“resources”, “test_http_get_data.json”) # 读取测试数据文件 param_data = ReadJsonFileUtils(data_file_path) data_item = param_data.get_value(‘dataItem’) # 是一个list列表,list列表中包含多个字典
“”" @pytest.mark.parametrize是数据驱动; data_item列表中有几个字典,就运行几次case ids是用于自定义用例的名称
“”"
@pytest.mark.parametrize(“args”, data_item, ids=[‘测试草料二维码get接口1’, ‘测试草料二维码get接口2’]) def test_caoliao_get_demo(self, args, login_test): # 打印用例ID和名称到报告中显示 print(“用例ID:{}”.format(args[‘id’])) print(“用例名称:{}”.format(args[‘name’])) print(“测试conftest传值:{}”.format(login_test)) logging.info(“测试开始啦~~~~~~~”) res = HttpUtils.http_get(args[‘headers’], CAOLIAO_HTTP_GET_HOST+args[‘url’]) # assert断言,判断接口是否返回期望的结果数据 assert str(res.get(‘code’)) == str(args[‘expectdata’][‘code’]), “接口返回status值不等于预期”
test_caoliao_http_post_interface.py内容:
import pytestimport loggingimport allurefrom utils.http_utils import HttpUtilsfrom utils.read_jsonfile_utils import ReadJsonFileUtilsfrom config.global_config import CAOLIAO_HTTP_POST_HOST
pytest.ini文件中要添加markers = httptest,不然会有warning,说这个Mark有问题@pytest.mark.httptest@allure.feature(“草料二维码post请求测试”)class TestHttpInterface: # 获取文件相对路径 data_file_path = ReadJsonFileUtils.get_data_path(“resources”, “test_http_post_data.json”) # 读取测试数据文件 param_data = ReadJsonFileUtils(data_file_path) data_item = param_data.get_value(‘dataItem’) #是一个list列表,list列表中包含多个字典
“”" @pytest.mark.parametrize是数据驱动; data_item列表中有几个字典,就运行几次case ids是用于自定义用例的名称 “”" @pytest.mark.parametrize(“args”, data_item, ids=[‘测试草料二维码post接口1’,‘测试草料二维码post接口2’]) def test_caoliao_post_demo(self, args): # 打印用例ID和名称到报告中显示 print(“用例ID:{}”.format(args[‘id’])) print(“用例名称:{}”.format(args[‘name’])) logging.info(“测试开始啦~~~~~~~”) res = HttpUtils.http_post(args[‘headers’], CAOLIAO_HTTP_POST_HOST+args[‘url’], args[‘parameters’]) # assert断言,判断接口是否返回期望的结果数据 assert str(res.get(‘status’)) == str(args[‘expectdata’][‘status’]), “接口返回status值不等于预期” assert str(res.get(‘data’).get(‘qrtype’)) == str(args[‘expectdata’][‘qrtype’]), “接口返回qrtype值不等于预期”
企业中的系统接口,通常都有认证,需要先登录获取token,后续接口调用时都需要认证token。因此框架需要能处理在运行用例前置和后置做一些动作,所以这里用到了conftest.py文件,内容如下:
import loggingimport traceback
import pytestimport requests
“”“如果用例执行前需要先登录获取token值,就要用到conftest.py文件了作用:conftest.py 配置里可以实现数据共享,不需要import导入 conftest.py,pytest用例会自动查找scope参数为session,那么所有的测试文件执行前执行一次scope参数为module,那么每一个测试文件执行前都会执行一次conftest文件中的fixturescope参数为class,那么每一个测试文件中的测试类执行前都会执行一次conftest文件中的fixturescope参数为function,那么所有文件的测试用例执行前都会执行一次conftest文件中的fixture
“””
获取到登录请求返回的ticket值,@pytest.fixture装饰后,testcase文件中直接使用函数名"login_ticket"即可得到ticket值@pytest.fixture(scope=“session”)def login_ticket(): header = { ‘Content-Type’: ‘application/x-www-form-urlencoded; charset=UTF-8’ } params = { “loginId”: “username”, “pwd”: “password”, } url = ‘http://testxxxxx.xx.com/doLogin’ logging.info(‘开始调用登录接口:{}’.format(url)) res = requests.post(url, data=params, headers=header, verify=False) # verify:忽略https的认证 try: ticket = res.headers[‘Set-Cookie’] except Exception as ex: logging.error(‘登录失败!接口返回:{}’.format(res.text)) traceback.print_tb(ex) logging.info(‘登录成功,ticket值为:{}’.format(ticket)) return ticket
#测试一下conftest.py文件和fixture的作用@pytest.fixture(scope=“session”)def login_test(): print(“运行用例前先登录!”)
使用yield关键字实现后置操作,如果上面的前置操作要返回值,在yield后面加上要返回的值 # 也就是yield既可以实现后置,又可以起到return返回值的作用 yield “runBeforeTestCase” print(“运行用例后退出登录!”)
由于用例中用到了@pytest.mark.httptest给用例打标,因此需要创建pytest.ini文件,并在里面添加markers = httptest,不然会有warning,说这个Mark有问题。并且用例中用到的日志打印logging模板也需要在pytest.ini文件中增加日志配置。pytest.ini文件内容如下:
[pytest]markers = httptest: run http interface test dubbotest: run dubbo interface test
log_cli = truelog_cli_level = INFOlog_cli_format = %(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)slog_cli_date_format=%Y-%m-%d %H:%M:%Slog_format = %(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)4s: %(message)slog_date_format=%Y-%m-%d %H:%M:%S
4.4 测试用例运行生成报告
运行方式:Terminal窗口,进入到testcases目录下,执行命令:
运行某一条case:pytest test_caoliao_http_post_interface.py运行所有case: pytest运行指定标签的case:pytest -m httptest
运行并打印过程中的详细信息:pytest -s test_caoliao_http_post_interface.py运行并生成pytest-html报告:pytest test_caoliao_http_post_interface.py --html=…/testoutput/report.html运行并生成allure测试报告:1. 先清除掉testoutput/result文件夹下的所有文件2. 运行case,生成allure文件:pytest --alluredir …/testoutput/result3. 根据文件生成allure报告:allure generate …/testoutput/result/ -o …/testoutput/report/ --clean4. 如果不是在pycharm中打开,而是直接到report目录下打开index.html文件打开的报告无法展示数据,需要双击generateAllureReport.bat生成allure报告;
pytest-html报告:
generateAllureReport.bat文件位置:
文件内容:
allure open report/
Allure报告:
框架中用到的一些细节知识点和问题,如:
conftest.py和@pytest.fixture()结合使用
pytest中使用logging打印日志
python中获取文件相对路径的方式
python虚拟环境
pytest框架下Allure的使用
我会在后续写文章再介绍。另外框架同样适用于dubbo接口的自动化测试,只需要添加python调用dubbo的工具类即可。点击【测试资料】菜单获取框架下载地址。
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
:vip1024b (备注软件测试)**
[外链图片转存中…(img-T6K0fgCi-1712801510308)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!