首页 >excel操作 > 内容

接口自动化测试框架

2023年1月14日 21:21

本文介绍一个接口自动化测试框架。

Python+unittest+requests

实现结果:读取Excel接口测试用例并执行,输出测试报告。

框架脑图

如图,各个模块及作用如上。

处理数据库

db_funcs用来处理数据库,实现数据库数据的读取操作。(如果没有用到则不需要)

import sqlite3from config.ProjectConfig import ETConfigfrom common.logger import write_logdef execute_db(sql):    """    连接接口项目sqlite数据库,并执行sql语句    :param sql: sql语句    :return:    """    try:        # 打开数据库连接        conn = sqlite3.connect("{0}\\studentManagementSystem\\db.sqlite3".format(ETConfig.PROJECT_DIR))        # 新建游标        cursor = conn.cursor()        # 执行sql        cursor.execute(sql)        # 获取执行结果        result = cursor.fetchall()        # 关闭游标、提交连接、关闭连接        cursor.close()        conn.commit()        conn.close()        return result    except sqlite3.OperationalError as e:        write_log.error("数据库连接,执行失败:{}".format(e))def init_db():    """    初始化数据库,删除掉departments的所有数据    :return:    """    execute_db("delete from departments;")if __name__ == '__main__':    init_db()

处理Excel

用来对写在Excel中的测试用例进行读取,和测试结果的写回。

from openpyxl import load_workbookclass DoExcel:   """读写Excel文件"""   def get_data(self,filename,sheetname):    wb=load_workbook(filename)    sheet=wb[sheetname]    test_data=[]    #读取Excel数据存入列表    for i in range(2,sheet.max_row+1):        row_data={}        row_data['case_id'] = sheet.cell(i, 1).value #第一列为case_id        row_data['module']=sheet.cell(i,2).value        row_data['title']=sheet.cell(i,3).value        row_data['headers'] = sheet.cell(i, 4).value        row_data['Cookie']=sheet.cell(i,5).value        row_data['method'] = sheet.cell(i, 6).value        row_data['url'] = sheet.cell(i, 7).value        row_data['data'] = sheet.cell(i,8).value        row_data['expected_code'] = sheet.cell(i, 9).value #预期状态码        row_data['actual_code'] = sheet.cell(i, 10).value #实际状态码        row_data['response']=sheet.cell(i,11).value        row_data['auth']=sheet.cell(i,13).value        row_data['file']=sheet.cell(i,14).value        test_data.append((row_data))    return test_data   #写入Excel方法   def write_back(self,filename,sheet_name,i,k,value):       #i为写入的行k为写入的列        wb=load_workbook(filename)        sheet=wb[sheet_name]        sheet.cell(i,k).value=value#写入表格第14列        wb.save(filename)if __name__ == '__main__':    test_data=DoExcel().get_data("D:/接口实战/接口自动化用例.xlsx",'storm')    # print(test_data)    DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx",'storm',2,5)

封装请求方法

对请求方法进行封装,通过传入的方法,来调用对于的request方法

#封装请求,让代码更简洁,更具有可读性,并且更好维护import requestsfrom  common.logger import write_logclass HttpReq(object):    """利用requests封装get请求和post请求需要传递的参数"""    def __init__(self):        self.headers = {"Content-Type": "application/json",                        # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36" 伪装user-agent                        }    @staticmethod    def http_request(url,data, http_method, headers=None, cookies=None, auth=None, file=None):        try:            if http_method.upper() == "GET":                res = requests.get(url, data=data, headers=headers, cookies=cookies, auth=auth, files=file)                return res            elif http_method.upper() == "POST":                res = requests.post(url, data=data, headers=headers, cookies=cookies, auth=auth, files=file)                return res            else:                # print("输入的请求方法不对")                write_log.info("输入的请求方法不对")        except Exception as e:            # print("请求报错了:{0}".format(e))            write_log.error("请求报错了:{0}".format(e))            raise eETReq = HttpReq()

日志模块

本模块用来生成执行测试用例时产生的日志

import loggingimport osfrom logging import handlersfrom config.ProjectConfig import ETConfigdef logger():    # os.makedirs("{}logs".format(ETConfig.Log_DIR), exist_ok=True)#os.makedirs() 方法用于递归创建目录。    log = logging.getLogger("{}\\et.log".format(ETConfig.Log_DIR))    format_str = logging.Formatter('%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s', '%Y-%m-%d %H:%M:%S')    # 按天录入日志,最多保存7天的日志    handler = handlers.TimedRotatingFileHandler(filename=("{}/et.log".format(ETConfig.Log_DIR)), when='D', backupCount=7, encoding='utf-8')    log.addHandler(handler)    log.setLevel(logging.INFO)    handler.setFormatter(format_str)    return logwrite_log = logger()write_log.info("你好")

发送邮件

本模块实现发送邮件功能,通过附件将html报告发送给对应的邮箱。

from email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom config.ProjectConfig import ETConfigfrom common.logger import write_logimport smtplibimport timeclass sendEmail:    # 发送邮件函数    def send_mail(self):        """        发送邮件        :return:        """        # 打开报告文件        # 邮箱信息        self.smtpserver = ETConfig.EMAIL_CONFIG['EMAIL_SERVER']        self.user = ETConfig.EMAIL_CONFIG['EMAIL_USER']        self.password = ETConfig.EMAIL_CONFIG['EMAIL_PWD']        self.sender = ETConfig.EMAIL_CONFIG['EMAIL_SENDER']        self.receiver = ETConfig.EMAIL_CONFIG['EMAIL_RECEIVER']        self.report_dir=ETConfig.Report_DIR        # # html报告路径        # self.report_dir = "{}report".format((ETConfig.Report_DIR))        with open('{}\\et_result.html'.format(self.report_dir), 'rb') as f:            mail_body = str(f.read(), encoding="utf-8")        msg = MIMEMultipart('mixed')        msg_html = MIMEText(mail_body, 'html', 'utf-8')        msg_html["Content-Disposition"] = 'attachment; filename="TestReport.html"'        msg.attach(msg_html)        msg_html1 = MIMEText(mail_body, 'html', 'utf-8')        msg.attach(msg_html1)#附件        msg['Subject'] = u'自动化测试报告 {}'.format(time.strftime("%Y-%m-%d", time.localtime()))        msg['From'] = u'AutoTest <%s>' % self.sender        msg['To'] = self.receiver        # msg['Cc'] = self.cc        try:            smtp = smtplib.SMTP()            smtp.connect(self.smtpserver)            smtp.login(self.user, self.password)            smtp.sendmail(self.sender, self.receiver, msg.as_string())            smtp.quit()            write_log.info("发送邮件成功!")        except Exception as e:            write_log.error("发送邮件失败:{}".format(e))

封装配置

ProjectConfig.py用来对项目用到的配置进行进行封装。

import osclass ProjectConfig(object):#封装配置    version="v1.0"    url="XXX"# 替换为你本地的接口项目路径(注意不是自动化项目路径)    PROJECT_DIR = "C:\\Users\\010702\\PycharmProjects\\easytest\\接口环境\\"    # 自动化测试项目目录    TEST_DIR = "D:\APItest"    Log_DIR="D:\\APItest\\log"    Report_DIR="D:\\APItest\\report"#邮件配置信息    EMAIL_CONFIG={"EMAIL_SERVER":"smtp.qq.com",#服务器                  "EMAIL_USER":"XXX",                  "EMAIL_PWD":"XXXXXXmdhje",#授权码                  "EMAIL_SENDER":"XXX",                  "EMAIL_RECEIVER":"XXX"                  }ETConfig=ProjectConfig()

测试用例模块

getUserStorm.py测试用例文件。

#storm项目获取用户信息 DDT+Excel Excel有几条数据,就执行几次用例import unittestimport requestsimport jsonfrom config.ProjectConfig import ETConfigfrom testcase.data.DepartmentData import ADD_DATAfrom ddt import ddt,data,unpackfrom common.wrapers import *#这里竟然可以只导入一个对象from common.HttpReq import ETReqfrom common.doExcel import DoExcelfrom common.HttpReq import HttpReqfrom common.is_json import IsJsonfrom common.logger import write_logimport warnings@ddtclass GetUserTest(unittest.TestCase):    test_data = DoExcel().get_data("D:/接口实战/接口自动化用例.xlsx", 'getuser')    #只要哪一行有值,就会被读为一条用例    @classmethod    def setUpClass(cls):       write_log.info("------------------")    """获取用户信息"""    def setUp(self):        warnings.simplefilter('ignore',ResourceWarning)    def tearDown(self):        pass    @write_case_log()    @data(*test_data)    def test_get_user_info(self,item):        print("正在执行测试用例{0}".format(item['title']))        r=HttpReq().http_request(url=item['url'],data=(item['data']),http_method=item['method'])        # print("响应文本为:"+r.text)        try:            self.assertEqual(item['expected_code'], r.json()['code'])  # 预期结果和直接返回的状态码比较            TestResult='PASS'            # print("测试用例执行成功")            write_log.info("测试用例执行成功")        except AssertionError as e:            TestResult='FAIL'            # print("执行用例出错(0)".format(e))            write_log.error("执行用例出错{0}".format(e))            raise e        finally:            DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,10,r.json()['code'])            DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,11,r.text)            DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,12,TestResult)#写入结果        # r=IsJson(r)        # self.assertEqual(item['expected'],r['code'])#结果和响应结果中的code边角if __name__ == '__main__':    # unittest.main()    suite=unittest.TestSuite()    suite.addTest(GetUserTest("test_get_user_info"))    # suite.addTest(AddDepartmentTest("test_add_department_2"))    runner=unittest.TextTestResult()    test_result=runner.run(suite)

执行用例

run.py用来执行用例,并生成测试报告。

import unittestimport platformimport os.pathfrom common.logger import write_logfrom config.ProjectConfig import ETConfigfrom common.HTMLTestRunnerCNs import HTMLTestRunnerfrom common.send_email import sendEmailclass RunCase(object):    report_dir=ETConfig.Report_DIR    #执行用例函数    def run_case(self):        # 运行测试用例并生成html测试报告        with open('{}//et_result.html'.format(self.report_dir), 'wb') as fp:            try:                write_log.info("RunCase执行用例--开始")                suite = unittest.TestSuite()                tests = unittest.defaultTestLoader.discover('..\\testcase', pattern='*Storm.py')                suite.addTest(tests)                runner = HTMLTestRunner(stream=fp, title=u'自动化测试报告', description=u'运行环境:{}'.format(platform.platform()),                                        tester="istester")                runner.run(suite)                write_log.info("RunCase执行用例--结束")            except Exception as e:                write_log.error("RunCase执行用例,生成报告失败:{}".format(e))if __name__ == '__main__':    test = RunCase()#创建对象    test.run_case()#调用测试用例执行函数    sendEmail().send_mail()    #调用发送邮件函数

测试报告

源码:https://github.com/2504973175/API_test.git


参考文章:https://blog.csdn.net/seanyang_/article/details/123763919

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时候联系我们修改或删除,在此表示感谢。

特别提醒:

1、请用户自行保存原始数据,为确保安全网站使用完即被永久销毁,如何人将无法再次获取。

2、如果上次文件较大或者涉及到复杂运算的数据,可能需要一定的时间,请耐心等待一会。

3、请按照用户协议文明上网,如果发现用户存在恶意行为,包括但不限于发布不合适言论妄图

     获取用户隐私信息等行为,网站将根据掌握的情况对用户进行限制部分行为、永久封号等处罚。

4、如果文件下载失败可能是弹出窗口被浏览器拦截,点击允许弹出即可,一般在网址栏位置设置

5、欢迎将网站推荐给其他人,网站持续更新更多功能敬请期待,收藏网站高效办公不迷路。

      



登录后回复

共有0条评论