安享智慧理财金融测试项目

1. 项目介绍

安享智慧理财金融系统是基于 Java 语言开发,集 PC 端、APP 端、WAP 端为一体的 P2P(个人对个人)的借贷系统,提供了完整的借款和投资功能。

web用户端

  • 说明:PC 网站,供借款人和投资人使用
  • 功能模块:登录注册、借款管理、理财管理、会员中心、资金管理、账户管理、推广管理

后台管理系统

  • 说明:PC 网站,内部运营管理系统
  • 功能模块:登录、系统首页、借款管理、资金管理、认证管理、用户管理、内容管理、系统管理、统计管理、扩展管理

手机用户端

  • 说明:APP 和 WAP,供借款人和投资人使用
  • 功能模块:登录、通用、借款、认证、用户中心、债权转让、推广、托管

1.1 相关专业术语

投资

案例:张三借给李四5W,约定期满1年后连本带息1次性还款6W元。

  1. 债权人:张三是李四的债权人
  2. 借款人:李四是借款人
  3. 投资:拿钱出来做某事,赔了就没了
  4. 投标:投递方案(金融项目中,发布借款需求为招标,投资借款为投标)
    • 招标:发布需求
    • 中标:被选中
  5. 债权转让:将未完成的借款业务,转让他人。

还款

  • 等额本息:将利息均摊,先息后本。相对于等额本金总还款额要多。每月固定还款额,适合收入不稳定人群
  • 等额本金:将本金均摊,每月固定本金,整体还款先高后低。相对于等额本息总还款额少。适合收入稳定人群
  • 提前还款:提前将剩余借款还完

1.2 核心流程

image-20240304102811030

1.2.1 借款流程

注册登录

注册时验证码固定为 666666 ,不过要先点击发送验证码,再输入验证码

image-20240303131322916
开通资金托管账号
image-20240303131227923

在线生成身份证号

image-20240303133819317 image-20240303134117022 image-20240303134704239 image-20240303134757116 image-20240303134923137
额度审批通过
image-20240303135542953 image-20240303135742950 image-20240303135920284
提交借款单(信用标)
image-20240303140807760
借款单审批
image-20240303142400502 image-20240303142556119 image-20240303142752568

1.2.2 投资流程

注册登录

注册登录方式一致,一个人既可以是借款人,同时也是投资者,但是不能投自己的标

资金托管账号

选择任意标进行投标,完成风险评估后即开通了资金托管账号

image-20240303191131531
充值

账户中充值的钱用于投标

image-20240303191759647

此时在投资账户中可看到自己的余额

image-20240303191945019
投标

选择看中标进行投资

image-20240303192058992
后台满标审核

满标审核通过即可,借款标筹集到所有款项即为满标

image-20240304123616673

2. 功能测试

2.1 需求评审

  • 前置:阅读需求

    1. 正常情况下阅读所有需求(测试主管)
    2. 涉及到本项目测试人员全部参与
  • 目标

    1. 熟悉项目功能
    2. 站在不同角度对需求进行查漏补缺
    3. 各部门对需求理解一致(重要)
  • 评审人员:测试、开发、产品

2.2 测试计划

根据需求文档确定需要测试对象,范围,启动准则,结束准则等

img

2.3 编写用例

根据原型图、需求说明书、各业务流程图等资料编写业务思维导图

image-20240305110945832 image-20240305111126154

根据思维导图进一步编写测试用例,编写时遵循以下原则:

  • 前置条件:来到此测试点需要经过哪些步骤以及满足哪些条件

    如测试购物车结算功能,前置条件有:1. 用户账户已登录 2. 购物车内有商品

  • 测试步骤:具体完成测试点的操作步骤(点击哪些按钮)

    如测试购物车结算功能,测试步骤有:1. 点击“购物车” 2. 点击“结算”

  • 测试数据:所有需要使用到的数据都需要包含其中

    如测试购物车结算功能,测试数据有:1. 用户正确账户密码 2. 添加的商品为”XXX“,份数为1

  • 预期结果:即完成测试步骤后的会发生的变化,包括前端、后端

    如测试购物车结算功能,预期有:1. 购物车物件清空 2. 待付款订单加1

如下是借款和投资业务的部分测试用例

image-20240305113550422 image-20240305113627874

2.4 用例执行

按照前置条件,测试步骤以及测试数据提供的信息对程序进行手工测试,并对测试结果进行断言

  1. 缺陷管理

    测试过程中发现的缺陷尽早填入缺陷报告中,通常缺陷报告会包含如下信息

    基本内容:

    • 缺陷标题

      用简短语言描述出缺陷

    • 前置条件

      缺陷出现需要满足的条件

    • 复现步骤

      重中之重,详细记录缺陷出现的步骤,方便开发人员更好地定位修复

    • 实际结果

      记录缺陷出现时的现象,若与期望结果一致则说明此缺陷已修复

    • 期望结果

    其他信息:

    • 缺陷 ID

    • 严重程度

      • S0:主流程无法跑通,系统无法运行,崩溃或严重资源不足,应用模块无法启动或异常退出,主要功能模块无法使用

        1.内存泄露;2.系统容易崩溃;3.功能设计与需求严重不符;4.系统无法登录;5.循环报错,无法正常退出

      • S1:影响系统功能或者操作,主要功能存在严重缺陷,但不会影响到系统

        1.功能未实现;2.功能存在报错;

      • S2:界面、性能缺陷

        1.边界条件下错误;2.大数据下容易无响应;3.大数据操作时没有提供进度条

      • S3:易用性和建议性问题

        1.界面颜色搭配不好;2.文字排列不整齐;3.出现错别字,但是不影响功能;4.界面格式不规范

    • 优先级

      越严重的 BUG 越先修复

    • 缺陷类型

      1. **功能性缺陷:**指软件功能与需求规格说明书不符合或实现不完整、存在逻辑错误等问题,导致软件无法正常工作
      2. **性能缺陷:**指软件在运行时存在性能瓶颈,例如响应时间过长、处理速度慢等问题,导致软件无法满足业务需求
      3. **安全性缺陷:**指软件存在安全隐患、数据泄露等安全漏洞,导致软件易遭到攻击,存在信息泄漏等风险
      4. **可用性缺陷:**指软件在运行时存在多种问题,如界面不友好、易用性差、操作繁琐等问题,导致用户无法正常使用软件
      5. **兼容性缺陷:**指软件在不同操作系统、不同硬件平台、不同浏览器等环境下存在问题,导致软件无法正常运行或兼容性存在问题
      6. **可维护性缺陷:**指软件代码耦合度高、难以维护、难以扩展等问题,导致软件后续维护的难度和成本增加
      7. **GUI问题缺陷:**指软件图形界面设计存在问题,如布局混乱、颜色搭配不合理等问题,导致用户体验不佳
    • 缺陷状态

      • 新建 New:当一个缺陷被提交到缺陷库中时,它会被自动设置为“New”状态

      • 打开 Open:缺陷被提交后,测试负责人或开发负责人会确认它是否是一个真正的缺陷。如果是,则缺陷会被指定给某个开发人员处理,并将其状态设置为“Open”,表示开发人员正在处理这个缺陷

      • 已修复 Fixed:当开发人员认为缺陷已经被解决时,可以将缺陷的状态设置为“Fixed”

      • 重新打开 Reopen:如果经过再次测试,发现缺陷仍然存在,测试人员会将缺陷重新转给开发组,并将其状态设置为“Reopen”

      • 关闭 Closed:当测试人员经过再次测试后确认缺陷已经被解决,可以将缺陷的状态设置为“Closed”

      • 被拒绝 Rejected:如果测试负责人或开发负责人发现缺陷是产品说明书中定义的正常行为,或者经过与开发人员的讨论后认为这不能算作一个缺陷,他们会将缺陷的状态设置为“Rejected”

      • 未复现 Unreproduced:如果开发人员无法复现问题,或者认为这不是一个问题,他们可以备注原因后将缺陷的状态设置为“Unreproduced”

      • 问题重复 Duplicate:如果发现有一个重复的缺陷记录,可以将缺陷的状态设置为“Duplicate”

      • 延期修复 Postpone:如果确认了是缺陷,但在当前版本中来不及修复,并与产品经理和测试工程师协商一致后,可以将缺陷的状态设置为“Postpone”

      此外,还有其他状态,如“未验证 Unverified ”、“测试不通过 Test Failure ”等,这些状态通常用于描述缺陷的不同处理阶段或状态

    image-20240305150348993

    如何定位缺陷是前端还是后端BUG?

    关键字:抓包

    前端BUG:
    ①请求错误(方法、URL、参数、信息头类型)
    ②显示错误(响应数据正常,前端解析提取错误)

    后端BUG:无响应或响应数据不正确

    如果缺陷不能复现怎么办?

    1. 提交缺陷,挂起
    2. 跟进几个版本,找开发协助定位
    3. 上线之前评估缺陷带来的影响

2.5 测试报告

  1. 测试目标、范围

  2. 测试环境

  3. 总用例数

  4. 缺陷统计及分析

    模块发现的缺陷、缺陷严重程度分布、开发与缺陷

  5. 测试总结

    1.测试结论 2.缺陷修复程度 3.剩余缺陷 4.测试收获

3. 接口测试

3.1 需求评审

参与人员:开发、测试、产品
目的:1.熟悉项目有哪些功能 2.站在不同角度对需求进行查漏补缺 3.各角色对需求理解一致

3.1.1 测试计划与方案

核心:测什么、谁来测、怎么测
其他:提测(提交测试)标准、上线标准、风险控制

3.2 分析接口文档

  1. 测试接口依赖的数据是否都明确(请求、响应)
  2. 分析接口之间依赖关系及关联
  3. 参数规则(类型、必填、长度等)

3.2.1 设计用例准则

先对单接口进行测试,再将多个单接口整体拼接为业务场景进行测试,接口若无法对应实际业务场景,则测试无意义

优先级:P0 > P1 >P2 >P3,通常时间不充裕的情况下可以不测 P3 优先级的测试点

3.2.2 单接口测试

  • 正向测试

    1. 必填参数组合【P1】

    2. 必填 + 非必填组合

      1)全部参数组合【P1】

      2)有关联关系参数组合【P1】

      3)其他参数组合【P3】

  • 反向测试

    1. 功能异常(覆盖反向需求、覆盖响应错误码)【P2】
    2. 数据异常(空、类型不符、长度不符)【P2】
    3. 参数异常(多参、少参、无参)【P3】

3.2.3 业务场景测试【P0】

分析功能用例并寻找对应接口请求先后关系,拼接后进行整体测试

根据接口 API 文档绘制思维导图

如"注册"业务所涉及的接口,其对应思维导图如下👇

image-20240306140647508

通常来说需要为每个接口所涉及的参数进行正向与逆向讨论,逆向设计时可以先从格式的角度思考,再从业务角度思考,中往往有**“为空”**这一样例;必测项需要包含 API 文档中返回数据所涉及的范围

3.3 编写接口设计用例

仔细阅读思维导图,结合 API 文档编写接口测试用例

“注册”业务所对应接口测试用例(节选)如下👇

image-20240306144122745

3.4 搭建环境

3.4.1 Mock介绍

mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,这个虚拟的对象就是 mock 对象,mock 对象就是真实对象在调试期间的代替品

3.4.2 在何种场景使用?

在本项目中涉及三方交易的部分皆用 Mock 进行实现,其过程大致为点击按钮后直接往数据库添加相应内容,同时人为构造接口需要的数据进行返回

  1. 依赖的接口未实现
  2. 依赖的接口响应速度慢
  3. 针对接口模拟各种异常

如何实现?

  1. 使用 mock 现有工具(moco)

  2. 自定义 mock

    1)编写一个函数,直接 return 模拟值

    2)使用接口开发框架编写要模拟的接口(Flask)

Mock案例

from flask import Flask,request
# 使用当前模块的名称作为应用程序的名称,以便正确地设置应用程序的根目录
app = Flask(__name__)
# 往 127.0.0.1:5000/login 发送 get 或者 post 请求会被此函数处理
@app.route('/login',methods=['get','post'])
def login():
    # 获取请求表单中关键字为username所对应的数据
    username = request.form.get("username")
    if username =='admin':
        return {"status":200,"msg":"成功","key":{"data":"..."}}
    return {"status": 400, "msg": "失败", "key": {"data": "..."}}
# 启动
app.run()

3.4.3 构造测试数据

此项目中已将数据提前构造完毕

  • 通过系统界面构造

    优点:可视化页面操作
    缺点:操作步骤较多,不适合频繁改造数据

  • 通过接口构造

    优点:速度快
    缺点:接口耦合度高(接口之间依赖性强,一个失败,后面全部失败)
    建议:适合依赖 3 个以内接口进行构造

  • 通过数据库构造【推荐】

    优点:灵活度大,执行速度最快
    缺点:需要熟悉库、表、字段
    建议:编写 SQL 语句时,使用复制生成的 SQL 语句,修改主要字段值

3.5 Jmeter 脚本实现自动化

Jmeter脚本需要依据测试用例进行编写,了解 Jmeter 各组件特性以及接口执行先后关系后并不困难,不过在细节上需要注意

  • 多次使用的具体数值可以在“用户定义的变量”进行变量管理,用到数据的地方只需要${变量名}$进行引用即可

    image-20240310143547301
  • 由于每次注册等业务都会操作真实数据库表,导致同一账号无法多次注册,不利于测试计划开展,因此需要设置 setUp 线程组(测试计划执行时会首先执行的线程组),使用 JDBC Request 组件在每次测试计划开启前移除指定用户在数据库表中的各种关联信息,同时添加借款标等信息,便于后续投资接口测试

    image-20240310144054999

    同时,为了能够一次性执行多条语句,在组件 JDBC Connection Configuration 中的 Database URL 中需要携带参数allowMultiQueries=true

  • 成功获取图片验证码时会返回 Cookie 信息,获取短信验证码除了需要填写正确信息外,还需要依赖于这一 Cookie 信息,使用 HTTP Cookie 管理器可以自动管理 Cookie 信息,在需要携带 Cookie 信息时帮助请求自动携带已有的信息,便于接口正常测试

  • 断言只需要对需要测试的点进行断言,无需对前置操作进行断言(前置操作在其余地方已测试过),如“注册”需要依赖“图片验证码”与“短信验证码”相关接口,但是这两个接口无需断言,只需对最后的注册结果进行断言即可

    image-20240310150354464
  • 不同模块的测试线程组可用“禁用线程组”进行分割,使层次关系更为清晰

    image-20240310150748233

3.5.1 持续集成

Jenkins 是一种持续集成工具,其可以实现将代码提交到 git 后就自动完成打包部署
在此案例中将其简单理解为拉取托管平台代码并生成 Jmeter 脚本测试报告,同时可以记录下历史构造记录的平台,当脚本发生变化时能被及时察觉,同时还具有定时执行的功能

新建任务,用于在 Jenkins 中管理项目

image-20240311141844629 image-20240311142058109

填写项目托管平台地址( GitHub 由于种种原因不太稳定,学习建议使用 Gitee 管理项目)

image-20240311144516598

拉取项目到本地后的执行步骤( Linux 需要用 Shell 的语法)

image-20240311144623767

每次生成测试报告时要保证目标文件夹下为空,因此在执行命令前需要清空相关数据(如果有的话)

# 删除测试报告产生的jtl文件
del result.jtl
# 删除report文件夹【当report文件夹不为空时无法产生新的测试报告】
# /S:除目录本身外,还将删除指定目录下的所有子目录和文件,用于删除目录树
# /Q:安静模式,带/S删除目录树时不要求确认
rmdir report /S /Q
# jmeter.bat绝对路径 -n -t jmeter自动化脚本绝对路径 -l 测试报告.jtl -e -o 生成的测试报告文件夹路径
# 含义为:使用jmeter执行脚本并将测试报告存放在指定文件夹中
# 同理,如果是Postman脚本则可以执行newman相关命令
D:\Program\Jmeter\apache-jmeter-5.6.3\bin\jmeter.bat -n -t C:\Users\Z_Jump_Dragon\Nutstore\1\我的坚果云\笔记\测试开发\项目\安享智慧理财\接口测试脚本\finance_auto_scripts\auto_script_jmeter.jmx -l result.jtl -e -o ./report
image-20240311155224443

拉取项目,执行命令

image-20240311160843319 image-20240311161002701

根据控制台指示地址对测试报告进行定位

image-20240311161318640

report 文件夹中的 index.html 即为测试报告文件,如下👇

image-20240311161842898

3.6 代码实现自动化

3.6.1 日志

日志用于记录程序运行的步骤和错误,通过参考日志可以清晰看到程序运行轨迹,方便 BUG 调试

Python 自带的日志工具使用方法如下所示👇

import logging
# 设置日志级别【高于这一级别的日志信息才会被记录】
logging.basicConfig(level=logging.DEBUG, filename="../log/p2p.log")
# 记录⽇志信息
logging.debug("调试信息")
logging.info("信息级别")
logging.warning("警告")
logging.error("断⾔错误!")
logging.critical("严重错误")

测试人员通常使用 info 等级记录测试步骤,使用 error 等级记录运行错误

日志封装重组

由于初始 logging 工具所记录日志界面不友好,因此手动对工具进行重组,使得日志生成后展示的信息更为友好

未来需要使用到日志的部分直接复制此段代码即可

# 日志工具
class GetLog:
    @classmethod
    def get_log(cls):
        cls.log = None
        if cls.log is None:
            # 1、获取日志器
            cls.log = logging.getLogger()
            # 设置日志级别 info
            cls.log.setLevel(logging.INFO)
            filepath = DIR_PATH + os.sep + "log" + os.sep + "p2p.log"
            # 2、获取处理器 TimedRotatingFileHandler:日志保存到文件且根据时间去分割
            tf = logging.handlers.TimedRotatingFileHandler(filename=filepath,
                                                           when="midnight",
                                                           interval=1,
                                                           backupCount=3,
                                                           encoding="utf-8")
            # 3、获取格式器
            fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
            fm = logging.Formatter(fmt)
            # 4、将格式器添加到处理器中
            tf.setFormatter(fm)
            # 5、将处理器添加到日志器中
            cls.log.addHandler(tf)
        # 返回日志器
        return cls.log
if __name__ == '__main__':
    # 生成封装后的日志工具,用法与 logging 一致
    log = GetLog.get_log()

3.6.2 BeautifulSoup 库

BeautifulSoup 库用于解析 HTML/XML 文件,从中提取出各元素标签的值。

在本案例的“请求开户”接口参数需要依赖“请求后台开户”返回的 HTML 界面中所有 input 标签,其中 name 属性值为参数名,value属性值为参数值。在使用代码实现自动化时需要使用到 BeautifulSoup 库

基本用法如下

# 此处包名是bs4
from bs4 import BeautifulSoup
page = """
<html>
<head>
<title>我是标题</title>
</head>
<body>
    <p id="test01">我是P标签1</p>
    <p id="test02">我是P标签2</p>
    <a href="/api.html">我是a标签1</a>
    <a href="/web.html">我是a标签2</a>
    <a href="/app.html">我是a标签3</a>
</body>
</html>
"""
# 创建 BeautifulSoup 对象示例,html.parser表面需要解析的文件为 HTML
bs = BeautifulSoup(markup=page,features='html.parser')
# find_all(标签名):获取所有匹配标签
for item in bs.find_all('a'):
    # get(属性名):根据标签属性名获取对应属性值
    # get_text():获取标签的文本内容
    print(item.get('href'))
    print(item.get_text())

3.6.3 目录结构

config.py

此文件存放各种公共配置,如服务器地址 HOST ,项目目录路径 DIR_PATH 等

util.py

此类负责存放各种工具方法,如日志工具类 GetLog ;将 Json 转换为便于 @parameterized.expand() 处理数据的方法 read_json ;在 HTML 中提取指定标签数据的方法 parser_html ;数据库连接处理方法 conn_mysql 以及每次测试之后的数据清除方法 clear_data 等

api⭐️
  1. 查看 Excel 编写的接口测试用例,尤其关注请求路径,请求方法与请求参数

    image-20240414135507939
  2. 编写类时以模块作为单位,方法则对应用例涉及的接口功能

    image-20240414140328913
  3. 编写模块接口实现类

    from api import log
    from config import SERVER_HOST
    
    class ApiRegister:
        # 初始化
        def __init__(self, session):
            # 获取session对象
            self.session = session
            # 图片验证码url
            self.__url_img_code = SERVER_HOST + "/common/public/verifycode1/{}"
            # 短信验证码url
            self.__url_phone_code = SERVER_HOST + "/member/public/sendSms"
            # 注册url
            self.__url_register = SERVER_HOST + "/member/public/reg"
    
        # 1、获取图片验证码接口 封装
        def api_img_code(self, random):
            log.info("正在调用获取图片验证码接口,请求方法:{} 请求url:{}".format("get",self.__url_img_code.format(random)))
            # 调用get方法 返回响应对象
            return self.session.get(url=self.__url_img_code.format(random))
    
        # 2、获取短信验证码接口 封装
        def api_phone_code(self, phone, imgVerifyCode):
            # 1、定义请求参数
            data = {
                "phone": phone,
                "imgVerifyCode": imgVerifyCode,
                "type": "reg"
            }
            log.info("正在调用获取短信验证码接口,请求方法:{}, 请求url:{} 请求参数:{}".format("post",self.__url_phone_code, data))
            # 2、调用请求方法
            return self.session.post(url=self.__url_phone_code, data=data)
    
        # 3、注册接口 封装
        def api_register(self, phone, password, verifycode, phone_code,dy_server,invite_phone):
            # 1、定义请求参数
            data = {
                "phone": phone,
                "password": password,
                "verifycode": verifycode,
                "phone_code": phone_code,
                "dy_server": dy_server,
                "invite_phone": invite_phone
            }
            log.info("正在调用注册接口,请求方法:{} 请求url:{} 请求参数:{}".format("post", self.__url_register, data))
            # 2、调用请求方法
            return self.session.post(url=self.__url_register, data=data)
    
script⭐️

script 存放的是测试工程师直接进行测试操作的脚本,测试类继承至 UnitTest 框架,类名必须以"Test"开头,方法则需以"test开头"

此处的脚本实现负责实例化 api 模块类,按照接口执行顺序对接口进行拼接从而构成完整测试点,通过参数化测试数据完成不同测试点的测试,最后通过断言来判断测试结果是否达到预期,同时将执行过程记录至日志信息中便于观察情况

测试类执行过程大致如下:

  • 首先执行类方法 setUpClass ,清除相关数据;
  • 在每个测试方法执行前先执行 setUp 方法进行初始化,获取 session 对象并作为参数传入,构造 api 类的实体对象,保存为类对象;
  • 测试方法执行,通过类对象调用需要测试的方法并传入测试数据,返回响应数据,通过对响应数据的状态码,文本等信息进行断言即可获得测试结果

如下为注册业务测试脚本👇

import unittest
from parameterized import parameterized
import requests
from api import log
from api.api_register import ApiRegister
from util import read_json, clear_data

class TestRegister(unittest.TestCase):
    # 整测试类执行前调用
    @classmethod
    def setUpClass(cls) -> None:
        # 在数据库中清除账号信息
        clear_data()

    # 初始化,测试方法执行前执行
    def setUp(self) -> None:
        # 获取session对象
        self.session = requests.session()
        log.info("正在初始化session对象:{}".format(self.session))
        # 获取ApiRegister实例
        self.reg = ApiRegister(self.session)

    # 结束,测试方法执行后执行
    def tearDown(self) -> None:
        # 关闭session对象
        self.session.close()
        log.info("正在关闭session {}".format(self.session))

    # 1、获取图片验证码接口 测试
    @parameterized.expand(read_json("register.json", "img_code"))
    def test01_img_code(self, random, expect_code):
        try:
            # 1、调用图片验证码接口
            r = self.reg.api_img_code(random)
            log.info("执行图片验证码响应状态码为:{}".format(r.status_code))
            # 2、查看响应状态码
            self.assertEqual(expect_code, r.status_code)
            log.info("执行图片验证码断言通过")
        except Exception as e:
            # 日志
            log.error("断言失败,原因:{}".format(e))
            # 抛异常
            raise

    # 2、获取短信验证码接口 测试
    @parameterized.expand(read_json("register_login.json", "phone_code"))
    def test02_phone_code(self, phone, imgVerifyCode, expect_text):
        try:
            # 1、调用获取图片验证码接口 --目的:让session对象记录cookie
            self.reg.api_img_code(123)
            # 2、调用短信验证码接口
            r = self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)
            log.info("执行接口结果为:{}".format(r.text))
            # 3、查看响应结果
            self.assertIn(expect_text, r.text)
            log.info("执行断言通过!")
        except Exception as e:
            # 日志
            log.error("断言失败,原因:{}".format(e))
            # 抛异常
            raise

    # 3、注册接口 测试
    @parameterized.expand(read_json("register_login.json", "register.json"))
    def test03_register(self, phone, password, imgVerifyCode, phone_code, expect_text):
        try:
            # 1、图片验证码接口
            self.reg.api_img_code(123)
            # 2、短信验证码接口
            self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)
            # 3、注册接口
            r = self.reg.api_register(phone=phone, password=password, verifycode=imgVerifyCode, phone_code=phone_code)
            log.info("执行接口结果为:{}".format(r.text))
            # 4、查看结果
            self.assertIn(expect_text, r.text)
            log.info("执行断言通过!")
        except Exception as e:
            # 日志
            log.error("断言失败,原因:{}".format(e))
            # 抛异常
            raise
run_suite.py

组装 script 的测试脚本,合并生成测试报告

# 1、导包
import os

from htmltestreport import HTMLTestReport
import unittest
# 2、组合测试套件
from config import DIR_PATH
suite = unittest.defaultTestLoader.discover("./script")
# 指定测试报告存储目录
report_path = DIR_PATH + os.sep + "report" + os.sep + "p2p.html"
# 3、执行测试套件
HTMLTestReport(report_path, title="p2p接口自动化测试报告").run(suite)
data

此文件夹存放各接口的待测 Json 数据,每个文件存放的测试数据应与 api 处理的接口对应,如下为部分注册登录相关测试数据

{
  "img_code": [
    {
      "desc": "获取图片验证码成功(随机小数)",
      "random": 0.123,
      "expect_code": 200
    },
    {
      "desc": "获取图片验证码成功(随机整数)",
      "random": 123,
      "expect_code": 200
    },
    {
      "desc": "获取图片验证码失败(随机数为空)",
      "random": "",
      "expect_code": 404
    },
    {
      "desc": "获取图片验证码失败(随机数为字符串)",
      "random": "123hello",
      "expect_code": 400
    }
  ],
  "phone_code": [
    {
      "desc": "获取短信验证码成功",
      "phone": "13600001111",
      "imgVerifyCode": 8888,
      "expect_text": "发送成功"
    },
    {
      "desc": "获取短信验证码成功",
      "phone": "13600001111",
      "imgVerifyCode": 8889,
      "expect_text": "验证码错误"
    }
  ],
  .....
}
log/report

一者存放日志文件,一者存放测试报告

image-20240313201903951
一些细节知识点
  • 当 package 被首次导入时,其下的 __init__.py 会自动执行

  • @parameterized.expand 传入的参数类型为 tuple

    import unittest
    from parameterized import parameterized
    
    class TestOKKK(unittest.TestCase):
        # 第一次a为1,b为2;第二次a为3,b为4
        @parameterized.expand(((1,2),(3,4)))
        def test01(self,a,b):
            print(a+b)
    

4. 面试介绍

  1. 项目基于什么框架?前端后端如何进行测试?

    • 架构:B/S架构(浏览器/服务器)
    • 前端:HTML + CSS + JavaScript + VUE
      后端:Java
      应用服务器:Nginx + Apache
      数据库:MYSQL
    • 前端使用 UI 自动化框架完成功能测试,后端则通过编写自动化脚本实现接口测试
  2. 性能测试有没有做过?主要做哪些方面?怎么做?具体压力测试主要是哪些方面?

    • 在简历中所提及的 P2P 项目中有做过与性能测试相关的内容,以用户登录为例
    • 首先指定详细的性能测试计划和流程,比如预期性能目标为 TPS 达到 x 情况下,登录响应时间不超过 y 秒,测试开始前使用 python 往数据库中插入若干有规律的记录以备后续并发操作的执行;
    • 接着确定性能测试工具,我所选择的性能测试工具是 JMeter。在 JMeter 中按照测试计划对线程组进行相关设置,如线程数,持续时间等,根据需要可添加组件。
    • 执行完毕后可通过聚合报告和服务器监听工具查看各种性能指标,如CPU利用率、内存利用率、磁盘IO情况等,通过分析各项性能指标,得出性能是否达标的结论,并将相关信息填入性能测试报告进行管理。

    需要注意的是,JMeter 单机负载能力有限,如果需要模拟用户请求数超过其负载极限,会导致 TPS 上不去

  3. 怎么进行测试用例设计?

    • 首先需要认真阅读需求说明书,明确需要测试的部分以及范围,如果有UI原型图的话可以配合说明书将功能流程走一遍加深印象
    • 接着通过思维导图工具总结概括出业务流程图,编写功能测试用例
    • 接着根据各功能的实际情况选择合适的设计方法,如等价类,边界值,判定表等,编写接口测试用例,需要包括前置条件、请求地址、请求数据、预期结果、测试结果等信息
    • 接着和团队成员之间针对用例进行进一步评审与修改
    • 执行测试用例,生成测试报告并进行缺陷追踪和管理

5. 经典题目

5.1 给你一个XXX功能/物件,你会如何测试?如何设计测试用例?

比如:微信朋友圈点赞、微信发语音消息、购物车、登录功能,支付功能,实物(一个水杯、一支笔、一把伞)……

  • 易用性:界面布局排版是否美观,是否符合产品需求,操作是否简单,操作是否有友好提示

  • 兼容性:不同手机、浏览器、操作系统、分辨率是否都能通过

  • 接口测试:接口返回报文、状态码是否正常

  • 功能测试:场景 + 流程 + 删改 + 排序

    将自己代入使用者场景;将自己代入接收者场景;删除修改数据时各方的变动;显示顺序等

  • 弱网测试:断网、网络信号差时操作是否正常

  • 性能测试:在指定环境下使用该功能的响应时间是否在需求规定时间内

  • 安全测试:客户端和服务端是否都对传送数据进行验证

智慧理财相关资料 30 一份,有意者扫描付款后留下邮箱,相关资料通过邮箱发送(远程数据库+网站有效地址)
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/698954.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【浏览器清空证书】

chrome://net-internals/#hsts 在地址栏输入并访问&#xff1a;chrome://net-internals/#hsts

【回眸】Linux内核(十一) 进程间通讯 之 管道

前言 进程的介绍已经告一段落,接下来学习的内容是进程间的通讯. 进程间通信(IPC) 面试考点: IPC的通讯方式通常有:管道(无名和命名) ,消息队列,信号量,共享存储,socket,streams等.socket和streams支持2个不同的主机上的2个进程IPC. 管道通常指无名管道 特点: 1. 半双工(…

【稳定检索/投稿优惠】2024年艺术、语言与文化交流国际会议(ALCE 2024)

2024 International Conference on Art, Language, and Cultural Exchange 2024年艺术、语言与文化交流国际会议 【会议信息】 会议简称&#xff1a;ALCE 2024 截稿时间&#xff1a;点击查看 大会地点&#xff1a;中国桂林 会议官网&#xff1a;www.icalce.com 会议邮箱&#…

Hadoop 2.0:主流开源云架构(二)

目录 二、Hadoop 2.0简述&#xff08;一&#xff09;Hadoop 2.0由来&#xff08;二&#xff09;Hadoop 2.0相关项目&#xff08;三&#xff09;Hadoop应用 三、Hadoop 2.0部署&#xff08;一&#xff09;部署综述&#xff08;二&#xff09;传统解压包部署 二、Hadoop 2.0简述 …

企业微信hook接口协议,ipad协议http,取消扫码返回

简要描述&#xff1a; 取消扫码返回 返回类型&#xff1a; 100003 返回uuid&#xff1a; f7503bb5-7d27-408f-ab24-8c4ace7f 返回示例 {"Vid":1688853790599424,"Qrcode_key":"D368DC88254A3E79FF72942B588D7FBE","Corpid":197…

PLSQL 报错 could not locate oci.dll

0、确保PLSQL已激活。 1、在PLSQL安装包内搜索oci.dll&#xff0c;如果没有搜到需要下载 链接&#xff1a;https://pan.baidu.com/s/1HOfKAEFfuAGYACjfcwqJ1g 提取码&#xff1a;6evh 2、打开PLSQL&#xff0c;设置oci.dll的路径 ps&#xff1a;PLSQL安装包 链接&#xff…

AI预测体彩排3采取888=3策略+和值012路或双胆下一测试6月11日新模型预测第1弹

很抱歉各位小伙伴&#xff0c;端午节三天去了趟外地&#xff0c;没有按时更新3D和排三的预测。前面跟大家说过&#xff0c;8码定位是关键&#xff0c;8码定位能稳定在80%的命中率&#xff0c;才有望通过缩号缩至200-250注以内通过等额方式进行投资。由于前面的模型对8码定位的效…

程序猿大战Python——流程控制——其他控制语句

for循环 目标&#xff1a;掌握for循环的使用。 与while循环功能类似&#xff0c;for语句也能完成反复多次的执行。 for语法&#xff1a; for 临时变量 in 序列:满足条件时&#xff0c;执行的代码1满足条件时&#xff0c;执行的代码2…… [else:当for循环正常执行结束后&#…

odoo15升级odoo16遇到的问题及解决过程

odoo15升级odoo16遇到的问题 PyMuPDF 档案管理整理时,从15升级16出现如下错误: File "f:\od162306\dms\dmssp\models\shenqb.py", line 136, in doc_fj_pdf doc.SaveAs(ftem, FileFormat=17) # input_file.replace(".docx", ".pdf") F…

分离式光电液位传感器有哪些特点?

分离式光电液位传感器是一种先进的液位检测技术&#xff0c;在科学技术的不断推进下得到了广泛应用。相比传统的液位传感器&#xff0c;分离式光电液位传感器具有许多独特的特点。 传感器采用了先进的光学技术&#xff0c;将传感器装在需要检测液位的位置&#xff0c;并采用了…

重温react-01

创建react项目 // 第一步 npm install create-react-app -g // 第二步 create-react-app my-app目录介绍 my-app/README.md# 项目第三方依赖包node_modules/package.json# 一般用来存放静态依赖public/index.htmlfavicon.ico# 存放项目源代码&#xff0c;注意只有放在scr目录…

期末复习4---PTA之前题目复习

怎么在不能用strlen也就四没有string.h头文件的时候实现统计字符串的长度&#xff1f; 字符串的逆序&#xff08;看收藏里面的题&#xff09; #include <stdio.h> void f(char *p);int main() {char s[1000];gets(s);f(s);printf("%s",s);return 0; }void f(…

为啥影像导入GIS后,颜色会变?两个方法解决它!

不知道你有没有遇到过这种情况&#xff0c; 影像的正常颜色是这样的—— 可是导入到GIS后&#xff0c; 颜色竟然变了&#xff0c; 而且变得很奇怪—— 你也不必惊讶&#xff0c; 极大概率是因为数据源类型没有正确识别&#xff0c; 有两个方法可以解决这个问题—— 方法一…

告别Proteus,拥抱SmartEDA:电路设计新纪元,效率飞跃不是梦!

在数字化浪潮席卷而来的今天&#xff0c;电路设计行业也迎来了前所未有的变革。曾经&#xff0c;Proteus以其稳定可靠的性能&#xff0c;赢得了众多电路设计工程师的青睐。然而&#xff0c;随着技术的不断进步和市场的快速变化&#xff0c;我们需要一款更加高效、智能的工具来应…

苹果一夜间重塑iPhone!GPT-4o赋能Siri,AI深入所有应用,库克:开启苹果AI新时代

千呼万唤&#xff0c;苹果如何用AI重塑iPhone&#xff0c;答案终于揭晓&#xff01; 各种令人激动的传闻&#xff0c;通通都是真的—— 苹果确定与OpenAI达成合作&#xff0c;接入ChatGPT&#xff0c;使用GPT-4o模型。 GPT-4o深夜发布&#xff01;Plus免费可用&#xff01;http…

工业4.0下的PLC进化论:ARMxy计算机如何重塑自动化

智能物流系统的高效与精准成为企业竞争力的关键。在这个背景下&#xff0c;传统的PLC系统因其固有的局限性&#xff0c;如扩展性差、系统封闭等&#xff0c;开始显得力不从心。ARMxy工业计算机作为新一代的PLC替代方案&#xff0c;凭借其低功耗、高性能以及高度的灵活性&#x…

使用LangChain与ChatGLM实现本地知识库(一)

前言 本篇主要内容为介绍ChatGLM3的安装使用&#xff0c;后续才会涉及到使用LangChain实现本地知识库的内容&#xff1b; ChatGLM为智谱与清华大学开源的一个大语言模型&#xff0c;支持多轮对话、内容创作等&#xff0c;ChatGLM3-6B为ChatGLM3系列中门槛相对较低的一个&…

成都跃享未来教育抖音小店深度解析靠谱与否

在如今网络购物日益繁荣的时代&#xff0c;抖音小店以其独特的平台优势和庞大的用户基础&#xff0c;吸引了越来越多的商家入驻。成都跃享未来教育咨询有限公司便是其中之一&#xff0c;它的抖音小店究竟靠不靠谱呢&#xff1f;今天&#xff0c;我们就来一起揭开这个谜底。 首…

vue实现拖拽元素;vuedraggable拖拽插件

效果图&#xff1a; 中文文档 以下代码可直接复制使用 安装依赖 npm i -S vuedraggable使用 <template><div class"container"><div>使用flex竖轴布局 <br>handle".mover" 可拖拽的class类名 <br>filter".forbid&qu…

解析ISP许可证:构建安全可靠的网络空间

在当今数字化时代&#xff0c;互联网已成为人们生活和工作中不可或缺的一部分。作为连接世界的纽带&#xff0c;互联网服务提供商&#xff08;ISP&#xff09;承担着重要的责任&#xff0c;为用户提供稳定、高效的网络接入和服务。而ISP许可证&#xff0c;则是保障这些服务合法…