# 你可能考虑不到系统架构上的异常




对于测试同学来说，设计及执行异常场景的用例是平时工作中非常重要的一部分，因为只关注正常流程的话，那么很多情况下隐藏的缺陷并不能被完全的发现。

很多同学经常在上线之后感到惴惴不安，心里很没底，哪怕上线之前测试的再充分，都会有这样的感觉。这是因为我们很难预见到线上系统会出现哪些我们所没有覆盖到的异常场景。

异常场景大致可以分为下面这几类吧

### 业务上的异常流程

比如正常的业务流程是用户先操作步骤1再操作步骤2，但是用户偏偏先做步骤2再做步骤1。因为测试同学在执行测试时，往往是对被测产品有一定的认识的。既然对被测有所了解，甚至大部分情况是非常了解，这样一来就会对被测产品的设计是有一定的认同感的，就会先入为主的认为用户一定会先做步骤1再做步骤2，这样就会忘记验证异常的场景，造成缺陷遗留到线上，产生了不太好的后果。

所以一些有经验的测试同学会站在用户的角度上去设计测试用例。因为用户的行为永远是千奇百怪的，所以有时候我们确实要设计一些逻辑上看上去不太合理的用例，设计这些用例时往往还会伴随着 “靠，竟然有这种操作”的惊叹，这种惊叹用例往往是很有价值的，能发现程序设计或者是产品设计上的漏洞。

永远不要相信用户的输入，永远不要认为用户的操作是感性合理有章可循的。抱着怀疑的态度去测试往往能产生意想不到的效果。

### 操作上的异常

这种异常可能会比较隐蔽。比如在电商系统生成订单的时候，用户连续点击了n次提交按钮，导致产生了n个订单，这显然是我们不想看到的结果。因为用户行为的随机性，有一些操作我们真的是很难想象到，我们只能尽量借助于monkey等方式进行一些混沌测试，毕竟猴子比用户更加的不可控。

### 架构上异常

很多测试同学不懂架构却要为架构背锅，这大概是不合理的吧。

在测试同学的能力模型里，业务能力的加点应该是最高的，技术能力和架构能力的技能点往往是少加甚至是不加的。如果你不需要为架构背锅，那么不了解架构应该没什么大问题，但如果线上问题的锅基本上就是你的锅，那么懂一点架构起码可以防身辟邪，多少是有用武之地的。

架构的异常场景是我们在设计用例的时候很难想象到的。因为你没办法想象一个在你的认知里根本不存在东西究竟是什么样子，这比叶公好龙和盲人摸象更加的虚无缥缈。如果你的意识里系统架构都不存在的话，那么你怎么知道架构在什么情况下会出现异常呢？

举个简单的缓存的例子，在我们的系统架构中，缓存是非常常见的中间件，一些需要频繁操作数据库去读写的数据我们可以放在缓存里以加速访问和存取速度。不过缓存天生有一些异常场景。

比如我们把一些数据放到缓存里，但是用户在访问系统的时候这部分数据可能用到的很少，大部分的用户请求可能还是直接读取数据库，造成数据库压力过大，系统整体性能很差甚至崩溃。这就是缓存命中率低的场景，这种场景我们比较难设计业务用例去覆盖，只能对其进行专项测试和优化。

另外系统在刚上线的时候缓存可能是空的，这就导致用户的请求全部击穿了缓存直接到了数据库，造成数据库崩溃，系统不可用。这就是缓存没有预热，或者是系统冷启动的问题，这种问题应该是常识，是不需要测试就能想到的，但前提是我们要对系统架构有一些了解才可以。

还有就是如果系统频繁对某个具体key值的缓存做读写，那么该key所在的缓存实例可能就会过载，造成整个缓存集群性能下降，这就是热点key的问题，也应该是不用测试就能想到并提前防范的。

不过缓存的过期时间和更新策略跟我们的业务相关性还是比较大的，是可以在设计的阶段就想好，然后在测试阶段去验证的。

从上面可以看出，如果你不知道系统架构里有缓存这样一个东西，那么万一哪天缓存出了问题造成了线上问题，那这个某名奇妙的锅很可能对你产生巨大的降维打击。领导一句你为什么没有测出来，你很可能连辩解的理由都解释不清楚。

综上，异常场景往往是我们测试的重点，业务异常和操作异常是大家可以想象到的，不过架构上的异常大家往往难以名状，出了问题却又有苦难言。所以多学一些架构知识应该是有好处的，有些问题其实可以提前防范和规避，不需要在上线之后惶惶不可终日的。不过这只是作者的一家之言了，因为水平有限，所以还请大家多多斧正。




原始封面

![课程图片](https://images.unsplash.com/photo-1432958576632-8a39f6b97dc7?w=300)


