FrostySun

Python接口自动化入门

Python接口自动化

接口的简介

什么是接口

接口(interface)是指通过一个协议对外或者对内提供的一个标准化的对接

现实中的接口:USB接口、Type-c接口、网线接口等等

对于我们而言,接口就是开发者将内部的方法通过某种方式对外暴露,让我们可以通过对方设定的标准进行访问的从而实现某种功能

接口的分类

通过接口类型分类
  • 内部接口

内部接口是开发者在程序内部某种功能的方法,这些方法只允许在程序内部调用,而不允许通过外部的方式来调用

内部接口如:登录接口、注册接口等等

  • 外部接口

外部接口也是开发者在程序内部的设定的方法,但是这些方法被开发者使用某些技术通过规定好的协议等等将这些方法对外暴露,让我们可以通过开发者设定的一系列协议规定等来访问对方提供的某些功能等等

外部接口:支付宝的支付接口、微信支付接口等等

请求协议分类
  • HTTP接口

    • HTTP请求协议分类:getpost、put、delete、option
  • WebService接口
  • socket接口

接口测试的本质

接口是程序内部的方法通过某种手段对外提供,其实接口的测试就是我们去测试这个方法(函数)是否能达到我们的预期

接口请求中的一些常用参数

  • General

    • Request URL:请求的url地址
    • Request Method:请求的方式
    • Status Code:请求的状态
  • Response Headers

    • Content-Language:表示客户端期望服务器返回的内容的语言
    • Content-Length:表示传输的请求/响应的Body的长度
    • Content-Type:代表内容的媒体类型和编码格式
  • Request Headers

    • Accept:客户端期望服务器返回的数据类型
    • Accept-Language:客户端传给服务器的数据的语言
    • Cookie:客户端存储并发送给服务器端的Cookie信息
    • Referer:发起请求的父链接,常用来作为防盗链
    • User-Agent:客户端的代理类型,通常是浏览器类型等等

Cookie和Session区别

  • Cookie

Cookie是服务器下发给浏览器一些缓存数据,浏览器保存到本地,以便下次请求的时候通过Cookie携带给服务器,通常用来验证登录等等,应为是存储在用户浏览器本地,可能会有安全隐患

  • Session

Session是服务器存储的一些数据,通常是和浏览器的Cookie配合使用,相比较Cookie,Session更加安全,存储量更大等等优势

调用Python访问接口

安装相关模块

  • requests模块

安装模块有以下两种方式

  • 通过Pycharm安装

    打开Pycharm->settings->Project->Project Interpreter->右边+号->输入我们需要安装的模块并选中->Install Package->等待安装完成即可

    image-20191203170941344.png

    image-20191203171019795.png

  • 通过CMD命令行安装

    打开CMD窗口,输入以下命令进行安装,等待安装完成即可

    # pip install 模块名称
    pip install requests

导入requests模块进行接口请求

此处我们使用聚合数据的接口进行测试

官网地址:https://www.juhe.cn/

申请账号,并在API页面查找部分免费使用的接口进行申请测试

image-20191203171718742.png

  • GET请求

    import requests
    
  1. = requests.get(url)
    print(res)
    print(res.status_code)
    print(res.headers)
    print(res.cookies)
    print(res.text)

  • POST请求

    import requests
    
    url = "http://apis.juhe.cn/simpleWeather/query"
    data = {"city": "北京", "key": ""}
    res = requests.post(url, data)
    print(res)
    print(res.status_code)
    print(res.headers)
    print(res.cookies)
    print(res.text)
    print(res.json(), type(res.json()))

进行用例、测试报告的操作

编写测试用例

  • 测试报告编写需要注意一下几点

    1. 测试报告需要引入我们unittest测试模块
    2. 测试用例的类需要继承unittest.TestCase
    3. 测试用例的方法命名开头必须以test开头
    4. 运行所有测试用例可调用main方法运行unittest.main()来执行
## 示例
import unittest

class TestMethod(unittest.TestCase):
    def test1(self):
        print("第一个测试用例")
        res = 1 + 1
        # 进行断言,一个参数是期望结果,第二个是实际结果
        try:
            self.assertEqual(1, res)
        except AssertionError as e:
            print("断言出错了,异常信息:{0}".format(e))
            # 抛出异常
            raise e

    def test2(self):
        print("第二个测试用例")
        res = 1 + 1
        # 进行断言,一个参数是期望结果,第二个是实际结果
        self.assertEqual(2, res)


if __name__ == '__main__':
    # 执行所有测试用例
    unittest.main()

生成测试报告

生成测试报告的方法分为两种
  1. 调用unittest默认的可以生成一个txt文件的测试报告,此测试报告的类型有点类似我们控制台的运行结果

    import unittest
    # 导入我们的测试报告的类
    from test01.testcase.TestCase import TestMethod
    
    # 进行实例化存储用例的对象,用来存储用例
    suite = unittest.TestSuite()
    # 添加需要执行的测试用例  添加的是单个用例
    suite.addTest(TestMethod('test1'))
    suite.addTest(TestMethod("test2"))
    
    with open("text.txt", "w+", encoding="utf-8") as file:
        # file = open("text.txt", "w+", encoding="utf-8")
        """
        @:param stream 表示需要保存测试用例的IO对象
        @:param verbosity 表示执行用例的保存结果的详细程度
        """
        runner = unittest.TextTestRunner(stream=file, descriptions=None, verbosity=2)
        runner.run(suite)
  1. 调用一些测试报告的生成模板进行HTML格式的测试报告的生成,此种测试报告更为详细,可以包含截图、日志、接口信息等等

    import unittest
    from test01.testcase.TestCase import TestMethod
    """
    引入我们需要生成测试报告的包
    此文件可以在https://github.com/wishchen/ExtentHTMLTestRunner进行下载
    下载后只需要将此文件复合到python安装目录下的lib目录下即可
    """
    from ExtentHTMLTestRunner import HTMLTestRunner
    # 进行实例化存储用例的对象,用来存储用例
    suite = unittest.TestSuite()
    # 添加需要执行的测试用例  添加的是单个用例
    """
    添加测试用例的方法有三种,三种不可同时使用
    1、添加单个测试用例,可以单独执行一个用例
    2、添加整个测试用例的类文件,以执行类文件中的所有测试用例
    3、添加整个测试用例的包,执行包下面的所有类文件中所包含的测试用例
    """
    # 此为第一种,添加单个测试用例
    suite.addTest(TestMethod('test1'))
    suite.addTest(TestMethod("test2"))
    # 此为第二种,添加测试用例的类文件
    loader = unittest.TestLoader()
    suite.addTest(loader.loadTestsFromTestCase(TestMethod))
    # 此为第三种,添加测试用例的包
    from test01 import testcase
    suite.addTest(loader.loadTestsFromModule(testcase))
    
    ## 生成测试用例
    with open("index.html", "wb") as file:
        runner = HTMLTestRunner(stream=file, verbosity=2, title="自动化测试报告", description="我得第一个测试报告")
        runner.run(suite)

优化测试用例的编写

  1. 创建我们的项目名称

     >P2P
     >> data
     >> run
     >> testcase
     >> util
  2. 创建参数化类

    class GatData:
        """
        测试用例需要用到的参数
        """
        ## 请求的公共URL地址
        url = "http://localhost:8080/p2p"
        ## 需要用到的手机号参数
        phone = None
        ## 短信验证码参数
        SMSCode = None
        ## 密码参数
        passwd = None
    
  3. 创建工具包,进行工具封装

    • 请求公共方法

      import requests
      import json
      
      
      class HttpRequest:
          """
          HTTP请求提取的公共方法
          可以将一些固定化的请求头一类的参数封装到此,不必要每个测试用例都进行编写
          """
      
          def get(self, url):
              """
              get请求的公共方法
              :param url: 请求的url地址
              """
              return requests.get(url)
      
          def post(self, url, data):
              """
               post请求的公共方法
              :param url: 请求的url地址
              :param data: post请求的参数
              """
              headers = {"Content-Type": "application/json"}
              data1 = json.dumps(data)
              return requests.post(url, data1, headers=headers)
      
    • 创建导出测试用例报告公共方法

      import unittest
      from ExtentHTMLTestRunner import HTMLTestRunner
      
      
      class ExportTest:
      
          def run_test(self, TestCase, title):
              """
              封装的测试用例报告导出工具方法
              :param TestCase: 测试用例的类
              :param title: 测试用例标题
              """
              suite = unittest.TestSuite()
              loader = unittest.TestLoader()
              suite.addTest(loader.loadTestsFromTestCase(TestCase))
              with open("index.html", "wb") as file:
                  runner = HTMLTestRunner(stream=file, verbosity=2, title=title,
                                          description="我的自动化测试用例")
                  runner.run(suite)
      
  4. 创建测试用例

    import unittest
    from P2P.util.HttpRequest import HttpRequest
    from P2P.data.GetData import GatData
    """
    创建测试用例类,继承unittest.TestCase
    """
    class TestCase(unittest.TestCase):
        """
        重写我们unittest的setUp方法和tearDown方法
        """
    
        def setUp(self) -> None:
            """
            此处我们可以调用此方法进行一些前置准备工作,比如说初始化我们的参数类
            加载参数Excel表格等
            """
            ## 初始化一个手机号
            setattr(GatData, "phone", "17629196006")
    
        def test_SMSCode(self):
            """
            短信验证码接口
            """
            url = getattr(GatData, "url") + "/getSMSCode"
            data = {"phone": getattr(GatData, "phone")}
            res = HttpRequest().post(url=url, data=data)
            if res.status_code == 200:
                res_json = res.json()
                try:
                    self.assertEqual(200, res_json["code"])
                except AssertionError as e:
                    print(res_json["message"])
                    raise
                setattr(GatData, "SMSCode", res_json["data"]["SMSCode"])
                print(res_json["message"])
                print("短信验证码接口测试通过")
            else:
                print("接口请求失败,错误码:{0},错误信息:{1}".format(res.status_code, res.json()["message"]))
    
        def tearDown(self) -> None:
            pass
    
  5. 执行测试

    • 创建run包

      ## 引入测试用例的包
      from P2P.testcase.TestCase import TestCase
      ## 引入导出测试报告的包
      from P2P.util.ExportTest import ExportTest
      
      ## 调用生成测试报告
      ExportTest().run_test(TestCase, title="p2p自动化测试报告")