测试角度的并发和幂等问题总结

本文探讨了金融业务测试中的并发问题与幂等问题,详细解析了并发的特点、优缺点及应用场景,介绍了并发测试的难点与预防措施,并深入讨论了幂等性的概念、常见问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文来自网易云社区


作者:刘静媛


前言  

   从事金融业务领域的测试工作过程已经有半年时间了,在此期间遇到了各种类型的问题,个人认为在日常测试工作中,特别是涉及资金的业务领域内,测试人员需要格外关注的方面有:系统的并发问题、幂等问题、性能问题及资损风险等。下面就是这段时间以来,在并发问题和幂等问题上站在测试角色上的一些积累和总结。


一、并发问题  

1、什么是并发?

   并发(Concurrency)是指系统在同一时间段内,同时执行多个计算程序。为了更好的解释并发的概念,引入并行(Parallelism)概念来进行对比分析。

下图较为形象的给出两者的工作机制:

20180906103841124e5c47-0c8d-4005-a9cc-663a63ac299e.png              

   在多个线程同时工作时,单个CPU硬件环境下不可能真正同时的有多个线程在工作,此时并发机制实际上是将CPU的运行时间划分成若干时间段,不同的时间段交由不同的线程使用,而其他线程此时属于挂起状态。在多个CPU的硬件环境下才有可能实现多个线程真正的同时工作。


2、并发与并行特点  

并发并行
宏观层面同时执行严格的同时执行
解决多个不相关的任务一般解决同一个任务
资源和数据共享资源和数据隔离
单、多处理器均可必须多处理器
彼此需要交互通信不需要交互通信
重点是组合协调重点是执行

3、并发的优缺点

优点:

(1)提升资源利用:这个优点是最容易理解的,多线程并发可以提升cpu的利用率,比如在一个线程等待磁盘IO资源时,CPU可以去执行另外的任务。在任务量大的情况下,并发机制能够明显减少系统耗时。

(2)模型边界清晰:能够并发的任务,应该是尽量没有依赖关系的,是相互独立的,能够同时执行而不相互影响的。例如设计一个文件处理器,就可以使用多个线程,每个线程负责一个文件的读取和操作,在多个线程同时工作时,对每个文件的操作是相互独立的。

(3)异步事件响应:在处理异步任务时,并发编程的优点更是显而易见的,它能够避免单线程情况下资源闲置和过度等待。建立单独的监听器,在得到异步响应时随时处理响应,高效合理的利用系统资源。

缺点:

(1)安全风险:由于同一进程下的多个线程会共享地址空间和数据,而多个线程访问资源的顺序具有不确定性,因此在多线程并发时容易出现脏读、幻读等问题。(线程安全)

(2)活跃度风险(饥饿、死锁、活锁)

(3)性能风险:线程频繁调度切换同样会带来资源浪费。

(4)分析、编程和测试复杂

4  、并发编程常见的应用场景

定时任务、分布式任务、WS服务、Servlet、异步消息

多见于:多进程并发、集群中机器之间并发

5  、并发安全措施

数据库行级锁:悲观锁,乐观锁

全局分布式锁

应用同步和锁机制:——Synchronized\CAS;——java.util.concurrent.locks;——java.util.concurrent.atomic

使用线程安全的容器:java.util.concurrent

6  、测试角度看并发问题:  

6  .1 难分析、难测试:

有些并发问题,是很难在平时测试过程中发现的,特别是系统底层存在的并发问题,例如:

缓存更新设计不合理导致的脏数据问题——如果缓存更新的设计模式是先清除旧的缓存再更新数据库,首先这个设计是不合理的,排除设计的正确性不谈,如果在测试人员不了解缓存更新策略的情况下,执行上层业务层面的并发测试,有很大的概率是在测试过程中并没有出现问题,但是仔细分析一下,在一个外部条件触发了缓存更新的同时,有可能出现另外两个并发操作:一个更新,一个查询。在删除缓存后,有一个查询操作访问缓存没有命中,会去查数据库,并把数据库中老的数据放进缓存中,同时更新操作会更新数据库。这样导致缓存中的数据一直是老的数据,是脏数据并且会一直脏下去。而在现实测试过程中,缓存的更新以及查询操作都发生的非常之快,很难人为造出类似或者更为复杂的并发场景。


6  .2 难定位、难复现:

大家在开发测试过程当中可能都会遇到的一个场景就是在多次执行同一个操作时,不定期的会有一个操作是执行失败了,很难找到失败的规律,测试同学提bug时也会很难再复现出bug并保留现场给开发人员排查。甚至此类情况直接出现在了生产环境,用户反馈说操作失败,但是更难说清楚在什么情况下会失败。这种问题发生的原因可能是多种多样的,可能是多线程设计的漏洞,也可能是系统交互的异常情况欠考虑引起的。当遇到这种情况时,靠碰运气和多次尝试是很笨拙的方法,关键还是分析出可能存在的并发问题,再有针对的尝试验证,确定是某种原因并分析解决后,再进行并发尝试,看是否还存在问题。

6  .3 预防和发现手段:

a.业务场景分析:实际应用场景下某功能是否会出现并发情况,对于会出现并发情况,重点关心代码设计,并准备做并发测试。

b.静态代码分析:可以借助工具   Contemplate's   ThreadSafe Solo,参考  http://www.contemplateltd.com/threadsafe

c.并发测试的注意事项:

   (1)不放过偶发的错误和失败

   (2)做好测试分析,完成非并发的功能测试后,针对测试分析时分析到的容易出并发问题的部分做独立的并发测试

   (3)并发测试时,注意并发测试设置的并发线程数需要做到可调节,通常要大于CPU数量


二、幂等问题  

1、幂等的概念

幂等来源于数学概念:单目运算中,x为某集合中的任意数,f为运算子,如果满足f(x)=f(f(x)),那么f运算就是幂等的。

幂等性是系统接口的一种承诺,承诺只要调用接口成功,多次相同的输入会有相同的结果反馈和等同一次处理的影响力。声明为幂等的接口会认为外部调用失败是常态,并且失败后必然会有重试。

2、引发幂等问题的常见原因

用户重复提交——非常容易发生,前端、后端均需要控制

网络重发——容易遗漏,但有可能发生

消息重发——容易遗漏,但有可能发生

系统间重试——需要根据业务情况来判断是否需要重试,哪些情况哪些系统需要重试

3、幂等问题的控制关键

在设计资金的系统中,幂等问题有着十分重要的地位,比如我们定义一个接口withdraw

bool withdraw(accountId, amount)  

withdraw的语义是从accountId对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。  

一种典型的情况是withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被丢掉了,导致客户端无法得知处理结果。如果是在交互设计或者前端展示上处理的不够好,用户会以为这次操作执行失败,然后刷新页面或者重复提交请求,这就导致了withdraw被调用两次,账户也被多扣了一次钱。整个过程如下图所示:  

2018090610401575e0c67d-71d7-436b-b335-082ec2791f3f.png                    

为解决此问题,需要对接口进行幂等性改造,增加一个唯一ID参数,如:

bool idempotent_withdraw(uniqId,accountId,amount)  

这个ID需要全局唯一的标识一次请求,客户端的同一个业务请求只有一个uniqId,服务端在收到请求后去检查一下是否已存在这个   uniqId并且执行成功了,如果执行成功就不会再处理第二次的调用请求,如此就避免了重复扣款的问题。  


 

总体而言,在技术实现上,控制幂等问题的关键在于唯一键+状态机。

首先,调用者在请求中携带一个唯一ID,这个ID唯一的标识一个工作单元,这个工作单元只允许被成功执行一次。

其次,接受者在收到请求,获得唯一ID时,要先去查询这个ID所标识的工作单元是否被执行过。   检查是否执行的逻辑通常是根据唯一请求ID ,在服务端查询请求是否有记录,是否有对应的响应信息,如果有,直接把响应信息查询后返回;如果没有,那么就当做新请求去处理。

4、测试角度看幂等

(1)需要更多的关注业务性质和产品设计上,是否需要做到幂等,是时间维度的幂等还是空间维度的幂等。

(2)接口的幂等测试一定不能遗漏,由于幂等场景相对容易制造出来,幂等测试的难度远远小于并发测试,因此在做接口测试时不妨对每个接口都思考一下是否需要幂等,需要的话就测试一下其幂等性

(3)业务场景,特别是涉及到资金流动的业务场景,对失败重试机制一定要慎重。


 



网易云大礼包:https://www.163yun.com/gift


本文来自网易云社区,经作者刘静媛授权发布

 


相关文章:
【推荐】 SpringBoot入门(五)——自定义配置

<think>嗯,用户让我介绍一下如何根据博客系统项目设计黑盒测试白盒测试。首先,我需要回忆一下黑盒白盒测试的基本概念,确保自己理解正确。黑盒测试主要关注功能,不需要看内部代码,而白盒测试则要了解内部结构,针对代码路径、条件等测试。 接下来,用户提到的是博客系统,所以得先考虑这样的系统通常有哪些功能模块。比如用户注册登录、博客文章的增删改查、评论功能、搜索、权限管理等等。需要把这些模块列出来,然后分别设计黑盒白盒的测试用例。 对于黑盒测试,可能需要从用户的角度出发,测试每个功能是否符合预期。比如注册时输入无效邮箱是否提示错误,登录失败的处理,发布博客的流程是否顺畅,编辑后是否保存正确,删除是否有确认提示等等。还有界面测试,比如不同浏览器、设备的兼容性,以及性能测试,比如多人同时发帖时的响应时间。 然后是白盒测试,这时候需要考虑代码结构。比如用户管理模块中的密码加密函数,需要覆盖各种条件,比如空密码、特殊字符等。博客发布模块的输入校验,可能需要检查XSS过滤SQL注入防护。这里需要设计用例覆盖所有条件分支,比如if-else语句的所有情况,循环的边界条件,比如空列表或者最大限制。 另外,可能需要提到具体的测试方法,比如黑盒中的等价类划分、边界值分析,白盒中的语句覆盖、条件覆盖等。还要考虑集成测试,比如各个模块之间的交互,比如发布博客后是否在首页正确显示,评论后通知功能是否正常。 需要注意的是,用户可能希望了解具体的例子,所以应该举一些实际的测试用例,比如用户注册的不同情况,或者博客编辑的异常输入处理。同时,要区分黑盒白盒的不同侧重点,黑盒更关注外部行为,白盒更关注内部逻辑。 还要确保回答结构清晰,分点说明,可能用序号或项目符号列出各个测试方法对应的例子。同时,语言要口语化,避免过于技术化的术语,但又要准确。可能需要检查是否覆盖了博客系统的主要功能模块,以及测试的全面性。 最后,总结一下两种测试方法的结合使用的重要性,确保功能正确代码质量。可能还需要提到自动化测试工具,比如Selenium用于黑盒,JUnit用于白盒,但用户没有特别问工具,所以可能不需要深入。</think>根据博客系统项目的特点,我会按照以下结构设计黑盒测试白盒测试(严格遵守LaTeX格式要求): # 一、黑盒测试设计(功能驱动) $$测试对象 = 博客系统前端功能 + 用户可见交互$$ **1. 核心功能测试用例** - 用户注册:$测试用例 = \lbrace 有效邮箱/无效格式/重复注册 \rbrace$ - 文章发布:$验证约束条件 = \lbrace 空标题/超长内容/非法标签 \rbrace$ - 评论系统:$边界值分析 = \lbrace 0字符/1000字符/XSS注入检测 \rbrace$ **2. 业务流程测试** ``` 发布流程 = 登录 → 写文章 → 添加标签 → 预览 → 发布 → 验证首页展示 编辑流程 = 定位文章 → 修改内容 → 保存草稿 → 版本比对 ``` **3. 兼容性矩阵** $$兼容组合 = \begin{pmatrix} Chrome & Windows 11 \\ Safari & iOS 16 \\ 微信浏览器 & Android \end{pmatrix}$$ # 二、白盒测试设计(代码驱动) $$覆盖率目标 \geq 90\%\ 语句覆盖 + 分支覆盖$$ **1. 关键模块测试** ```python # 用户权限验证函数 def check_permission(user, post): if user.is_admin: # 分支1 return True elif post.author == user: # 分支2 return not post.is_locked # 条件组合 else: return False ``` 测试路径覆盖: - 管理员访问 - 作者访问未锁定文章 - 非作者访问已锁定文章 **2. 数据库操作测试** $$SQL注入防御验证 = \lbrace 特殊字符过滤 \rightarrow OR 1=1 \rightarrow 结果集验证 \rbrace$$ **3. API接口测试** ```javascript // 文章点赞接口 POST /api/like 测试断言 = { 响应码: 200/401/403, 等性: 重复请求检测, 并发测试: 100用户同时点赞 } ``` # 三、测试策略结合 $$测试有效性 = 黑盒测试(功能验证) \cup 白盒测试(逻辑验证)$$ 1. 先执行黑盒测试验证核心业务流 2. 根据代码覆盖率报告补充白盒用例 3. 重点模块采用灰盒测试(参数边界+代码路径结合) **示例组合测试**:文章搜索功能 - 黑盒:验证模糊搜索/特殊字符处理/空结果展示 - 白盒:覆盖倒排索引构建算法/Trie树查询路径 建议使用测试金字塔模型: $$自动化测试占比 = 70\%\ 单元测试 + 20\%\ 接口测试 + 10\%\ UI测试$$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值