python+Requests+UnitTest结合做接口自动化

一.GET请求

第一步:导包

import json
import requests

第二步:发送请求

第一种方式:使用url传递参数

变量名=requests.get("请求的url")

第二种方式:通过params传递参数:

(1)字符串

变量1="url"
变量2="参数名=参数值"
变量3="参数名=参数值"
...
变量4=requests.get(变量1=url,params="keyword=变量2&变量3...")

(2)字典:

变量1="http://www.litemall360.com:8080/wx/goods/list"
变量2={
    "keyword":"床",
    "page":1,
    "limit":10,
    "categoryId":0
}
变量3=requests.get(变量1=url,params="变量2")

第三步:查看响应

print(变量名.text)//以文本方式查看
print(r.json())//以json格式查看

查看响应数据编码格式:

print(变量名.encoding)

设置响应数据编码格式:

变量名.encodings="utf-8"

二.post请求:

提交json数据:

第一步:导包

import json
import requests

第二步:发送请求

变量1=”url“

url="http://www.litemall360.com:8080/wx/auth/register"

变量2=”参数值”

date={
    "code":"666666",
    "username":"xiaoxiaoer",
    "password":"123456",
    "repeatPassword":"123456",
    "mobile":"13106120403"
}
变量名3=requests.post(url=变量1,json=(变量2))

第三步:查看响应

print(变量3.json())

说明:

  • data: 参数接收form表单数据,后台会⾃动附加form表单请求信息头(data数据格式为字典)

  • json:参数接收json数据,后台会⾃动附加json表单请求信息头(headers = {"Content-Type":"application/json"})

提交表单数据:

第一步:导包

import requests
import json

第二步:发送请求

变量1=”url“

变量1 = "http://localhost/index.php?m=Home&c=User&a=do_login"

变量2=”参数值“

变量2 = { 
    "username": "13488888888", 
    "password": "123456", 
    "verify_code": "8888" }
变量名3 = requests.post(url="变量1", data="变量2")

第三步:查看响应

print(变量3.json())

三.其他请求方式(了解):

  • put:修改资源

  • delete:删除资源

  • head:响应数据中只包含请求头,前提是项目中已实现该功能

  • options:查看接口支持的请求方法,前提是项目中已实现该功能

响应内容解析:

用途:断言

实现:

  • response.status_code :响应状态码

  • response.url :url地址信息

  • response.encoding :查看响应数据编码格式

  • response.headers :查看头部信息

  • response.cookies : 查看cookies信息

  • response.text :文本形式查看响应数据

  • response.content :字节码形式查看响应数据

  • response.json() :json形式查看响应数据

# 案例:访问百度首页的接口`http://www.baidu.com`,获取以下响应数据
import requests
import json
r=requests.get("https://www.baidu.com")
r.encoding="utf-8"
# 获取响应状态码
print("响应状态码为:",r.status_code)
# 获取请求URL
print("请求URL为:",r.request.url)
# 获取响应字符编码
print("编码格式为:",r.encoding)
# 获取响应头数据
print("响应头数据为:",r.headers)
print("Content-Type:",r.headers.get("Content-Type"))
# 获取响应的cookie数据
print("响应的cookie数据为:",r.cookies)
print("提取指定的cookies为:",r.cookies.get("BDORZ"))
# 获取文本形式的响应内容
print("文本形式响应内容:",r.text)
# 获取字节形式的响应内容
print("字节形式响应内容:",r.content)
print("字节形式响应内容:",r.content.decode("utf-8"))

四.设置请求头:

变量名={
    "Content-Type":"application/json;charset=utf-8"
}
import requests
import json
#URL
url1="http://www.litemall360.com:8080/wx/auth/login"
#请求头
headers1={
    "Content-Type":"application/json;charset=utf-8"
}
#请求体
json1={
    "username":"user123",
    "password":"user123"
}
r=requests.post(url=url1,headers=headers1,json=json1)
print(r.json())

五.设置cookie:(了解) 

例子:获取cookies传入其他依赖url里面
import requests
# 获取验证码
r = requests.get("http://localhost/index.php?m=Home&c=User&a=verify")
print(r.cookies)
#获取PHPSESSID的cookies
cookies1 = r.cookies.get("PHPSESSID")
print(cookies1)

# 登录
url = "http://localhost/index.php?m=Home&c=User&a=do_login"
data = {
  "username": "13488888888",
  "password": "123456",
  "verify_code": "8888"
}
#设置请求头cookies的值为验证码的cookies1
cookies = {
"PHPSESSID": cookies1
}
w = requests.post(url=url, data=data, cookies=cookies1)
print(w.json())

# 我的订单:http://localhost/Home/Order/order_list.html
#把cookies1传入我的订单里面
e = requests.get("http://localhost/Home/Order/order_list.html",cookies=cookies1)
print(e.text)

设置session(掌握):

作用:在多个请求之间存储数据并自动添加数据,如cookies

使用:

  • 实例化: session = requests.Session()

  • 发送请求:

request.get() 变成session.get()

request.post() 变成session.postt()

...

import requests
import json

#实例化session,创建session对象
session = requests.Session()

# 获取验证码
r = session.get("http://localhost/index.php?m=Home&c=User&a=verify")

# 登录
url = "http://localhost/index.php?m=Home&c=User&a=do_login"
data = {
    "username": "13488888888",
    "password": "123456",
    "verify_code": "8888"
}
w = session.post(url=url, data=data)
print(w.json())

# 我的订单:http://localhost/Home/Order/order_list.html
#把cookies1传入我的订单里面
e = session.get("http://localhost/Home/Order/order_list.html")
print(e.text)

六.获取Tokken: 

获取方法:

变量1 = requests.post(url=url, json=json)
从变量1json的结果里面获取data下的token里面的token值并存在变量2里面
变量2=(变量1.json()["data"]["token"])
import requests
import json

# 登录
url = "http://www.litemall360.com:8080/wx/auth/login"
json = {
   "username": "user123",
   "password": "user123"
}
r = requests.post(url=url, json=json)
print(r.json())
#从json的结果里面获取data下的token里面的token值并存在w变量
w=(r.json()["data"]["token"])
print("token为:",w)

#添加购物车
url1="http://www.litemall360.com:8080/wx/cart/add"
#设置请求头X-Litemall-Token=w值
headers={
    "X-Litemall-Token":w
}
json1={
"goodsId":1181000,
"number":1,
"productId":2
}
r1=requests.post(url=url1,json=json1,headers=headers)
print(r1.json())

七.集成UnitTest:

UnitTest优势:

  • 管理测试用例

  • 提供了丰富的断言

  • 生成测试报告

作用:用来管理用例,加载用例,执行用例

原理:有几个核心组件

1、测试固件 setUp() 每条用例执行之前,首先会执行这个setUp()方法,在setUp()方法中完成准备初始化工作 比如:连接数据库,后期在将Web UI功能自动化的时候,可以在这里去打开浏览器,配置 tearDown() 每条用例执行完成之后,回收一些资源,比如:关闭数据库,关闭浏览器

2、测试用例 每一条用例需要实现一个用例方法,每个用例方法都必须要以test开头

3、测试套件 执行用例的时候,需要创建测试套件,把用例加入测试套件。

4、加载器 用来加载用例的,把测试用例加入测试套件中

5、执行器 用来执行测试套件中的用例的 如何使用unittest框架来编写用例

unittest.TestCase:TestCase类,所有测试用例类继承的基本类

class 类名(unittest.TestCase):

使用unittest框架编写测试用例思路:

1.导入模块包

import unittest

2.定义测试类,继承父类为unittest.TestCase

#可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。
#可继承unittest.TestCase的各种断言方法。
class Test(unittest.TestCase): 

3.定义setUp()方法用于测试用例执行前的初始化工作(前置处理)

#注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”
#注意,输入的值为字符型的需要转为int型
    def setUp(self):
        self.number=raw_input('Enter a number:')
        self.number=int(self.number)

 4.定义测试用例,以“test_”开头命名的方法

#注意,方法的入参为self
#可使用unittest.TestCase类下面的各种断言方法用于对测试结果的判断
#可定义多个测试用例
#最重要的就是该部分
    def test_case1(self):
        print self.number
        self.assertEqual(self.number,10,msg='Your input is not 10')
        
    def test_case2(self):
        print self.number
        self.assertEqual(self.number,20,msg='Your input is not 20')

    @unittest.skip('暂时跳过用例3的测试')
    def test_case3(self):
        print self.number
        self.assertEqual(self.number,30,msg='Your input is not 30')

5.定义tearDown()方法用于测试用例执行之后的善后工作(后置处理)

#注意,方法的入参为self
    def tearDown(self):
        print 'Test over'

6.如果直接运行该文件(name值为main),则执行以下语句,常用于测试脚本是否能够正常运行

if __name__=='__main__':

(1)执行测试用例方案一如下:

#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
    unittest.main()

(2)执行测试用例方案二如下:

#6.2.1先构造测试集
#6.2.1.1实例化测试套件
    suite=unittest.TestSuite()
#6.2.1.2将测试用例加载到测试套件中。
#执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
    suite.addTest(Test('test_case2'))
    suite.addTest(Test('test_case1'))
#6.2.2执行测试用例
#6.2.2.1实例化TextTestRunner类
    runner=unittest.TextTestRunner()
#6.2.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
    runner.run(suite)
'''
    
'''
#6.3执行测试用例方案三如下:
#6.3.1构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
    test_dir = './'
    discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#6.3.2执行测试用例
#6.3.2.1实例化TextTestRunner类
    runner=unittest.TextTestRunner()
#6.3.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
    runner.run(discover)   
'''

八.生成测试报告: 

1.先导包

import time
import unittest
from 登录实现unittest import test
from HtmlTestRunner import HTMLTestRunner

2.封装测试套件

#实例化TestSuite()对象
suite=unittest.TestSuite()
#添加测试用例或者类进来
suite.addTest(unittest.makeSuite(test))

3.指定报告路径

通过时间模块把日期传入文件名上(年月日-时分秒)
report="./report-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))

4.打开文件流

#以二进制写入的方式打开
with open(report,"wb") as f:as f代表创建一个别名
    #创建HTMLRUNNER运行器
    runner=HTMLTestRunner(f,title="接口测试报告")
    #执行测试套件
    runner.run(suite)

九.参数化:

基本步骤:

参数化:
1.分析:哪些内容需要参数化
数据数据:用户名,密码,验证码
预期结果:content_type
        状态码,业务码,业务消息
2.选择数据承载形式:
    json
    db
3.修改测试用例的代码
    3.1构建参数化数据(build_date)
    3.2在测试用例前引用参数化(@paramete)
    3.3在具体的测试用例中按照获得的数据进行参数替换

基于json文件实现参数化:

第一步:导包

#导入引用参数化的包
from parameterized import parameterized

第二步: 构造测试数据

#参数化
#定义构造数据方法
def build_data():
    #指定文件路径
    file="../data/login.json"
    #定义测试数据空列表
    test_data=[]
    #通过文件流的形式打开读取文件并取名为f
    with open(file,encoding="utf-8") as f:
        #加载f文件数据并用json_data接收
        json_data=json.load(f)
        #使用for循环遍历json_data文件把文件的数据一行一行的赋值,
        for case_data in json_data:
            #变量名等于你获取的第一条测试用例里面case_data通过他的get指明他的key
            #实际上他的key就是文件里面定义的变量名
            #基于文件里面的参数名来提取他的值并存下来
            username = case_data.get("username")
            password = case_data.get("password")
            verify_code = case_data.get("verify_code")
            content_type = case_data.get("content_type")
            status_code = case_data.get("status_code")
            status= case_data.get("status")
            mag = case_data.get("mag")
            #传递数据追加到空列表里面去
            test_data.append((username,password,verify_code,content_type,status_code,status,mag))
            #打印一下组装出来的数据
            #print(test_data)
        #返回数据
        return test_data

 第三步:在测试类里面的测试方法上引用参数化

 # 通过parameterized.expand通过传入build_data()来获得相关的数据
    # 引用参数化
    @parameterized.expand(build_data())

基于数据库实现参数化:

第一步:导包

#导入db工具类
from tpshop.tools.dbutil import DBUtil
#导入引用参数化的包
from parameterized import parameterized

第二步:创建数据库的工具类连接执行数据库操作

# 导包
import pymysql

# 创建工具类
class DBUtil():
    # 初始化
    __conn = None
    __cursor = None

    # 创建连接
    @classmethod
    def __get_conn(cls):
        if cls.__conn is None:
            cls.__conn = pymysql.connect(host="localhost",
                                         port=3306,
                                         user="root",
                                         password="123123123",
                                         database="books")
        return cls.__conn

    # 获取游标
    @classmethod
    def __get_cursor(cls):
        if cls.__cursor is None:
            cls.__cursor = cls.__get_conn().cursor()
        return cls.__cursor

    # 执行sql
    @classmethod
    def exe_sql(cls, sql):
        try:
            # 获取游标对象
            cursor = cls.__get_cursor()
            # 调用游标对象的execute方法,执行sql
            cursor.execute(sql)
            #  如果是查询
            if sql.split()[0].lower() == "select":
                # 返回所有数据
                return cursor.fetchall()
            #  否则:
            else:
                # 提交事务
                cls.__conn.commit()
                # 返回受影响的行数
                return cursor.rowcount
        except Exception as e:
            # 事务回滚
            cls.__conn.rollback()
            # 打印异常信息
            print(e)
        finally:
            # 关闭游标
            cls.__close_cursor()
            # 关闭连接
            cls.__close_conn()

    # 关闭游标
    @classmethod
    def __close_cursor(cls):
        if cls.__cursor:
            cls.__cursor.close()
            cls.__cursor = None

    # 关闭连接
    @classmethod
    def __close_conn(cls):
        if cls.__conn:
            cls.__conn.close()
            cls.__conn = None

第三步:构造测试数据

#DB参数化
#定义构造数据方法
def build_data():
    #通过数据库去获取数据作为参数化的列表
    sql="select * from t_login"
    #执行dbutil.exe_sql方法把sql传入进去并把查询结果返回放在变量db_data里
    db_data=DBUtil.exe_sql(sql)
    #定义测试数据空列表
    test_data=[]
    #使用for循环遍历db_data的数据并一行一行的赋值,
    for case_data in db_data:
        #按照下标来提取数据并赋值给变量
        username = case_data[2]
        password = case_data[3]
        verify_code = case_data[4]
        status_code = case_data[5]
        content_type = case_data[6]
        status= case_data[7]
        mag = case_data[8]
        #传递数据追加到空列表里面去
        test_data.append((username,password,verify_code,content_type,status_code,status,mag))
        #打印一下组装出来的数据
        #print(db_data)
    #返回数据
    return test_data

第四步:在测试类里面的测试方法上引用参数化

# 通过parameterized.expand通过传入build_data()来获得相关的数据
# 引用参数化
@parameterized.expand(build_data())

十.集成UnitTest:

UnitTest优势:

管理测试用例,提供了丰富的断言,生成测试报告

unittest.TestCase:TestCase类,所有测试用例类继承的基本类:class 类名(unittest.TestCase):

使用unittest框架编写测试用例思路:

1.导入模块包

import unittest

2.定义测试类,继承父类为unittest.TestCase

#可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。
#可继承unittest.TestCase的各种断言方法。
class Test(unittest.TestCase):

3.定义setUp()方法用于测试用例执行前的初始化工作(前置处理)

#注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”
#注意,输入的值为字符型的需要转为int型
def setUp(self):
self.number=raw_input('Enter a number:')
self.number=int(self.number)

4.定义测试用例,以“test_”开头命名的方法

#注意,方法的入参为self
#可使用unittest.TestCase类下面的各种断言方法用于对测试结果的判断
#可定义多个测试用例
#最重要的就是该部分
def test_case1(self):
print self.number
self.assertEqual(self.number,10,msg='Your input is not 10')

def test_case2(self):
print self.number
self.assertEqual(self.number,20,msg='Your input is not 20')
​
@unittest.skip('暂时跳过用例3的测试')
def test_case3(self):
print self.number
self.assertEqual(self.number,30,msg='Your input is not 30')

5.定义tearDown()方法用于测试用例执行之后的善后工作(后置处理)

#注意,方法的入参为self
def tearDown(self):
print 'Test over'

6.如果直接运行该文件(name 值为 main ),则执行以下语句,常用于测试脚本是否能够正常运行

if __name__=='__main__':

(1)执行测试用例方案一如下:

#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
unittest.main()

(2)执行测试用例方案二如下:

#6.2.1先构造测试集
#6.2.1.1实例化测试套件
suite=unittest.TestSuite()
#6.2.1.2将测试用例加载到测试套件中。
#执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))
#6.2.2执行测试用例
#6.2.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.2.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(suite)
'''

'''
#6.3执行测试用例方案三如下:
#6.3.1构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#6.3.2执行测试用例
#6.3.2.1实例化TextTestRunner类
runner=unittest.TextTestRunner()
#6.3.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(discover) 
'''

十一.使用接口测试框架实战:

 操作步骤:

1.先进行初始步骤创建py文件,每个文件都会有不同的用途管理 

apitestFramework #项目名称
api #定义封装被测系统的接口
scripts #定义测试用例脚本
date #存放测试数据
report #存放生成的测试报告
tools #存放第三方的文件
app.py #定义项目的配置信息
utils.py #定义工具类
run_suite.py #执行测试套件的入口

python+Requests+UnitTest结合做接口自动化_第1张图片

2.封装被测系统的接口

# 封装被测试系统接口
# 定义接口类
import requests


class LoginAPI:
# 初始化
    def __init__(self):
        self.url_verify = "http://192.168.0.222:5252/index.php?m=Home&c=User&a=verify"
        self.url_login = "http://192.168.0.222:5252/index.php?m=Home&c=User&a=do_login"
# 获取验证码接口
    def get_verify_code(self, session):
        return session.get(self.url_verify)
# 登录接口
    def login(self, session, username, password, verify_code):
        login_data = {
            "username": username,
            "password": password,
            "verify_code": verify_code
                    }
        return session.post(url=self.url_login, data=login_data)

2.定义测试用例脚本

2.1使用传参的方式定义测试用例脚本

#设计测试用例
#导包
import requests
import unittest
from tpshop.api.login import LoginAPI
# 定义测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()
    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()
    # 定义测试方法
    # 登录成功
    def test01_login_success(self):
        #调用验证码接口
        response = self.login_api.get_verify_code(self.session)
        #断言状态码是否等于200
        self.assertEqual(200, response.status_code)
        #断言Content-Type是否包含image
        self.assertIn("image", response.headers.get("Content-Type"))
        #调用登录接口
        response = self.login_api.login(self.session, "18512829605", "123456","8888")
        #打印响应结果
        print(response.json())
        #断言状态码是否等于200
        self.assertEqual(200, response.status_code)
        #断言status是否包含1
        self.assertEqual(1, response.json().get("status"))
        #断言mas是否包含登录成功
        self.assertIn("登陆成功", response.json().get("msg"))
    #账号不正确
    def test02_user_isnot_exist(self):
        #调用验证码接口
        response=self.login_api.get_verify_code(self.session)
        self.assertEqual(200, response.status_code)
        #断言Content-Type是否包含image
        self.assertIn("image", response.headers.get("Content-Type"))
        #调用登录接口
        response=self.login_api.login(self.session,18512829607,123456,8888)
        #打印响应结果
        print(response.json())
        #断言状态码是否等于200
        self.assertEqual(200, response.status_code)
        #断言status是否包含1
        self.assertEqual(-1, response.json().get("status"))
        #断言mas是否包含登录成功
        self.assertIn("账号不存在!", response.json().get("msg"))
        #密码错误
    def test03_password_exist(self):
        # 调用验证码接口
        response = self.login_api.get_verify_code(self.session)
        self.assertEqual(200, response.status_code)
        # 断言Content-Type是否包含image
        self.assertIn("image", response.headers.get("Content-Type"))
        # 调用登录接口
        response = self.login_api.login(self.session, 18512829605, 1234567, 8888)
        # 打印响应结果
        print(response.json())
        # 断言状态码是否等于200
        self.assertEqual(200, response.status_code)
        # 断言status是否包含1
        self.assertEqual(-2, response.json().get("status"))
        # 断言mas是否包含登录成功
        self.assertIn("密码错误", response.json().get("msg"))

2.2使用参数化的方式定义测试用例脚本

首先把需要参数化的数据使用json的方式存放起来

[
  {
    "desc": "case01 登录成功",
    "username": "18512829605",
    "password": "123456",
    "verify_code": "8888",
    "content_type": "image",
    "status_code": 200,
    "status": 1,
    "mag": "登陆成功"
  },
  {
    "desc": "case02 账号不存在",
    "username": "18512829606",
    "password": "123456",
    "verify_code": "8888",
    "content_type": "image",
    "status_code": 200,
    "status": -1,
    "mag": "账号不存在!"
  },
  {
    "desc": "case03 密码错误",
    "username": "18512829605",
    "password": "1234567",
    "verify_code": "8888",
    "content_type": "image",
    "status_code": 200,
    "status": -2,
    "mag": "密码错误"
  }
]

引用参数化设计测试用例脚本

#设计测试用例
#导包
import json
import requests
import unittest
from tpshop.api.login import LoginAPI
#引用参数化导包
from parameterized import parameterized
#参数化
#定义构造数据方法
def build_data():
    #指定文件路径
    file="../data/login.json"
    #定义测试数据空列表
    test_data=[]
    #通过文件流的形式打开读取文件并取名为f
    with open(file,encoding="utf-8") as f:
        #加载f文件数据并用json_data接收
        json_data=json.load(f)
        #使用for循环遍历json_data文件把文件的数据一行一行的赋值,
        for case_data in json_data:
            #变量名等于你获取的第一条测试用例里面case_data通过他的get指明他的key
            #实际上他的key就是文件里面定义的变量名
            #基于文件里面的参数名来提取他的值并存下来
            username = case_data.get("username")
            password = case_data.get("password")
            verify_code = case_data.get("verify_code")
            content_type = case_data.get("content_type")
            status_code = case_data.get("status_code")
            status= case_data.get("status")
            mag = case_data.get("mag")
            #传递数据追加到空列表里面去
            test_data.append((username,password,verify_code,content_type,status_code,status,mag))
            #打印一下组装出来的数据
            #print(test_data)
        #返回数据
        return test_data

# 创建测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()
    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()

    # 通过parameterized.expand通过传入build_data()来获得相关的数据
    # 引用参数化
    @parameterized.expand(build_data())
    # 定义测试方法创建测试用例
    #引用参数名替换输入数据和预期结果
    def test02_login(self,username,password,verify_code,content_type,status_code,status,mag):
        #调用验证码接口
        response = self.login_api.get_verify_code(self.session)
        #断言状态码是否等于200
        self.assertEqual(status_code, response.status_code)
        #断言Content-Type是否包含image
        self.assertIn(content_type, response.headers.get("Content-Type"))
        #调用登录接口
        response = self.login_api.login(self.session, username, password,verify_code)
        #打印响应结果
        print(response.json())
        #断言状态码是否等于200
        self.assertEqual(status_code, response.status_code)
        #断言status是否包含1
        self.assertEqual(status, response.json().get("status"))
        #断言mag是否包含登录成功
        self.assertIn(mag, response.json().get("msg"))

2.3使用DB参数化设计测试用例脚本

首先进行工具类的封装

# 导包
import pymysql

# 创建工具类
class DBUtil():
    # 初始化
    __conn = None
    __cursor = None

    # 创建连接
    @classmethod
    def __get_conn(cls):
        if cls.__conn is None:
            cls.__conn = pymysql.connect(host="localhost",
                                         port=3306,
                                         user="root",
                                         password="123123123",
                                         database="books")
        return cls.__conn

    # 获取游标
    @classmethod
    def __get_cursor(cls):
        if cls.__cursor is None:
            cls.__cursor = cls.__get_conn().cursor()
        return cls.__cursor

    # 执行sql
    @classmethod
    def exe_sql(cls, sql):
        try:
            # 获取游标对象
            cursor = cls.__get_cursor()
            # 调用游标对象的execute方法,执行sql
            cursor.execute(sql)
            #  如果是查询
            if sql.split()[0].lower() == "select":
                # 返回所有数据
                return cursor.fetchall()
            #  否则:
            else:
                # 提交事务
                cls.__conn.commit()
                # 返回受影响的行数
                return cursor.rowcount
        except Exception as e:
            # 事务回滚
            cls.__conn.rollback()
            # 打印异常信息
            print(e)
        finally:
            # 关闭游标
            cls.__close_cursor()
            # 关闭连接
            cls.__close_conn()

    # 关闭游标
    @classmethod
    def __close_cursor(cls):
        if cls.__cursor:
            cls.__cursor.close()
            cls.__cursor = None

    # 关闭连接
    @classmethod
    def __close_conn(cls):
        if cls.__conn:
            cls.__conn.close()
            cls.__conn = None

然后引用DB工具类进行用例设计

#设计测试用例
#导包
import json
import requests
import unittest
from tpshop.api.login import LoginAPI
#导入db工具类
from tpshop.tools.dbutil import DBUtil
#导入引用参数化的包
from parameterized import parameterized
#DB参数化
#定义构造数据方法
def build_data():
    #通过数据库去获取数据作为参数化的列表
    sql="select * from t_login"
    #执行dbutil.exe_sql方法把sql传入进去并把查询结果返回放在变量db_data里
    db_data=DBUtil.exe_sql(sql)
    #定义测试数据空列表
    test_data=[]
    #使用for循环遍历db_data的数据并一行一行的赋值,
    for case_data in db_data:
        #按照下标来提取数据并赋值给变量
        username = case_data[2]
        password = case_data[3]
        verify_code = case_data[4]
        status_code = case_data[5]
        content_type = case_data[6]
        status= case_data[7]
        mag = case_data[8]
        #传递数据追加到空列表里面去
        test_data.append((username,password,verify_code,content_type,status_code,status,mag))
        #打印一下组装出来的数据
        #print(db_data)
    #返回数据
    return test_data

# 创建测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()
    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()

    # 通过parameterized.expand通过传入build_data()来获得相关的数据
    # 引用参数化
    @parameterized.expand(build_data())
    # 定义测试方法创建测试用例
    #引用参数名替换输入数据和预期结果
    def test02_login(self,username,password,verify_code,content_type,status_code,status,mag):
        #调用验证码接口
        response = self.login_api.get_verify_code(self.session)
        #断言状态码是否等于200
        self.assertEqual(status_code, response.status_code)
        #断言Content-Type是否包含image
        self.assertIn(content_type, response.headers.get("Content-Type"))
        #调用登录接口
        response = self.login_api.login(self.session, username, password,verify_code)
        #打印响应结果
        print(response.json())
        #断言状态码是否等于200
        self.assertEqual(status_code, response.status_code)
        #断言status是否包含1
        self.assertEqual(status, response.json().get("status"))
        #断言mag是否包含登录成功
        self.assertIn(mag, response.json().get("msg"))

3.生成测试报告

首先需要导入HTMLTestRunner.py类

#生成测试报告
#练习.导包
import unittest
import time
from tpshop.scripts.test03_login_db import TestLoginAPI
from tools.HTMLTestRunner import HTMLTestRunner
#2.封装测试套件
#实例化对象
suite=unittest.TestSuite()
#调用addTest方法通过unittest.makeSuite把测试类添加进来
suite.addTest(unittest.makeSuite(TestLoginAPI))
#3.指定测试报告路径并借助format来占位并调用系统的时间模块
report="./report/-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))
#4.以文件流的形式打开文件并取名为f
with open(report,"wb") as f:
    #5.创建HtmlTestRunner运行器指明为文件f并完善报告的名字
    runner=HTMLTestRunner(f,title="tpshop测试报告")
    #6.执行测试套件,执行封装的套件
    runner.run(suite)

你可能感兴趣的:(python,python)