美文网首页
接口测试

接口测试

作者: qianyewhy | 来源:发表于2017-09-14 14:56 被阅读111次

1、使用脚本测试接口与使用接口工具的对比

  • 测试数据不可控
    使用工具测试接口,必须手动向数据库添加数据,而脚本可以直接写入数据库
  • 无法测试加密接口1、使用脚本测试接口与使用接口工具的对比
  • 测试数据不可控
    使用工具测试接口,必须手动向数据库添加数据,而脚本可以直接写入数据库
  • 无法测试加密接口
    -可扩展功能不足
    不能生产HTML格式的测试报告,不能将报告自动发送到指定邮箱,不能定时任务,不能持续集成
    2、一般的接口测试工具测试过程
  • 接口工具调用被测系统的接口,并传参
  • 系统根据传参向数据库进行查询数据
  • 将查询结果组装成一定格式的数据返回给被调用者
  • 人工或者通过工具的断言功能检查接口测试的正确性
    3、接口自动化测试过程
  • 接口测试项目向测试数据库中插入测试数据(张三的个人信息)
  • 调用系统接口(传参)
  • 系统接口根据传参查询数据库,得到张三的个人信息
  • 将查询结果组装成一定格式的数据返回给被调用者
  • 通过单元测试框架断言查询结果并生产测试报告
    为了避免正式数据库被污染,建议使用测试数据库
    4、使用requests进行请求
    Requests 支持HTTP 连接保持和连接池,支持使用cookie 保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的URL 和POST 数据自动编码。现代、国际化、人性化。
    5、接口自动化测试框架


    image.png

    pyrequests 框架:
    db_fixture/: 初始化接口测试数据。
    interface/: 用于编写接口自动化测试用例。
    report/: 生成接口自动化测试报告。
    db_config.ini : 数据库配置文件。
    HTMLTestRunner.py unittest 单元测试框架扩展,生成HTML 格式的测试报告。
    run_tests.py : 执行所有接口测试用例。
    6、接口自动化整体思路
    1)配置数据库
    2)创建测试数据
    3)编写接口测试用例
    7、数据库配置

  • 在被测系统中新建一个测试数据库,并且将系统的数据库指向被测数据库
    ![Upload image.png failed. Please try again.]
  • 修改了数据库配置之后需要重新执行“python3 manage.py migrate”生成数据库表结构
  • 创建数据库配置文件db_config.ini
 Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
# 原来的数据库配置
DATABASES = {
    'default': {
        # 驱动
        'ENGINE': 'django.db.backends.mysql',
        # 主机地址
        'HOST': '127.0.0.1',
        # 端口
        'PORT': '3306',
        # 数据库名称
        'NAME': 'guest',
        # 用户名
        'USER': 'root',
        # 密码
        'PASSWORD': 'root',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
    }
}
  • 简单封装数据库操作,数据库表数据的插入和清除,.../db_fixture/mysql_db.py
    该步骤是为了初始化测试数据库做准备
# coding=utf-8
import pymysql.cursors
import os
import configparser as cparser


# ======== Reading db_config.ini setting ===========
base_dir = str(os.path.dirname(os.path.dirname(__file__)))
base_dir = base_dir.replace('\\', '/')
file_path = base_dir + "/db_config.ini"

cf = cparser.ConfigParser()

cf.read(file_path,encoding='utf8')
host = cf.get("mysqlconf", "host")
port = cf.get("mysqlconf", "port")
db   = cf.get("mysqlconf", "db_name")
user = cf.get("mysqlconf", "user")
password = cf.get("mysqlconf", "password")


# ======== MySql base operating ===================
class DB:

    def __init__(self):
        try:
            # Connect to the database
            self.connection = pymysql.connect(host=host,
                                              port=int(port),
                                              user=user,
                                              password=password,
                                              db=db,
                                              charset='utf8mb4',
                                              cursorclass=pymysql.cursors.DictCursor)
        except pymysql.err.OperationalError as e:
            print("Mysql Error %d: %s" % (e.args[0], e.args[1]))

    # clear table data
    def clear(self, table_name):
        # real_sql = "truncate table " + table_name + ";"
        real_sql = "delete from " + table_name + ";"
        with self.connection.cursor() as cursor:
            cursor.execute("SET FOREIGN_KEY_CHECKS=0;")
            cursor.execute(real_sql)
        self.connection.commit()

    # insert sql statement
    def insert(self, table_name, table_data):
        for key in table_data:
            table_data[key] = "'"+str(table_data[key])+"'"
        key   = ','.join(table_data.keys())
        value = ','.join(table_data.values())
        real_sql = "INSERT INTO " + table_name + " (" + key + ") VALUES (" + value + ")"
        #print(real_sql)

        with self.connection.cursor() as cursor:
            cursor.execute(real_sql)

        self.connection.commit()

    # close database
    def close(self):
        self.connection.close()

    # init data
    def init_data(self, datas):
        for table, data in datas.items():
            self.clear(table)
            for d in data:
                self.insert(table, d)
        self.close()

"""
if __name__ == '__main__':

    db = DB()
    table_name = "sign_event"
    data = {'id':1,'name':'红米','`limit`':2000,'status':1,'address':'北京会展中心','start_time':'2016-08-20 00:25:42'}
    table_name2 = "sign_guest"
    data2 = {'realname':'alen','phone':12312341234,'email':'alen@mail.com','sign':0,'event_id':1}

    db.clear(table_name)
    db.insert(table_name, data)
    db.close()
"""

首先要读取数据库配置,获取数据库信息,如主机地址,用户名,密码,端口等
其次通过pymysql库中的connect方法连接数据库
然后封装clear方法和insert方法
8、创建测试数据

import sys

sys.path.append('D:\\pydj\\guest\\pyrequest\\db_fixture')
try:
    from mysql_db import DB
except ImportError:
    from .mysql_db import DB

# create data
datas = {
    'sign_event': [
        {'id': 1, 'name': '红米Pro发布会', '`limit`': 2000, 'status': 1, 'address': '北京会展中心',
         'start_time': '2017-08-20 14:00:00'},
        {'id': 2, 'name': '可参加人数为0', '`limit`': 0, 'status': 1, 'address': '北京会展中心',
         'start_time': '2017-08-20 14:00:00'},
        {'id': 3, 'name': '当前状态为0关闭', '`limit`': 2000, 'status': 0, 'address': '北京会展中心',
         'start_time': '2017-08-20 14:00:00'},
        {'id': 4, 'name': '发布会已结束', '`limit`': 2000, 'status': 1, 'address': '北京会展中心',
         'start_time': '2001-08-20 14:00:00'},
        {'id': 5, 'name': '小米5发布会', '`limit`': 2000, 'status': 1, 'address': '北京国家会议中心',
         'start_time': '2017-08-20 14:00:00'},
    ],
    'sign_guest': [
        {'id': 1, 'realname': 'alen', 'phone': 13511001100, 'email': 'alen@mail.com', 'sign': 0, 'event_id': 1},
        {'id': 2, 'realname': 'has sign', 'phone': 13511001101, 'email': 'sign@mail.com', 'sign': 1, 'event_id': 1},
        {'id': 3, 'realname': 'tom', 'phone': 13511001102, 'email': 'tom@mail.com', 'sign': 0, 'event_id': 5},
    ],
}


# Inster table datas
def init_data():
    """
    db = DB()
    for table, data in datas.items():
        db.clear(table)
        for d in data:
            db.insert(table, d)
    db.close()
    """
    DB().init_data(datas)


if __name__ == '__main__':
    init_data()

1)创建一个字典datas,键表示表名,值表示表里的数据
2)init_data()函数用于读取datas 字典中的数据,调用DB 类中的clear()方法清除数据库,然后,调用insert()方法插入表数据。
3)之后的测试用例就已经这些数据进行编写
9、编写测试用例


image.png
import unittest
import requests
import os, sys

parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)
from pyrequest.db_fixture import test_data


class AddEventTest(unittest.TestCase):
    """添加发布会"""

    def setUp(self):
        self.base_url = "http://127.0.0.1:8000/api/add_event/"

    def tearDown(self):
        print(self.result)

    def test_add_event_all_null(self):
        """ 所有参数为空 """
        payload = {'eid': '', '': '', 'limit': '', 'address': "", 'start_time': ''}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result['status'], 10021)
        self.assertEqual(self.result['message'], 'parameter error')

    def test_add_event_eid_exist(self):
        """ id已经存在 """
        payload = {'eid': 1, 'name': '一加4发布会', 'limit': 2000, 'address': "深圳宝体", 'start_time': '2017'}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result['status'], 10022)
        self.assertEqual(self.result['message'], 'event id already exists')

    def test_add_event_name_exist(self):
        """ 名称已经存在 """
        payload = {'eid': 16, 'name': '红米Pro发布会', 'limit': 2000, 'address': "深圳宝体", 'start_time': '2017'}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result['status'], 10023)
        self.assertEqual(self.result['message'], 'event name already exists')

    def test_add_event_data_type_error(self):
        """ 日期格式错误 """
        payload = {'eid': 14, 'name': '一加5手机发布会', 'limit': 2000, 'address': "深圳宝体", 'start_time': '2017'}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result['status'], 10024)
        self.assertIn('start_time format error.', self.result['message'])

    def test_add_event_success(self):
        """ 添加成功 """
        payload = {'eid': 17, 'name': '一加7手机发布会', 'limit': 2000, 'address': "深圳宝体", 'start_time': '2017-05-10 12:00:00'}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result['status'], 200)
        self.assertEqual(self.result['message'], 'add event success')


if __name__ == '__main__':
    test_data.init_data()  # 初始化接口测试数据
    unittest.main()

10、集合测试用例并执行

from pyrequest.HTMLTestRunner import HTMLTestRunner
import unittest
from pyrequest.db_fixture import test_data
import time
import sys

sys.path.append('./interface')
sys.path.append('./db_fixture')

# 指定测试用例为当前文件夹下的 interface 目录
test_dir = 'D:\pydj\guest\pyrequest\interface'
print(test_dir)
discover = unittest.defaultTestLoader.discover(test_dir, pattern='*_test.py')

if __name__ == "__main__":
    # 初始化接口测试数据
    test_data.init_data()

    now = time.strftime("%Y-%m-%d %H_%M_%S")
    filename = 'D:/pydj/guest/pyrequest/report/' + now + '_result.html'
    fp = open(filename, 'wb')
    runner = HTMLTestRunner(stream=fp,
                            title='Guest Manage System Interface Test Report',
                            description='Implementation Example with: ')
    runner.run(discover)
    fp.close()

相关文章

  • 接口测试概述

    接口(interface)的概念 常见接口名词 接口测试: 接口测试目的: 接口测试的重要性: 接口测试流程 接口...

  • 接口、安全、性能测试

    接口测试 1.定义:接口测试时测试系统组件间接口的一种测试 包括:模块接口测试、后端服务器接口测试、外部接口测试。...

  • 接口测试 - 测试流程

    接口测试流程逐步分为: 接口需求调研 -> 接口测试工具选择 -> 接口测试计划 -> 接口测试的用例编写...

  • 接口测试初解

    1.什么是接口 2.什么是接口测试: 接口测试主要包含三方面:接口功能测试、接口安全测试、接口性能测试 3.接口测...

  • 2018-05-16

    1.接口测试基础 1.1.什么是接口测试? 接口测试是测试系统组件间接口的一种测试。 接口测试主要用于检测外部...

  • 接口测试

    1.在线http测试:接口在线测试 模块接口测试和web接口测试: 模块接口测试是单元测试的基础。它主要测试模块的...

  • 接口测试

    软件测试分类:界面测试,接口测试,单元测试对软件提供的接口进行测试接口测试: 地址,参数,返回值(期望结果)接口-...

  • 接口功能测试要点

    单接口测试: 组合接口测试(场景测试)

  • 接口自动化测试设计

    一、接口测试基础 1.什么是接口测试? 接口测试是测试系统组件间接口的一种测试。 接口测试主要用于检测外部系统与系...

  • 软件测试-接口测试详解

    一、接口测试的背景 1)什么是接口测试呢? 接口测试是测试系统组件间接口的一种测试,接口测试主要用于检测外部系统与...

网友评论

      本文标题:接口测试

      本文链接:https://www.haomeiwen.com/subject/iorlsxtx.html