墨菲定律是这样一条定律,Anything that can go wrong will go wrong。
引申到软件开发行业,不测试的代码就会出错。
假设屏幕上有一个需要输入电子邮件地址的文本框,是否需要测试它,如何测试它?很多人告诉我,上网搜一个正则表达式就可以了。
在回答这个问题之前,我先说个我的亲身经历,我用我的一个邮箱注册某个网站,而我的邮箱恰好是@之前有两个.的,结果,注册时那个网站提示我,请输入正确的邮件地址。很显然,这种情况没有被测试过。
那么我们回到测试电子邮件地址这个话题,究竟要测试多复杂的地址组合才能够放心呢?
我们上网来搜一个正则表达式吧,看看效果如何。
^\w+[-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
这个据说还是最佳答案。我们来测试一下它如何?
比如:
a_____186@163.com
会不会通过上述校验呢?答案是不会。而它确实是一个合格的邮箱地址。
所以,网上搜索的正则表达式有多不靠谱可以看到了。
附带一个测试用例集合给给大家一个参考。
正如开头所说,可能出错的事情就会出错。
所以,不测试如何能够放心呢?
那么如何才能够最初令自己放心的测试呢。比如,页面有三个文本框每个文本框有三种校验,分别是,必须输入,长度限制和格式要求,那么加在一起一共是多少种组合的测试呢?
如果你想测试三个文本框(A B C),三种测试(1 2 3),那么分开测试,每种情况至少运行一次,只要有3种测试应该就够了。这种把各种指令都要运行一遍的覆盖方式叫做指令覆盖。*注:是否指令覆盖其实严重依赖于代码的书写方式。这里的举例主要是为了说明各种分析对于测试覆盖率的不同影响。
A 1
B 2
C 3
但是很显然这种测试是不充分的。那么继续,可以扩展为9种组合。这种把各个分支都运行一遍的方式叫做分支覆盖。
A 1 2 3
B 1 2 3
C 1 2 3
但是这就够了吗?并不是,往下延展当控件的输入违背了校验的时候,需要提示错误消息,为了提升用户体验,要将每个控件的第一个错误都要打印到屏幕上,那么组合的可能性就多起来了。而不仅仅是这么几个。具体数字有兴趣的同学可以自己计算一下。这种把从一点到另一点的各种可能的路径都覆盖的方式叫做路径覆盖。
而这样的测试组合就显得数量很多了,一想到一个大的系统有若干的界面,界面的控件数量远超过3个,验证组合也非常多,测试工作量岂不是大的惊人?
等价测试用例是一种用来简化测试的手法,即对于等价的东西没有必要反复测试。但是这个建立的前提是代码上那些逻辑等价的东西也是等价的。如果代码上不是等价的,那么划分等价测试用例的方法就是一个有严重危害错误。所以划分等价类之前最好了解一下对应的代码是怎么写的。
举个简单的例子如果代码无法满足 f(n), f(n+1)的等价那么就要全部测试所有的组合。举例来说,如果上述三个文本框的这种组合测试条件的两个文本框出错和三个文本框同时出错这两个条件出现的结果不一致,那就表示代码本身的逻辑复杂度超过了本身业务复杂度的要求(总会有程序员能想办法写出这样的代码,尤其是初级程序员)。遇到这种情况,全部测试各种可能的组合才是最安全的。
有效等价类划分,比如,有个固定的翻页控件,代码结构清晰,全部采用的是除法计算页数的,每页显示15条数据,那么16条和17条是等价的。不必把所有的条数全部测试。
无效等价类划分,比如,北京管理员和上海管理员在同一个系统中,尽管处理逻辑可能完全相同。但是由于代码书写的时候采用了较为复杂的结构,北京管理员角色id=1,上海管理员的角色id=2,而在计算的时候使用了同一个变量做了不同的意思,恰好某个逻辑下把角色id赋值给了另外一个变量,那么这个代码就使得这两个同为区域管理员的情况,使用效果却不同。
简单的说,是否是等价类是由代码决定的,而不是业务逻辑决定的。而如果作为测试人员你无法评估代码是否具备等价特征,那么最好的办法就是全部测试。因为:不测试的代码就会出错。
Web页面有个性别的下拉框,是否需要测试request接收后是否做了数据范围验证?
屏幕都已经做了限制了,用户只能选择“男”或者“女”,所以没有什么特别的了吧?相信很多人都会这么想。
可是,访问网站的并不只有浏览器,HttpClient这个类也可以访问后台,Postman这个工具也可以访问后台,甚至可以写一个自己的html来提交表单,它们是不受限制的。所以,在这种情况下,性别可以输入的内容就没有限制了。那么,如果输入的是</option>会发生什么后果呢,不同的系统反应也会不一样,试试看,也许会有惊喜。如果输入的是;select version() 试试呢。
记住“不测试的代码就会出错”就更容易发现问题所在。
那么是否一定要追求测试覆盖率100%呢?
并不是。
首先要知道测试覆盖率是个什么东西。目前能够度量测试覆盖率的工具都是度量“指令覆盖率”的。所以首先要知道即使测试覆盖率达到了100%也不说明测试就很充分。
其次,有些代码很难构建测试。比如,某些Exception的发生条件。所以不要追求100%这个数字,而要关注更有意义的指标。到底测试有多充分。
至于一些看似简单的功能,千万请不要掉以轻心,一不小心就会漏测。尝试反复登录系统的那个不一定是人类,也可能是段代码。你登录页面就不能是个简单用户名密码验证功能。同样的尝试注册的也不一定就是人类。而频繁使用同一个IP地址访问的可能就是用一个局域网下的用户(往往是同一个单位的人)。
操作者的操作方式也不是单一的,而是各种可能会更灵活的可能性。比如:操作者往回按浏览器的回退按钮,再继续操作;从收藏夹访问然后操作;直接复制url地址;
多种浏览器、多种不同尺寸的屏幕、多种操作系统都是发现问题的好地方。
打开浏览器的开发者窗口,直接修改Html,书写javascript的用户;采用wireshark抓包改包的用户;自己写个客户端访问的用户;采用爬虫访问网络的用户;直接写个iFrame把你的网站套在Ta的网站上显示的用户;写个<img src>引用你的图片资源的用户;手机访问的用户;低速不稳定网络访问的用户;
你能够模拟的越多,你能够防御的也就越多。
想想看,虽然你不打算支持IE6,但是如果有个用户真的用IE6来访问你的网站会如何?