接口自动化笔记

配置:

在pycharm中安装requests第三方库

打开DOS命令或者在pycharm的terminal中输入pip install requests就可以安装了

安装pyyaml 5.3.1第三方库

打开DOS命令或者在pycharm的terminal中输入pip install pyyaml安装

语法:

  1. 使用单元测试框架

    class (类名):
    def setUP(self):
    passdef test_01(self):
    print('this is test01’)
    def tearDown(self):
    pass
  2. 跳过用例

    #如果想要跳过某条用例,只需要在前面加****@unittest.skip**# @unittest.skip #跳过本条用例def test_02(self):
        print('this is test02’)def test_03(self):
        print('this is test03’)
  3. 只在开始和结束输出,每条用例运行中不再输出

    @classmethoddef setUpClass(cls):
        print('this is start…’)@classmethoddef tearDownClass(cls):
        print('this is end…’)
  4. 断言

    **self.assertIn('预期结果****’,res.text)**

    如果断言结果与实际结果不一致,则会出现下方情况,点击查看差异 左边预期结果,右边实际结果

  5. 设置全局变量global 在登录接口中设置一个cookie的全局变量,下边的接口中就可以使用了

    global cokcok=res.cookies
  6. 导入用例: 先在项目中新建一个Python Package命名为case,然后在其中新建一个后缀为.yaml的文件, 然后在文件中写入用例,格式为:

    Url: 网址 #每个参数名的冒号后面要加空格再跟参数值method: 请求方式Detil:描述(此项可不写)data: 参数名: 参数值(不加引号)check:
  7. 预期结果(-后有空格) 如:

    url: http://192.168.2.110/geeknet/flow.php?step=add_to_cartmethod: POSTDetil: 加入购物车data:
      goods: '{“quick”:1,”spec”:[],”goods_id”:62,”number”:”1”,”parent”:0}’check: #预期结果
      - one_step_buy-url: http://192.168.2.110/geeknet/flow.php?step=cartmethod: GETdata:check:
    • 购物车( 1 ) 在类前添加@ddt.ddt 然后在需要引入的函数前加@ddt.file_data(r’用例文件存放路径’)如

      @ddt.file_data(r’D:\python\jiekou0518\case\api.yaml’)#加r防止路径转移

      然后在函数中使用如:

      def test_one(self,**test_data):url=test_data.get('url’)
  8. 如何连接数据库 (1)新建一个python包config,然后在其中创建一个config.ini文件,向其中写入数据库的连接配置:哪个MySQL连接,主机,端口号,用户名,密码,库名,编码方式:

    [MYSQL]host = 192.168.2.110port = 3306user = rootpasswd = rootdb = gkcharset = utf8

    (2)在common文件夹中建一个Python文件configmysql来配置连接数据库

    #配置
    mysqlimport pymysql
    import config
    parserconfig = configparser.ConfigParser()
    #读取配置文件
    config.read(r’D:\python\jiekou0518\config\config.ini’)
    class ApiTools():
    #定义函数连接数据库
    def conn_mysql(self):
        host = config.get('MYSQL’,’host’)
        port = config.get('MYSQL’,’port’)
        user = config.get('MYSQL’,’user’)
        passwd = config.get('MYSQL’,’passwd’)
        db = config.get('MYSQL’,’db’)
        charset = config.get('MYSQL’,’charset’)
        self.connect = pymysql.connect(
            host = host,
            port = int(port),
            user = user,
            passwd = passwd,
            db = db,
            charset = charset,
        )
        #连接数据库中的游标cursor,用来执行sql语句
        self.cursor = self.connect.cursor()# 定义执行MySQL的函数,不同的场景下有不同的方法def execute_sql(self,sql):
        '’’ 执行sql语句,包括更新和新增数据 '’’
        self.conn_mysql() #连接数据库并获取游标
        self.cursor.execute(sql) #用游标去执行sql语句
        self.connect.commit() #执行完毕提交def search_sql(self,sql):
        '’’ 执行查询语句 '’’
        self.conn_mysql()
        self.cursor.execute(sql)
        return self.cursor.fetchall() #返回所有行的值#定义关闭sql连接的函数,避免占用服务器资源def close_sql(self):
        '’’ 关闭游标和数据库连接 '’’
        self.cursor.close()
        self.connect.close()#测接口要测幂等,为了防止重复提交if __name__ == '__main__’:too = ApiTools()too.conn_mysql()sql = 'delete from gk_order_info WHERE zipcode =457100;’api = too.execute_sql(sql)too.close_sql()print(api)
  9. 最后在runfile文件中新增*tearDownClass*函数,用来删除用例执行后的脏数据(无用的)

    @classmethoddef tearDownClass(cls):
        too = configmysql.ApiTools()
        too.conn_mysql()
        sql = “delete from gk_order_info where order_sn in(select o.order_sn from “           “(select order_sn from gk_order_info order by add_time desc limit 1) as o)”
        too.execute_sql(sql)
        too.close_sql()
  10. 最后将用例打印出报告,使用unittest。*makeSuite(*类名*)*可以将主函数所有的类都添加到测试集合中

    if __name__=='__main__’:
    #
    unittest.main()
    su=unittest.TestSuite()
    #建立测试集合
    su.addTest(unittest.makeSuite(Test))
    #将主函数中的所有用例都添加进去
    now=time.strftime('%Y-%m-%d %H-%M-%S')
    #使用当前时间并格式化时间为年月日时分秒
    filename = r’D:\python\jiekou0518\report\ '+ now +’resuilt.html’
    fp=open(filename,’wb’)runner=HTMLTestRunner(stream=fp,title='自动化测试报告’,description='用例描述’)
    runner.run(su)
    fp.close()

    Runfile文件案例:

    import unittest
    import ddt,time,requests
    from common import configmysql
    from HTMLTestRunner import HTMLTest
    Runner@ddt.ddtclass Test(unittest.TestCase):
    @classmethoddef
    setUpClass(cls):
    #在所有用例执行之前先先执行登录的用例,获取cookies
        url='http://192.168.2.110/geeknet/user.php’
        data={
            'username’:’lee000000’,
            'password’:’000000’,
            'act’:’act_login’,
            'back_act’:’http://192.168.2.110/geeknet/',
            'submit’:’’
        }
        res=requests.post(url=url,data=data)
        cls.assertIn(cls,’欢迎您回来’,res.text)
        global cok
        cok=res.cookies@ddt.file_data(r’D:\python\jiekou0518\case\api.yaml’)#加r防止路径转移def test_one(self,**test_data):
        url=test_data.get('url’)
        method=test_data.get('method’)
        detil=test_data.get('detil’)
        data=test_data.get('data’)
        check=test_data.get('check’)
        if method=='GET’:
            #转化为文本格式,方便后边去断言
            res=requests.get(url=url,cookies=cok).text
        elif method=='POST’:
            res=requests.post(url=url,data=data,cookies=cok).text
        # for I in check:
        #     try:
        #         self.assertIn(i,res)
        #         print(i,’用例执行成功’)
        #     except Exception as e:
        #         print(i,’用例执行失败’)
        for I in check:
                self.assertIn(i,res)@classmethoddef tearDownClass(cls):
        too = configmysql.ApiTools()
        too.conn_mysql()
        sql = “delete from gk_order_info where order_sn in(select o.order_sn from “           “(select order_sn from gk_order_info order by add_time desc limit 1) as o)”
        too.execute_sql(sql)
        too.close_sql()
        if __name__=='__main__’:
        #
        unittest.main()
        su=unittest.TestSuite()
        #建立测试集合
        su.addTest(unittest.makeSuite(Test))
        #将主函数中的所有用例都添加进去
        now=time.strftime('%Y-%m-%d %H-%M-%S')
        #使用当前时间并格式化时间为年月日时分秒
        filename = r’D:\python\jiekou0518\report\ '+ now +’resuilt.html’fp=open(filename,’wb’)
        runner=HTMLTestRunner(stream=fp,title='自动化测试报告’,description='用例描述’)
        runner.run(su)
        fp.close()
  11. 如何将测试报告通过邮件发送到指定人员 Config.ini 配置mail163邮箱时,password不是登录密码,只是一个授权码 (1)在config.ini配置文件中新增邮箱配置:

    [email]smtpserver = smtp.163.com
    sender = luokuo8080@163.com
    password = luokuo8080
    receive = luokuo1018@163.com

    (2)在common包中新增configmail.py文件。编写发送邮件的代码

    import configparser
    import osimport smtplib
    from email.mime.text import MIMEText
    from email.header import Header
    config = configparser.ConfigParser()config.read(r’D:\python\jiekou0518\config\config.ini’)
    class Send_mail:
    #我们需要先将最新的测试报告传到我们的函数中
    def send_email(self,new_report):
        #parm new_report是把找到的最新的测试报告传进来作为邮件内容发送
        f = open(new_report,’rb’)
        body = f.read()
        f.close()
        smtpserver = config.get('email','smtpserver') #从config.ini文件中取出email的参数    sender = config.get('email’,’sender’)
        password = config.get('email’,’password’)
        receive = config.get('email’,’receive’)
        subject = 'API TEST 自动化测试报告lee'  #定义标题    msg = MIMEText(body,’html’,’utf-8’)
        msg['from’] = sender
        msg['to’] = receive
        msg['subject’] = Header(subject,’utf-8’)
        smtp = smtplib.SMTP() #实例化smtp(发送邮件的方法)
        smtp.connect(smtpserver) #连接smtp服务器
        smtp.login(sender,password) #登录
        smtp.sendmail(sender,receive,msg.as_string()) #发送
        smtp.quit() #退出def latest_report(self,report_dir):
        #:param report_dir:把报告存放的路径传进来,以供筛选最新生成的测试报告
        #report_dir:把报告存放的路径传进来
        lists = os.listdir(report_dir)
        #列举report_dir下面的所有文件 结果以列表的形式返回
        #对列表进行排序(默认从小到大)
        lists.sort(key = lambda fn:os.path.getmtime(report_dir + '\\’ +fn))
        #os.path.getmtime是获取文件的最后修改时间
        #os.path.join路径拼接
        file = os.path.join(report_dir,lists[-1])
        #即file= 'D:\python\jiekou0518\report\ 2020-05-20 10-46-05resuilt.html'    return file
        if __name__ == '__main__’:
        mail = Send_mail()
        report_dir = r’D:\python\jiekou0518\report’
        new_report = mail.latest_report(report_dir)mail.send_email(new_report)
        (3)在runfile中调用发送邮件的函数并将测试报告发送到指定邮箱#先引入configmail文件中的类f
        rom common.configmail import Send_mail
        #然后调用
        mail = Send_mail()
        report_dir = r’D:\python\jiekou0518\report’
        new_report = mail.latest_report(report_dir)
        mail.send_email(new_report)

简答说下你们的自动化是如何做的?

我们使用的是用python编写的一个小型的接口自动化 使用的是python+unittest+yaml+request+ddt框架,进行编写的接口自动化脚本。 一般我们会把接口自动化的测试用例按格式放到yaml文件里面 然后把一些固定的配置文件可以放到config.ini文件里面,比如说数据库的IP地址,账号和密码,端口,要连接的数据库的库名等等,如果需要调用config.ini里的配置可以通过实例化configparser把配置文件里面的内容给get进来然后我们会写一些经常用到的工具,放到tools里面,比如说连接数据库的函数,包括提交sql语句和查询语句和关闭数据库连接的函数。把他们放到configmysql文件里面,然后在我们测试的时候我们会把我们的主方法写在runmain.py 这个文件里面,然后在这个文件里面使用request方法重构get和post请求,我们会首先用ddt.file_data把yaml文件路径引入,然后定义一个函数,把测试用例的url,方法和请求参数以及预期结果通过**test_data把数据传进来之后再一个一个给get进来,然后用if语句去判断get请求或者post请求并用request去发送请求,然后用for循环把检查点给循环出来并进行assert断言,并用try方法去处理异常信息,然后执行完毕之后我们可以调用数据库处理的方法去进行数据清理,最后用HtmlTestrunner发送测试报告。

如何测试依赖的接口?

对于依赖的接口我们一般是 把上一个接口的返回值给一个中间变量return出来,并 且把这个变量设置成全局变量,如果下个接口使用直接调用这个全局变量就可以了。

如何测试需要登录的接口?

一般需要登录的接口我们使用的是unittest框架 那么我们就可以把需要登录的接口放到setupclass里面然后把cookie的值给一个 中间变量,然后把中间变量global成全局变量,然后下面的接口如果需要cookie直 接在请求的时候直接把全局变量的cookie传入进去就可以了。

测试用例放在哪?

我们的测试用例是在yaml文件里面管理的,把测试用例维护到yaml文件里面 然后在使用里面的测试用例的时候我们可以用ddt进行数据驱动,用ddt.file_data 把yaml文件的路径引入进来然后用get方法获取yaml文件里面的每个字段的字段名 然后再去构造请求。

接口产生的垃圾数据如何清理?

用python连数据库,做增删改查的操作。测试用例前置操作,用setUp做数据准备比如登录。测试用路后置操作,tearDown连接数据库做数据清理

python如何连接数据库(*mysql*)?

通过导入pymysql包去连接数据库 需要通过configparser用get方法去获取config.ini配置文件里面 的数据库的参数比如:port 、user 、passwd 、db名字、charset 编码方式 然后用pymsql.connet方法把参数传进去去连接数据库获取数据库游标cursor 然后用游标的execute方法去执行sql用commit方法去提交数据,如果是 查询的数据需要通过cursor.fetchall()获取所有数据并把数据return出来, 然后最后关闭游标,关闭连接。

**脚本结构:**
**— api.yaml**
**存放接口测试用例**
**— config.ini**
**存放数据库的连接配置**
**存放email的连接的配置**
**— common**
**—configmysql.py**
**构造数据库连接的方法**
**构造数据库执行(execute_sql)**
**/查询(****search_sql****)**
**/关闭数据库连接(****close_sql****)**
**--configemail.py**
**发送邮件**
**-- runmain.py**
**主方法**
(0)

相关推荐

  • 5 分钟掌握 Python 中常见的配置文件

    为什么要写配置文件 在开发过程中,我们常常会用到一些固定参数或者是常量.对于这些较为固定且常用到的部分,往往会将其写到一个固定文件中,避免在不同的模块代码中重复出现从而保持核心代码整洁. 这个固定文件 ...

  • Python 如何使用 HttpRunner 做接口自动化测试

    Python 如何使用 HttpRunner 做接口自动化测试

  • pytest文档73-pytest+yaml实现接口自动化框架之用例参数关联

    前言 使用 yaml 文件写测试用例的时候,如何在 yaml 文件的测试用例里面实现参数关联? 这是很多做自动化测试的小伙伴经常思考的一个问题. 接着前面的pytest+yaml 文件实现接口自动化框 ...

  • Python常用配置文件ini、json、yaml读写总结

    原创 吾非同 吾非同 3天前 开发项目时,为了维护一些经常需要变更的数据,比如数据库的连接信息.请求的url.测试数据等,需要将这些数据写入配置文件,将数据和代码分离,只需要修改配置文件的参数,就可以 ...

  • python接口自动化25-全局变量token项目设计

    获取token 在做接口自动化的时候,经常会遇到多个用例需要用同一个参数token,并且这些测试用例跨.py脚本了. 一般token只需要获取一次就行了,然后其它使用unittest框架的测试用例全部 ...

  • httprunner学习9-完整的用例结构(yaml&json)

    前言 前面几篇零散的学了一些httprunner的知识点,那么一个完整的 YAML/JSON 用例文件包含哪些关键字呢? 测试用例结构 在 HttpRunner 中,测试用例组织主要基于三个概念: 测 ...

  • 接口自动化

    一.自动化分类 (1)接口自动化 > python/java+requests+unittest框架来实现 > python/java+RF(RobotFramework)框架来实现--对 ...

  • python接口自动化1-发送get请求

    前言 requests模块,也就是老污龟,为啥叫它老污龟呢,因为这个官网上的logo就是这只污龟,接下来后面的自动化都离不开它. 一.环境安装 1.用pip安装requests模块 >>p ...

  • python接口自动化2-发送post请求

    前言 发送post的请求参考例子很简单,实际遇到的情况却是很复杂的,首先第一个post请求肯定是登录了,但登录是最难处理的.登录问题解决了,后面都简单了. 一.查看官方文档 1.学习一个新的模块,其实 ...

  • python接口自动化3-自动发帖(session)

    前言 上一篇模拟登录博客园,但这只是第一步,一般登录后,还会有其它的操作,如发帖,评论等,这时候如何保持会话呢? 一.session简介 1.查看帮助文档,贴了一部分,后面省略了 >>im ...

  • python接口自动化4-绕过验证码登录(cookie)

    前言 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接). 获取不到也没关系,可以通过添加cookie的方式绕过验证码. 一.抓登录coo ...

  • python接口自动化5-Json数据处理

    前言 有些post的请求参数是json格式的,这个前面第二篇post请求里面提到过,需要导入json模块处理. 一般常见的接口返回数据也是json格式的,我们在做判断时候,往往只需要提取其中几个关键的 ...

  • python接口自动化6-重定向(Location)

    前言 某屌丝男A鼓起勇气向女神B打电话表白,女神B是个心机婊觉得屌丝男A是好人,不想直接拒绝于是设置呼叫转移给闺蜜C了,最终屌丝男A和女神闺蜜C表白成功了,这种场景其实就是重定向了. 一.重定向 1. ...

  • python接口自动化7-参数关联

    前言 我们用自动化发帖之后,要想接着对这篇帖子操作,那就需要用参数关联了,发帖之后会有一个帖子的id,获取到这个id,继续操作传这个帖子id就可以了 一.删除草稿箱 1.我们前面讲过登录后保存草稿箱, ...

  • python接口自动化8-参数化

    前言 前面一篇实现了参数的关联,那种只是记流水账的完成功能,不便于维护,也没什么可读性,接下来这篇可以把每一个动作写成一个函数,这样更方便了. 参数化的思维只需记住一点:不要写死! 一.登录函数 1. ...