接口自动化(1)

目前软件测试的自动化主要是接口的自动化,如selnium等UI自动化工具仅仅在回归测试中有所应用……

接口API的自动化分为两种,一种是使用工具,另一种是使用Python代码自动化测试;

接口主流的测试自动化工具主要有:

  • Postman
  • Jemeter
  • Fiddler

其他的测试工具大多使用4要素:

  • url
  • methord
  • headers
  • body

接口文档一般是必有的,由开发经理或者架构师产出。

API自动化常用库

  • Requests—>用于Python发送接口访问的请求
  • Pytest—>驱动数据,组织测试用例
  • Logging—>日志库
  • Pymysql—>Python读取数据库

目前常用的是阿里的oceanbase库

Python代码测试是必要的,nginx反向代理后无法使用抓包工具进行抓包

库环境的应用版本选择要互不冲突。

库的安装:

#!/bin/sh
# 1升级 python3.8 和 pip3 
apt install -y python3.8
rm -rf /usr/bin/python3
ln -s /usr/bin/python3.8  /usr/bin/python3
# 2.安装课程需要的库
pip3 install requests==2.18.4
## 官方bug修复https://www.osgeo.cn/pytest/announce/release-6.0.1.html
pip3 install pytest==6.0.1
pip3 install pytest-html==3.1.1
#注意这里是对指定版本修复升级 不能下载最新版本 库之间不兼容的~!
pip3 install pytest==8.0.1
pip3 install attrs==19.1.0
pip3 install PyMySQL==1.0.2
pip3 install allure-pytest==2.9.45

Request 库

官方网站:https://pypi.org/

近期API:https://requests.readthedocs.io/en/latest/api/

库-对象名对象API功能
requests发请求
1.1get (url=&拼接参数值,headers请求头)

1.2 post请求

1.2.1 发送请求体式字符串 post(url,headers请求头,data=请求体数据)

1.2.2 发送请求体json| 字典
post(url,headers请求头,json=请求体数据)   
响应结果:
encoding=’utf-8′
2.1 状态码
status_code
2.2 响应头
结果.headers
2.3 响应体
2.3.1 字符串响应体 text
2.3.2 json响应体  
json()

上下游接口调试

#1 接口文档要素
import requests
#           运维服务器            + 接口地址
login_url="http://localhost:6088/api/User"
login_headers={'Content-Type':'application/json'}
login_method='post'
login_body={
    "username": "admin" ,
    "password": "123"}

# = 左边API表
# = 右边实际参数  来自于接口文档

shiji=requests.post(url=login_url,headers=login_headers,json=login_body)

print(shiji.status_code)
print(shiji.headers)
print(shiji.json())

# 下游代码---》一个值  环境变量~ 正则表达提取器  存    {{}}  ${}引用
shouquanma=shiji.headers['Authorization']
print(shouquanma)



# 发出下游接口

#           运维服务器            + 接口地址
user_url='http://localhost:6088/api/User?IsEnabled=true&Page=1'
url_headers={'Authorization':shouquanma}
user_method='get'


# = 左边API表
# = 右边实际参数  来自于接口文档

shiji=requests.get(url=user_url,headers=url_headers)

print(shiji.status_code)
print(shiji.headers)
print(shiji.json())

requests 库提供了API(application program interface )

上游传递授权码时可以使用get+默认值的方式:

# 下游代码---》一个值  环境变量~ 正则表达提取器  存    {{}}  ${}引用
shouquanma=shiji.headers.get('Authorization','error')

也可以使用try:

try:
    # 提取json响应体
    body=shiji.json()
except:  # try 中报错执行本分支+ 断言 失败 执行本分支~
    body="无结果~"
    print("获取结果失败有bug~")
else: # try 中不报错执行本分支   +断言成功 执行本分支 
 
    print("获取结果成功无bug~")
finally: # 不管try 是否有异常  都要运行~
    print(body)
    print("获取结果结束~")

Pytest 库

和unitest一样的单元测试框架,但是更加方便,自带报告,更方便的ddt(数据驱动)

# 导入 pytest 测试框架
import pytest
# 定义 TestOrdering 类
class Test11():
    # 定义 test_login11() 方法
    def test_login11(self):
        print(" 正在执行登录用例第一条 ")
    # 定义 test_add() 方法
    def test_login22(self):
        print(" 正在执行登录用例第二条 ")
    # 定义 test_del() 方法
    def test_login33(self):
        print(" 正在执行登录用例第三条 ")
if __name__ == '__main__':
    '''
    运行方式,直接在文件内执行以下命令
    其中, -v 参数显示命令执行过程, -s 参数显示打印的信息
    如不加 -s 参数,则 print() 函数打印的信息不会显示
    '''
    pytest.main(['-v','-s','jw1.py'])

if判断语句检测的是脚本是否是直接运行的,还是被导入的,只有直接运行时才会执行下面的测试用例执行器。

测试固件:(老版本只用setup,teardown)

# 导入 pytest 测试框架
import pytest
# 定义 TestOrdering

class Test11():
    def setup_class(self):
        print('all the test case preparation')
    def teardown_class(self):
        print('all the test case closure')
    def setup_method(self):
        print('test case preparation')
    def teardown_method(self):
        print('test case closure')
    # 定义 test_login11() 方法
    def test_login11(self):
        print(" 正在执行登录用例第一条 ")
    # 定义 test_add() 方法
    def test_login22(self):
        print(" 正在执行登录用例第二条 ")
    # 定义 test_del() 方法
    def test_login33(self):
        print(" 正在执行登录用例第三条 ")
if __name__ == '__main__':
    '''
    运行方式,直接在文件内执行以下命令
    其中, -v 参数显示命令执行过程, -s 参数显示打印的信息
    如不加 -s 参数,则 print() 函数打印的信息不会显示
    '''
    pytest.main(['-v','-s','test.py'])

写用例,调用开发代码:

import pytest

from testdev import Count

class TestAdd():
    def test_add(self):
#     # design test case-->expect result
#         a = 1
#         b = 2
#         expect = 3
#     # #invoke development code,test procedure---->actual result
#         c1 = Count(a, b)
#         result = c1.add()
#     # #result of assertion:
#         assert result == expect
# #symplify the above code to:
        assert Count(50,50).add()
if __name__ == '__main__':
    pytest.main(['-v','-s','test2.py'])

练习,调用素数检查模块功能,使用真假断言,非断言:

import pytest
from tsetdev1 import is_prime
class TestCord:
    def test_1(self):
        assert is_prime(19)
    def test_2(self):
        assert not is_prime(9)
if __name__ == '__main__':
    pytest.main(['-v', '-s', 'test3.py'])

pytest进行数据驱动:

每条用例的参数不同而过程相同时,可以进行参数化,方便ddt。

语法:

@pytest.mark.parametrize(‘参数名字’,[数据])

def test_xxx(self,参数名):(self是类的第一个固定参数,如果参数化的方法写到了类里面就必须加上self)

pass

参数的数据类型没有要求但是要一致。

列表中的数据个数决定了执行次数。

例子:

import pytest


@pytest.mark.parametrize('username', ['lucy', 'natsu', 'gray'])
class TestCode:

    def test_1(username):
        print(f'the test case is {username}')
if __name__ == '__main__':
    pytest.main(['-s','-v','test4.py'])

数据为元组:

import pytest
from testdev import Count

class Test():
    @pytest.mark.parametrize('Data',[(1,2,3),(2,3,5),(3,6,9)])
    def test_1(self,Data):
        print(f"current use case data :{Data}")
        assert Data[2]==Count.add(Data[0],Data[1])
if __name__ == '__main__':
    pytest.main(['-v','-s','test5.py'])

一条用例有多个数据的,比如有用户名密码和预期结果的时候:

1、单参数加字典实现:

import pytest
from testdev import Count

class Test():
    @pytest.mark.parametrize('Data',[(1,2,3),(2,3,5),(3,6,9)])
    def test_1(self,Data):
        print(f"current use case data :{Data}")
        assert Data[2]==Count.add(Data[0],Data[1])
if __name__ == '__main__':
    pytest.main(['-v','-s','test5.py'])

2、多参数实现:

import pytest

@pytest.mark.parametrize('username',['natsu','gray','arsa'])
@pytest.mark.parametrize('pwd',['123','456','789'])
@pytest.mark.parametrize('expect',[True,True,False])
def test_login(username,pwd,expect):
    print(f'current use case username:{username},pwd:{pwd},expect:{expect}')
if __name__ == '__main__':
    pytest.main(['-sv','test7.py'])

多参数遍历了所有的参数,如上面这个代码遍历了27条用例,实际上不能很好的确定用例的预期结果。 需要使用pymysql代码。

数据驱动主要以单驱动为主。

页: 1 2 3


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注