【Unittest】接口自动化测试框架设计

Api 自动化测试

个人源码:https://github.com/wupeng-paynewinn/ApiTest_Unittest
整体:

  • ApiTest
    • Common
      • A.py
      • BaseTest.py
      • Cache.py
      • Decorator.py
      • General.py
      • Third.py
      • init.py
    • Config
      • config.ini
      • product-config.ini
      • test-config.ini
    • Report
      • init.py
      • TestReport.html
    • TestCase
      • test_01_02_login.py
    • TestDate
      • 01_02_login.json
    • readme.md
    • requirements.txt
    • run_all_case.py

一、Config 模块

|-- config.ini
|-- product-config.ini
|-- test-config.ini

在 config.ini 中的 [ENVIRONMENT] 块中定义环境、发件人、收件人、邮件主题,如:

[ENVIRONMENT]
environment=test

[SENDER]
smtpserver = mail.qq.com
user = xxx@qq.com
password = xxxxxx
sender = xxx@qq.com

[RECEIVER]
;receiver = xx1@xx.com, xx2@xx.com
receiver = xx@xx.com

[MSG]
subject = 小象自动定时测试报告(生产api)

将会读取 test-config.ini 文件中的配置,由这种方式将配置文件与环境剥离开。

[HOST]
cn_https=https://xxx.10jqka.com.cn
cn_http=http://xxx.10jqka.com.cn
en_https=https://
en_http=http://

[HOST] 块中定义host,可以在 case.json 文件中使用,如:

{
  "request": {
    "host": "{{cn_https}}", 
    "api": "/info/api/v3/auth/post/login",
    "method": "POST", 
    "header": {
      "Content-Type": "application/x-www-form-urlencoded"
    }
  },
    ....
}

使用 {{}} 包裹,将会从config中解析。否则,当成字符串处理

二、case 定义形式

测试用例,以 json 文件的形式定义。主要包括一个 request 块,和多个 case 块。基本的形式如下:

{
  "request": {
    "host": "{{cn_https}}", 
    "api": "/info/api/v3/auth/post/login",
    "method": "POST", 
    "header": {
      "Content-Type": "application/x-www-form-urlencoded"
    }
  },
  "case_01": {
    "query":"test=1&test2=2",
    "data": [
      {
        "key": "useragent",
        "value": "android",
        "type": "text"
      }
    ],
    "assert": [
      {
        "type": "eq",
        "rules": "status",
        "expect": 0,
        "msg": "这里是报错显示的msg"
      }
    ],
    "set_result": [
      {
        "key": "cache_key",
        "value": "payload.id"
      }
    ]
  }
}

request 对象中包含:

  • host:在config 中定义
  • api:接口地址,与host组成完整url
  • method:请求方式,支持POST与GET
  • header:对象,可填写多个键值对

case_01 为用例名称,一个json文件中可以含有多个用例。同一个文件下所有的用例,请求的内容都相同。

  • query: 字符串,按照"field1=value1&field2=value2"规则,解析结果将于data合并

  • data: 数组,按照method内容,post则放在body中发送,get则放在url中。数组中可放入多个对象。

    • key: 必填,参数名称。
    • value:必填,请求内容。
    • type:必填,类型:text/array/json/file
    • file_name: 非必填,type 为 file 时需要参数。文件名称。
    • file_type: 非必填,type 为 file 时需要参数。文件类型。例子:text/plain
    • from:非必填,数据来源。当数据来源于cache时,填cache。目前只支持cache
  • assert:数组,定义请求结果断言。可以含有多个对象,定义不同的断言,

    • type:断言类型,eq/not_eq等
    • rules:取值规则,返回数据中的结构 例如 payload.group_id
    • expect: 预期值,对比用
  • set_result:非必填 数组,需要保存在cache中的数据

    • key: 名称,注意唯一性
    • result_field:返回数据的结构 例如:payload.group_id

三、定义单元测试

# -*- coding: utf-8 -*-
import unittest
from Common.BaseTest import BaseTest

# 定义测试类
class TestLogin(BaseTest):
    # 定义测试用例文件地址
    json_file = "/TestData"
	
    # 定义单个测试用例
    def test_01_login(self):
        # 定义需要执行的case名称
        self.run_case("case_01")

    def test_02_login(self):
        self.run_case("case_02")
        # 保存全部返回结果
        self.set_result("286592399")

    def test_03_create_group(self):
        # 在用例中定义测试用例文件地址
        self.set_json_file("/TestData")
        # 定义单个参数
        self.set_single_extra_body("code_list", "1112,1113")
        self.set_single_extra_body("code", "1200")
        self.run_case("case_01")


if __name__ == '__main__':
    unittest.main()

四、Cache 模块

为了方便用例间上下文联动,引入cache模块。可以将接口返回的结果保存在cache中,也可以从cache中取出所需要的内容放入到请求体中。

但需要注意的是,cache模块受用例执行顺序的影响,必须保证当前取值的用例在存值用例的后面执行。

使用:

  • 配合 json 文件:

    • 存值,在 {case_name}.set_result 块中定义需要保存的数据

      例如:

      {
      "set_result": [
            {
              "key": "286592399_token",
              "result_field": "payload.token"
            },
            {
              "key": "286592399_all",
              "result_field": "*"
            }
          ]
      }
      
    • 取值,在 {case_name}.data 块中定义需要取值的数据

    例如:

    {
      "data": [
        	{
          	"key": "token",
          	"value": "{{286592399_token}}",
          	"type": "text"
        	}
      ]
    }
    

    data 中使用 {{}} 将会从cache中取值

  • 配合 test 类:

    • 存值:

      使用 set_result 方法保存全部数据。

      self.run_case("case_02")
      self.set_result("286592399")
      

      这两个方法会将 case_02 的所有返回结果保存在286592399 键中。set_result 方法 必须在 run_case 之后执行。

      也可以写成:

      self.run_case("case_02").set_result("286592399")
      
    • 取值:

      使用 get_result 方法从cache中取值。

      self.get_cache(key="286592399",r="")
      

      其中,r 为取值规则。如果为空,则将 286592399 键中所有数据取出,如果需要取出指定结构下的数据,只需要给 r 设定规则,例如:

      self.get_cache(key="286592399",r="payload.token")
      

五、给case请求体增加参数

  • 增加 header

    • set_extra_header

        self.set_extra_header({"test_header":"header","test_data2":"header"})
      
      
    • set_single_extra_header

      self.set_single_extra_header(key="test_header",value="header")
      
  • 增加 body(post):

    ​ 将在body体中传输

    • set_extra_body

      self.set_extra_body({"test_data":"data","test_data1":"data"})
      
    • set_single_extra_body

      self.set_single_body(key="test_data",value="1")
      
  • 增加 params (get):

    ​ 将在url中传输

    • set_extra_params

      self.set_extra_body({"test_data":"data","test_data1":"data"})
      
    • set_single_extra_params

      self.set_single_body(key="test_data",value="1")
      

      以上将被解析为: http://www.domian.com/some_api?test_data=data&test_data1=data

六、执行顺序问题

​ 在 run_all_case.py 文件中定义测试用例执行:

suite = unittest.TestSuite()
suite.addTest(TestVanishLogin('test_1_login_01'))
suite.addTest(TestVanishLogin('test_1_login_02'))
suite.addTest(TestVanishLogin('test_2_create_01'))
runner = unittest.TextTestRunner(verbosity=2)

runner.run(suite)

使用 addTest 手动增加测试用例,设置执行顺序。在执行用例很多的情况下,比较麻烦,也可以使用:

discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#runner.run(discover)
runner = HTMLTestRunner(stream=fp, title=u'测试报告', description=u'用例执行情况:')
runner.run(discover)

使用自动 discover 功能,自动加载所有测试用例,但其加载执行的顺序是按照文件名和方法名排序的。

需要优先执行的文件可以将文件名命名为: test_1_1_1_vanish_account_login.py

文件内需要优先执行的用例可以将方法名命名为: test_1_1_account_login_01()

用名称中的数字用来控制用例执行顺序。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值