Python+Requests+Pytest 接口自动化测试脚本总结 |
您所在的位置:网站首页 › python脚本自动化配置文件 › Python+Requests+Pytest 接口自动化测试脚本总结 |
目录 一、框架搭建流程 1. 封装接口请求 2. 存储接口信息 3. 封装登录和其他方法 4. 使用Pytest管理测试用例 5. 添加日志模块 6. 生成测试报告 7. 测试报告发送至邮箱 8. 优化动态数据的存储 9. 项目目录 二、上传代码到github 三、运行测试用例的两种方法 1. 命令行模式 2. 在python脚本中调用pytest 四、重构接口自动化测试框架 一、框架搭建流程 1. 封装接口请求封装post和get方法方便在使用requests模块发送请求时,仅调用一个方法即可 #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: run_method.py import requests class RunMethod(object): def post_main(self, url, headers, data): # 忽略不安全的请求警告信息 requests.packages.urllib3.disable_warnings() # 遇到requests的ssl验证,若想直接跳过不验证,设置verify=False即可 response = requests.post(url=url, headers=headers, data=data, verify=False) return response def get_main(self, url, headers, data=None): # 忽略不安全的请求警告信息 requests.packages.urllib3.disable_warnings() response = requests.get(url=url, headers=headers, data=data, verify=False) return response def run_main(self, method, url, headers, data=None): # 忽略不安全的请求警告信息 requests.packages.urllib3.disable_warnings() requests.adapters.DEFAULT_RETRIES = 5 if method == "Post": res = self.post_main(url, headers, data) elif method == "Get": res = self.get_main(url, headers, data) # 将响应的的数据以字典数据结构和json数据格式返回 return res.json() 2. 存储接口信息使用yml文件作为配置文件,存储每一个接口信息,主要包括”接口名称、method、url、data和headers“,以及预期结果”expected“ # fileName: api_config.yml host: https://XXX.com login: name: 【登录】手机号码登录 method: Post url: /v1/login/ data: phone_country: 86 phone_number: 1210000000 password: 123456 device_id: XXX device_name: Iphone8plus device_pubkey: XXX headers: Content-Type: application/x-www-form-urlencoded Authorization: Basic XXX asset_main: name: 【资产】用户资产列表页 method: Get url: /v2/main/ headers: Authorization: Bearer app-version: 4.8.0 device-id: XXX expected: success: true lend: name: 发送请求 method: Post url: /v1/lend/ data: payment_password: 123456 amount: 100 pledge_source: 1 headers: Content-Type: application/x-www-form-urlencoded Authorization: Bearer device-id: XXX app-version: 4.8.0 3. 封装登录和其他方法1)登录方法用于获取并存储token,存储至access_token.yml中; 2)参数”api_name“的取值是配置文件api_config.yml中的接口名称,比如:login、asset_main和loan_lend。同样封装了一个类ReadYaml,方法是取配置文件中各接口的”method、url、data、headers和expected“等; 3)除了登录接口,其他接口的headers均需要token值,所以在处理headers时要区分登录接口和其他接口; 4)建议:添加异常处理捕获异常,输出自定义的错误信息。 #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: app_api.py from common.run_method import RunMethod from common.read_info import ReadYaml from common.get_log import get_log from common.deal_token import write_token import json class AllApi(object): def __init__(self): self.run = RunMethod() self.read = ReadYaml() self.logger = get_log() # 登录,获取token def login(self, api_name): try: # 获取接口请求参数 method = self.read.get_method(api_name) url = self.read.get_url(api_name) data = self.read.get_data(api_name) headers = self.read.get_headers(api_name) response = self.run.run_main(method, url, headers, data) # 把token值写到配置文件access_token.yml中,供其他接口调用 write_token(response) print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False)) return response except Exception as e: self.logger.info("接口访问出错啦~ %s" % e) # 其他接口请求封装 def send_request(self, api_name): try: # 获取接口请求参数 method = self.read.get_method(api_name) url = self.read.get_url(api_name) headers = self.read.get_headers(api_name) # 区分Get和Post方法 if method == "Get": response = self.run.run_main(method, url, headers) elif method == "Post": data = self.read.get_data(api_name) response = self.run.run_main(method, url, headers, data) # print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False)) print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False)) print(response["success"]) return response except Exception as e: self.logger.info("接口访问出错啦~ %s" % e) # 获取预期结果,方便断言时直接使用 def get_expect(self, api_name): try: # 获取配置文件中的预期结果 expect = self.read.get_expected(api_name) # print(expect) return expect except Exception as e: self.logger.info("获取预期结果出错啦~ %s" % e) 4. 使用Pytest管理测试用例1)在执行所有用例之前先执行登录接口,获取token。所以把登录接口的请求放在conftest.py文件中 #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: conftest.py from API.all_api import AllApi import pytest from common.get_log import get_log logger = get_log() # 在执行所有用例之前先执行登录接口,获取token @pytest.fixture(scope="session") def init_token(): # 正确邮箱/手机号和密码登录 logger.info("\n ============================= 在所有用例执行之前,生成token =============================") all_login = AllApi() all_login.login("login_sandbox_phoneNumber")2) 把每个功能模块封装成一个类,每个用例封装成一个方法。例如资产模块的用例如下: #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: test_asset.py from API.all_api import AllApi import pytest from common.get_log import get_log logger = get_log() # 资产模块的测试用例 @pytest.mark.usefixtures("init_token") class TestAsset(object): @pytest.fixture(scope="class") def init_asset(self): logger.info("\n ==============================【资产】测试用例开始 ==============================") all_request = AllApi() return all_request @pytest.mark.parametrize("api_name", ["asset_main"]) def test_asset_main(self, api_name, init_asset): print("\n 用例名称:获取资产列表信息\n") res = init_asset.send_request(api_name) expected = init_asset.get_expect(api_name) # 断言1:success的值为true assert res['success'] == expected['success'], "success的值为: %s" % res['success'] if __name__ == "__main__": # pytest.main(['-v', 'test_asset.py']) pytest.main(['-v', 'test_asset.py', '--html=report/asset_report.html', '--self-contained-html']) 5. 添加日志模块1)使用配置文件配置loggers、handlers和formatters(日志器、处理器和格式器),文件名称是log.conf [loggers] keys=root,main [logger_root] level=DEBUG handlers=consoleHandler,fileHandler [logger_main] level=DEBUG qualname=main handlers=fileHandler [handlers] keys=consoleHandler,fileHandler [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=fmt args=(sys.stdout,) [handler_fileHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=fmt args=('../log/Wallet_API_Test.log','a') [formatters] keys=fmt [formatter_fmt] format=%(asctime)s - %(filename)s - %(levelname)s - [line:%(lineno)d] - %(message)s2)使用fileConfig()函数读取日志配置文件 # fileName: get_log.py import logging.config import logging # 读取日志配置文件 def get_log(): con_log = "../configs/log.conf" logging.config.fileConfig(con_log) log = logging.getLogger() return log 6. 生成测试报告1)安装pytest-html插件。也可以使用allure插件生成测试报告,但是如果pytest版本过高,就无法识别allure插件 2)添加“--self-contained-html”可以整合样式文件到html文档中,方便之后发送测试报告到邮箱 pytest.main(['-v', '--html=report/all_report.html', '--self-contained-html']) 7. 测试报告发送至邮箱 #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: run_email.py from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header import smtplib # 定义发邮件 def send_mail(file_path): f = open(file_path, 'rb') mail_body = f.read() f.close() smtpserver = 'smtp.qq.com' # 设置登录邮箱的账号和授权密码 user = '[email protected]' password = "" sender = '[email protected]' # 可添加多个收件人的邮箱 receives = ['[email protected]'] # 构造邮件对象 msg = MIMEMultipart('mixed') # 定义邮件的标题 subject = '接口自动化测试报告' # HTML邮件正文,定义成字典 msg['Subject'] = Header(subject, "utf-8") msg['From'] = sender msg['To'] = ','.join(receives) # 构造文字内容 text_plain = MIMEText("附件是最新的接口自动化测试报告,请查看", 'html', 'utf-8') msg.attach(text_plain) # 构造附件 text_attr = MIMEText(mail_body, 'base64', 'utf-8') text_attr["Content-Type"] = 'application/octet-stream' text_attr['Content-Disposition'] = 'attachment; filename = "test.html"' msg.attach(text_attr) # 邮箱设置时勾选了SSL加密连接,进行防垃圾邮件,SSL协议端口号要使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) # 向服务器标识用户身份 smtp.helo(smtpserver) # 向服务器返回确认结果 smtp.ehlo(smtpserver) # 登录邮箱的账号和授权密码 smtp.login(user, password) print("开始发送邮件...") # 开始进行邮件的发送,msg表示已定义的字典 smtp.sendmail(sender, receives, msg.as_string()) smtp.quit() print("已发送邮件") if __name__ == "__main__": report = "../testcase/report/report.html" send_mail(report) 8. 优化动态数据的存储把多个登录账号信息等动态数据放到excel表格中,使用xrld和xlutils库对表格进行读取和写入。利用excel存储测试数据,实现测试数据和测试脚本的分离,方便测试数据的维护 9. 项目目录一直在更新中,文件名可能与其他地方不一致 二、上传代码到github1. 创建git仓库:进入项目的根目录,比如项目名是:Test,则进入Test文件夹下 命令:git init 2. 将项目内所有文件添加至仓库中 命令:git add . 3. commit到仓库 命令:git commit -m '首次提交' 4. 到github上创建Repositories后,复制仓库的地址,比如:https://github.com/XXX/Test.git 5. 将本地仓库关联到github上(很重要) 命令:git remote add origin https://github.com/XXX/Test.git 6. 上传代码到github远程仓库:其中-u是把本地master分支和远程master分支关联起来,以后再push时不需要加上-u 命令:git push -u origin master 7. 若再次上传,则要执行这三步: 1)把Test中的文件都添加进来:git add . 2)提交暂存区的文件,其中message是简要说明这次提交的信息:git commit -m "message" 3)把本地文件推送到github上(有时候需要输入github账号和密码): git push origin master 8. git常用命令,可参考文章git常用命令结合若干个使用场景 9. 项目git地址:(备注:代码写的不够专业,一直在优化改进中。有兴趣的可以一起讨论) https://github.com/ChangYixue/Test.git 三、运行测试用例的两种方法 1. 命令行模式1)先进入测试用例文件所在目录,然后使用“pytest”命令执行该目录下所有的测试用例文件; 2)也可以指定某一个测试用例文件,直接在pytest后面加上文件名称即可,比如“pytest test_asset.py” 3)执行”某文件下的类中所有用例方法“或者”某方法“,分别用命令”pytest 文件名::类名“和”pytest 文件名::类名::方法名“ 2. 在python脚本中调用pytest if __name__ == "__main__": # 若存在多个标记,则用or连接,形成一个测试集,比如'-m=assetList or test or allLists' pytest.main(['-v', 'test_asset.py', '-m=test']) 四、重构接口自动化测试框架1. 背景:公司开发人员帮忙重构了脚本,使配置测试环境、维护测试数据、取接口信息和处理接口依赖等更加灵活 2. 重构后的框架简介请移步:Python+Pytest+tox 接口自动化测试框架 未完待续...... |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |