自学接口自动化测试

        当你乘坐火车的时候,你不会想到一个30000mA(111Wh)的充电宝突然无法带上车了,你会不会生气呢?最新的铁路携带物品规定于7月开始实施,充电宝最多携带两个,每个额定容量不超过100Wh,也就是27000mA,所以过安检会让你要么寄快递,要么让别人来拿,要么留下,反正你是带不上火车的,要是你强行带走,可能警察也会强行把你带走。吃一点长一智,所以每次出行乘坐交通工具时,先看一看携带物品是否可以上车,充电宝、打火机、压缩性气体罐装物品如喷雾、香水、酒等等,不然非常影响你的出行,当然开车不需要考虑这些问题。说到底,还是没钱,还是要努力学习啊。

        这次总结的是(三)接口自动化测试-Python自带Requests+Unittest框架,此Python库是一款非常好用的脚本工具,毕竟Python语言容易上手,所以使用Python编写脚本进行测试也是非常方便的。


CSDN话题挑战赛第2期

参赛话题:学习笔记


目    录

        一、Requests简介

        1、不同测试方式区别

        2、Python特点

        3、Requests库的简介

        二、Requests常用函数

        1、环境搭建

        2、常用函数

        3、基本语法格式

        三、Requests用于接口测试

      1、不带参数的GET请求

        2、带参数的GET请求

        3、带参数的POST请求

        4、响应结果转换为JSON格式

        四、Requests库综合应用

        1、融入unittest框架

        2、参数化和断言

        3、输出测试报告和测试日志

        五、测试代码和运行结果

        1、测试代码

        2、运行结果


        一、Requests简介

        1、不同测试方式区别

工具

手写脚本

灵活性差

灵活性高

操作简单

需要一定的编程能力

用于较为单一的接口测试

用于业务连续的接口测试

        2、Python特点

        (1)简单

        (2)高级

        (3)面向对象

        (4)可扩展

        (5)免费和开源

        (6)边编译边执行

        (7)可移植

        (8)丰富的库

        3、Requests库的简介

        (1)官方文档:urllib.request --- 用于打开 URL 的可扩展库 — Python 3.10.7 文档

        (2)Requests是唯一的一个非转基因的Python HTTP库,可以安全享用。

        (3)特点

        Keep-Alive&连接池

        国际化域名和URL

        带持久Cookies的会话

        浏览器式的SSL认证

        自动内容解码

        Unicode响应体

        文件分块上传、下载

        流下载

        连接超时

        分块请求


        二、Requests常用函数

        1、环境搭建

        (1)非Python自带库,需单独安装

        windows→pip install requests、easy_install requests、或者pycharm中安装

        linux→sudo pip install requests

        2、常用函数

(1)requests.request() #构造一个请求,支持以下各种方法

(2)requests.get() #获取html的主要方法(至少有一个参数-接口地址、有返回值的方法。返回值就是本次请求的服务器响应结果)

(3)requests.post() #向html网页提交post请求的方法

(4)requests.head() #获取html头部信息的主要方法

(5)requests.put() #向html提交put请求的方法

(6)requests.patch() #向html提交局部修改的请求

(7)requests.delete() #向html提交删除请求

        3、基本语法格式

(1)Response常用属性

(2)r.status_code #http请求的返回状态,若为200则表示请求成功

(3)r.text #http响应内容的字符串形式,即返回的页面内容

(4)r.recoding #从http header中猜测的相应内容编码方式

(5)r.rapparent_encoding #从内容中分析处的响应内容编码方式(备选)

(6)r.content #http响应内容的二进制形式


        三、Requests用于接口测试

      1、不带参数的GET请求

        (1)发送不带参数的GET请求requests.get("url")

        (2)获取和输出各种响应值

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/19 8:25
# software: PyCharm

"""get请求"""

# (1)导入requests包
import requests
import json

# (2)构造一个不带参数的get请求
response = requests.get("http://www.baidu.com")

print(f"本次响应数据类型是{type(response)}")

# (3)输出本次响应的状态码
print(f"\n\n本次响应状态码数据类型是{type(response.status_code)}")
print(f"本次响应状态码是{response.status_code}")

# (4)输出本次响应的所有文本
print(f"\n\n本次响应文本数据类型是{type(response.text)}")
response.encoding = "utf-8"
print(f"本次响应文本是{response.text}")

# (5)输出本次响应的所有值
print(f"\n\n本次响应cookies数据类型是{type(response.cookies)}")
response.encoding = "utf-8"
print(f"本次响应网站的Cookies是{response.cookies}")

# (6)判断:本次请求后,服务器响应返回的字符串中,是否有“百度一下,你就知道”
exp = "百度一下,你就知道"
if exp in response.text:
    print(f"\n\n响应值中包含你希望的字符串:{exp}。")
else:
    print("\n\n响应值中不包含你希望的字符串。")

        2、带参数的GET请求

        (1)发送带参数的GET请求requests.get("url", params=params)

        (2)获取和输出各种响应值

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/19 8:25
# software: PyCharm

"""get请求"""

# (1)导入requests包
import requests
import json

# (2)构造一个不带参数的get请求、带参数的get请求、带参数的post请求
get_parameter = {
    "q": "apple",
    "from": "en",
    "to": "zh",
    "appid": "xxx",
    "salt": "202002121503",
    "sign": "7105f811ca9d3835146ed9c44ab46770",
}
response1 = requests.get("https://fanyi-api.baidu.com/api/trans/vip/translate", params=get_parameter)

print(f"\n本次响应数据类型是{type(response1)}")

# (3)输出本次响应的状态码
print(f"\n本次响应状态码数据类型是{type(response1.status_code)}")
print(f"本次响应状态码是{response1.status_code}")

# (4)输出本次响应的所有文本
print(f"\n本次响应文本数据类型是{type(response1.text)}")
response1.encoding = "utf-8"
print(f"本次响应文本是{response1.text}")

# (5)输出本次响应的所有值
print(f"\n本次响应cookies数据类型是{type(response1.cookies)}")
response1.encoding = "utf-8"
print(f"本次响应网站的Cookies是{response1.cookies}")

# (6)判断:本次请求后,服务器响应返回的字符串中,是否有“百度一下,你就知道”
exp = "apple"
if exp in response1.text:
    print(f"\n响应值中包含你希望的字符串:{exp}。")
else:
    print("\n响应值中不包含你希望的字符串。")
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/19 10:33
# software: PyCharm

"""
使用Python加requests库方式实现:输入一个字符串,通过百度翻译接口,输出其中文翻译内容
技术点:
    (1)输入函数input
    (2)get请求
    (3)带参数(构造数据:随机数函数random、加密函数MD5)
    appid-xxx、密钥-zzz
    (4)字符串的拼接
    (5)字符编码的转换(输入字符串必须转化为utf-8)
    (6)只输出翻译结即可(apple-苹果)
    (7)使用函数的方式调用
"""
import hashlib
from random import randint

import requests

# 设定字符编码格式
encoding = "utf-8"


def get_md5(content):
    """MD5加密函数"""
    # 获取一个MD5加密算法对象
    md = hashlib.md5()
    # 对字符串编码转化为“utf-8”,否则会报TypeError: Unicode-objects must be encoded before hashing
    md.update(content.encode(encoding))
    # 返回加密后的16进制字符串
    return md.hexdigest()


def test_baidu_input():
    """百度翻译函数"""
    # 定义接口URL
    url = "https://fanyi-api.baidu.com/api/trans/vip/translate"
    # 定义APPID
    app_id = "xxx"
    # 定义密钥secretkey
    secret_key = "zzz"
    # 定义随机数salt,直接转换为字符串
    salt = str(randint(100000, 999999))
    print(f"salt:{salt}")
    # 定义被翻译的字符串q
    q = input("请输入你要翻译的内容:")
    # 定义源语言from=auto,翻译语言to=zh
    tr_from = "auto"
    tr_to = "zh"
    # 加密字符串拼接
    splicing_sign = app_id + q + salt + secret_key
    sign = get_md5(splicing_sign)
    print(f"sign:{sign}")
    # 构造参数
    data = {"q": q, "from": tr_from, "to": tr_to, "appid": app_id, "salt": salt, "sign": sign}
    # 构造get请求
    res = requests.get(url, params=data)
    # 响应结果JSON格式化:res.json()等同于json.load(res.text)
    result = res.json()
    tr_res = result["trans_result"][0]["dst"]
    print(f"翻译结果:{tr_res}")


test_baidu_input()

        3、带参数的POST请求

        (1)发送带参数的POST请求requests.get("url", data=params)(等同于以字典的形式提交form表单数据)

        (2)获取和输出各种响应值

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/19 8:25
# software: PyCharm

"""get请求"""

# (1)导入requests包
import requests
import json

# (2)构造一个不带参数的get请求、带参数的get请求、带参数的post请求
post_parameter = {
    "q": "apple",
    "from": "en",
    "to": "zh",
    "appid": "xxx",
    "salt": "202002121503",
    "sign": "7105f811ca9d3835146ed9c44ab46770",
    "Content-Type": "application/x-www-form-urlencoded",
}
response2 = requests.post("https://fanyi-api.baidu.com/api/trans/vip/translate", data=post_parameter)

print(f"\n本次响应数据类型是{type(response2)}")

# (3)输出本次响应的状态码
print(f"\n本次响应状态码数据类型是{type(response2.status_code)}")
print(f"本次响应状态码是{response2.status_code}")

# (4)输出本次响应的所有文本
print(f"\n本次响应文本数据类型是{type(response2.text)}")
response2.encoding = "utf-8"
print(f"本次响应文本是{response2.text}")

# (5)输出本次响应的所有值
print(f"\n本次响应cookies数据类型是{type(response2.cookies)}")
response2.encoding = "utf-8"
print(f"本次响应网站的Cookies是{response2.cookies}")

# (6)判断:本次请求后,服务器响应返回的字符串中,是否有“百度一下,你就知道”
exp = "苹果"
if exp in response2.text:
    print(f"\n响应值中包含你希望的字符串:{exp}。")
else:
    print("\n响应值中不包含你希望的字符串。")

        4、响应结果转换为JSON格式

        response.json()等同于json.loads(response.text)

# (1)导入requests包
import requests
import json

get_parameter = {
    "q": "apple",
    "from": "en",
    "to": "zh",
    "appid": "20200211000382774",
    "salt": "202002121503",
    "sign": "7105f811ca9d3835146ed9c44ab46770",
}
response1 = requests.get("https://fanyi-api.baidu.com/api/trans/vip/translate", params=get_parameter)

print(type(response1.json()), response1.json())
print(response1.json()["error_msg"], json.loads(response1.text))

        四、Requests库综合应用

        1、融入unittest框架

        (1)unittest工作原理

        unittest:单元测试框架,作为自动化测试框架的用例组织执行框架

        核心:TestCase测试用例(每个测试方法都是test开头、setUp()初始化、tearDown销毁)、TestSuite测试套件、TestRunner测试运行器、TestLoader测试用例加载器、Fixture

        内容:编写web自动化-webdriver、编写接口自动化-requests请求、编写移动端自动化-python+appium+unittest

        (2)unittest主要结构

        创建测试类(继承unittest.TestCase类)

        编写测试用例

        定义测试套件(流程unittest.TestSuite())

        加载测试用例

        创建测试报告(HTMLTestRunner)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/20 9:41
# software: PyCharm

"""
快速搭建unittest框架:
    (1)创建测试类
"""
import unittest
import requests


class TestV2ex(unittest.TestCase):
    """定义一个测试类,继承unittest.TestCase类"""

    def setUp(self) -> None:
        """初始化方法"""
        print("初始化属性")

    def tearDown(self) -> None:
        """定义结束方法"""
        print("所有用例执行结束")

    def test_hot(self):
        """自定义测试方法"""
        # driver = webdriver.Firefox()

    def test_node(self):
        """自定义测试方法"""
        res = requests.get("http://www.baidu.com")
        return res

    def test_user(self):
        """自定义测试方法"""
        a = 1
        b = 2
        self.assertEqual(a, b)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/20 12:22
# software: PyCharm


"""
快速搭建unittest框架:
    (2)编写测试用例
    (3)定义测试套件(流程)
    (4)加载测试用例
    (5)创建测试报告:使用unittest框架内容HTMLTestRunner导出HTML格式的测试报告
"""
import unittest
from HTTPTestRunner import HTMLTestRunner

from unittest_api import TestV2ex

# 构建测试套件(流程)
testsuite = unittest.TestSuite()
# 加载测试用例
testsuite.addTest(TestV2ex("test_hot"))
testsuite.addTest(TestV2ex("test_node"))
testsuite.addTest(TestV2ex("test_user"))
# 创建测试报告
fp = open('./report.html', 'wb')  # wb:以二进制的格式写入
"""
HTMLTestRunner:
    (1)https://pypi.python.org/pypi/HTMLTestRunner
    (2)python下的Lib目录,新建一个HTMLTestRunner.py文件,把内容直接复制进去并修改
    第94行,将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第766行,将uo = o.decode(‘latin-1’)修改成uo = e
    第772行,将ue = e.decode(‘latin-1’)修改成ue = e
    第631行,将print >> sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime)修改
成print(sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime))
"""
# stream:文件信息流;title:报告的标题;description:一般写对于测试环境的描述信息(操作系统、浏览器……);tester:测试人员
runner = HTMLTestRunner(stream=fp, title='测试报告', description='执行报告')
runner.run(testsuite)
fp.close()

        2、参数化和断言

        (1)使用CSV外部文件

        参数化:

        程序中(代码本身:random、list、range)

        外部数据文件(CSV文件、text文件)

        (2)断言

        自带断言方法

assertEqual(a, b)            a==b

assertNotEqual(a, b)         a!=b

assertTrue(x)                bool(x) is True

assertFalse(x)               booI(x) is False

assertIs(a, b)               a is b

assertIsNot(a, b)            a is not b

assertIsNone(x)              x is None

assertIsNotNone(x)           x is not None

assertIn(a, b)               a in b

assertNotIn(a, b)            a not in b

assertIsInstance(a, b)       isinstance(a,b)

assertNotIsInstance(a, b)    not isinstance(a,b)

        自写判断进行结果输出

if-else

try-except-finally异常捕获

        3、输出测试报告和测试日志

        (1)测试报告

        框架内容-HTMLTestRunner(python2,修改内容可在python3中使用)

        导出HTML格式的测试报告

        runner = HTMLTestRunner(stream=fp, title='测试报告', description='执行报告')

# 创建测试报告
fp = open('./report.html', 'wb')  # wb:以二进制的格式写入
"""
HTMLTestRunner:
    (1)https://pypi.python.org/pypi/HTMLTestRunner
    (2)python下的Lib目录,新建一个HTMLTestRunner.py文件,把内容直接复制进去并修改
    第94行,将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第766行,将uo = o.decode(‘latin-1’)修改成uo = e
    第772行,将ue = e.decode(‘latin-1’)修改成ue = e
    第631行,将print >> sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime)修改
成print(sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime))
"""
# stream:文件信息流;title:报告的标题;description:一般写对于测试环境的描述信息(操作系统、浏览器……);tester:测试人员
runner = HTMLTestRunner(stream=fp, title='测试报告', description='执行报告')
runner.run(testsuite)
fp.close()

         (2)日志

        APP---adb

adb logcat                                                              #打印默认日志数据

adb logcat -v time *:e --pid=<pid> >D:\log.txt      #打印详细时间(-v time)、级别是Error(*:e)和给定pid中(--pid=<pid>)的日志数据并保存到电脑固定位置

        

        Linux---查看系统运行日志

        

        生成日志(标准化格式:程序员按企业设计输出系统运行信息)

        

        用途:系统运行异常时查看异常信息(用户名、时间和日期、操作事件、操作对象、操作内容、信息级别显示(info/warning/error/exception)) 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/8/20 12:21
# software: PyCharm

"""测试日志输出"""

import time

info_type = 3


def log():
    """以标准格式输出一些脚本运行过程中的重要信息"""
    fp = open('./log.txt', 'a+')
    # 运行时间记录:年月日时分秒
    e_t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print(e_t)
    # 获取当前运行的文件名和函数名
    f_n = log.__name__
    print(f_n)
    # 模拟信息类型的判断
    # msg_type = "info"
    if info_type == 0:
        msg_type = "info"
    elif info_type == 1:
        msg_type = "warning"
    elif info_type == 2:
        msg_type = "error"
    else:
        msg_type = "exception"
    # 组织一条写入log.txt的信息
    info = f"[{e_t}][{msg_type}]:{f_n}\n"
    # 将info写入log
    fp.write(info)
    fp.close()


log()

 log.txt日志文件

        [2022-08-20 12:47:10][info]:log
        [2022-08-20 12:47:14][warning]:log
        [2022-08-20 12:47:17][error]:log
        [2022-08-20 12:47:20][exception]:log
        [2022-09-07 16:37:17][exception]:log
        [2022-09-07 16:37:54][exception]:log

        五、测试代码和运行结果

        1、测试代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/27 18:15
# software: PyCharm

"""
    1、使用unittest框架
    2、定义请求方法
    3、在方法中完成请求
    4、对返回值进行JSON格式化
    5、对格式化后的数据进行类型(字典、列表)判断
    6、对接口数据进行断言
    7、将日志信息进行组合写入日志文件
"""
import time
import unittest

import requests


class TestV2ex(unittest.TestCase):
    """对v2ex网站进行测试"""

    def setUp(self) -> None:
        """初始化测试环境"""

    def test_hot(self):
        """对热点话题接口进行测试"""
        # 定义函数开始时间
        start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        # URL地址
        url = "https://www.v2ex.com/api/topics/hot.json"
        # 发送请求
        res = requests.get(url)
        # JSON格式化响应结果
        result = res.json()
        # 定义表示返回值中数据元素个数的变量
        res_num = 0
        # 判断数据类型,确定元素个数
        res_type = type(result)
        if isinstance(result, dict):
            res_num = 1
        elif isinstance(result, list):
            res_num = len(result)
        else:
            print("无该数据类型")
        # 预期结果
        except_num = 10
        # 断言
        try:
            self.assertEqual(except_num, res_num, "个数不一样!!!")
        except AssertionError as ae:
            print(ae)
        finally:
            # 定义函数结束时间
            end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            # 组合日志信息
            log_info = f"start_time:{start_time}|res_type:{res_type}|res_num:{res_num}|end_time:{end_time}"
            # 输出测试日志
            with open("./log/log.txt", "a+", encoding="utf-8") as f:
                f.write(log_info)
                f.write("\n")

    def tearDown(self) -> None:
        """重置测试环境"""


if __name__ == '__main__':
    unittest.main()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/27 18:15
# software: PyCharm

"""
快速搭建unittest框架:
    (2)编写测试用例
    (3)定义测试套件(流程)
    (4)加载测试用例
    (5)创建测试报告:使用unittest框架内容HTMLTestRunner导出HTML格式的测试报告

    HTMLTestRunner:
    (1)https://pypi.python.org/pypi/HTMLTestRunner
    (2)python下的Lib目录,新建一个HTMLTestRunner.py文件,把内容直接复制进去并修改
    第94行,将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第766行,将uo = o.decode(‘latin-1’)修改成uo = e
    第772行,将ue = e.decode(‘latin-1’)修改成ue = e
    第631行,将print >> sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime)修改
成print(sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime))
"""
import time
import unittest
from HTTPTestRunner import HTMLTestRunner

from test_case import TestV2ex

# 构建测试套件(流程)
test_suite = unittest.TestSuite()
# 加载测试用例
test_suite.addTest(TestV2ex("test_hot"))
# 创建测试报告
f_t = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
filename = f"./result/{f_t}.html"
with open(filename, "wb") as f:
    """wb:以二进制的格式写入"""
    # stream:文件信息流;title:报告的标题;description:一般写对于测试环境的描述信息(操作系统、浏览器……);tester:测试人员
    runner = HTMLTestRunner(stream=f, title='测试报告', description='执行报告')
    runner.run(test_suite)

        2、运行结果

 


        愿你我都能为中华民族的伟大复兴尽一份绵薄力量,让中华文化的根扎根在中国这片绿水青山之上,让新一代中华儿女传承与发扬!!!

---无名之辈


以上内容均是本人自学,当然是有网上公布的内容,如有冒犯,请留言,立即改正,谢谢!


        看完要是觉得对自己有用,动一下您那根金色的会一指禅的右手食指,按一下您的鼠标左键,在对应的那个位置点个赞,亦或者在评论区留下您的绝顶好句,亦或者收藏在您的收藏夹里,再走也不迟嘛!您说要不要得!谢谢您的阅读和赞赏!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值