但是确实存在一些不好测试的东西并且很难只让它执行一些非常简单的逻辑,比如嵌入式系统中的BSP(板级支持包)。开发它们所使用的语言、环境以及它们本身的特性等决定了它们是很难测试的。这里说的难测试其实是一个测试代价问题,具体的说就是要付出更多的时间和努力。这就需要你在付出的代价和测试带来的收益之间进行平衡。如果付出的代价所带来的收益(更少的调试、维护、发布成本)是巨大的,那么付出的代价就是非常值得的。
误区之三:测试代码可以随意写
大家肯定知道测试代码是不能随意编写的,并且在编写测试代码时也不是抱着一种随意的态度,但是你编写出来的测试代码以及测试代码运行的情况却表现出了一种随意性和无序性。因为你可能并没有弄清楚测试的真正意图所在。
本人曾经看到过有关验收测试的这样一个案例,验收测试者使用昂贵的商用测试工具对一个具有图形界面的软件进行测试。测试的方法是通过编写测试脚本驱动鼠标在图形界面上随机的点击(当然每一次的点击,都点到了图形界面上可以接收事件的区域),然后等待着被测试软件的崩溃。当然这种测试方法可以作为验收测试的一个方面,但是决不是唯一的一个方面。还有更重要的内容被忽视了。
测试的目的是用来检验软件系统是否满足了需求。所以,你的测试代码一定要明确的表达出这一点来。就那上面的案例来说,如果测试者真正从用户的需求出发,那么他写出来的测试脚本肯定不会是那样的,而因该是每一个测试用例都清晰的刻画了一项用户的需求,然后检验系统是否实现了用户期望的功能。这样的测试才是有明确目的,才是最有效的测试。和把界面逻辑和应用逻辑隔离,采用明确表现用户需求测试用例进行测试相比,上面的测试方法不能不说是随意了一点。
在针对类进行的单元测试中,也经常会看到一些错误的测试方法。很多的测试者往往针对类中的每个特定的实现细节进行测试。类中的特定的实现细节是很容易变化的,在快速的迭代式开发中更是如此。一旦你测试的类中的某个实现细节发生了变化,你原先的测试代码就要进行相应的更改,否则就失去了意义。这种频繁更改的代价是巨大的。类是一种抽象,它反映了更高层面的内聚性,它应该有明确的职责和定义良好的服务接口,它的职责和对外的接口相对于内部的实现细节来说要稳定的多,并且我们要验证的正是这个类是否具备了它的职责。因此,在对类进测试时,我们应该针对类的接口来验证类是否实现了它的职责而不是其他。这样写出来的测试代码要稳定的多,也有效的多。
细想一下,造成容易陷入针对实现细节测试的原因主要是由于先实现了类,然后才去进行测试。如果先实现了类的功能,然后在去对类进行测试,潜意识中就会不由自主的想去验证已经完成的类的某种实现细节。如果能够在编写实际类前,首先编写针对该类的测试代码,情况就会有很大的不同,因为这会迫使你从类的使用者的角度去考虑问题。结果就是会把关注点放在类的易用性上,放在类的职责上面,放在类提供服务的接口上面,而不是某种实现细节。
总之,测试代码的编写应该从被测试的对象是否满足需要的层面进行,而不是其他。
误区之四:单元测试和验收测试没有什么区别
和误解之三一样,可能很多人并不承认这一点。但是他们却又不能比较清楚的说出二者的差别来。这样,在他们进行测试代码的编写时就会比较迷茫。本小节结试图给出一些区分单元测试和验收测试的一些原则来。
我们还以经常用来和软件进行类比的建筑为例,首先给大家一个感性的认识。单元测试可以类比为一个建筑的质检人员对建筑进行的检测, 他关注的重点是建筑的内部结构、地基、框架以及墙壁是否垂直等。他的检测是要保证建筑的各个部分是正常的、安全的,换句话说,就是要保证施工满足建筑上面的质量标准。验收测试可以类比为建筑的使用者来对建筑进行的检测。首先,他认为这个建筑是满足规定的工程质量的,这是有建筑的质检人员来保证的。使用者关注的重点是住在这个建筑的中的感受。他关心建筑的外观是否美观、各个房间的大小是否合适,窗户的位置是否合适,是否能够满足家庭的需要等。这里,建筑的使用者执行的就是验收测试,他是从用户的角度出发的。建筑的质检人员执行的就是单元测试,他是从构建者的角度出发的。
正是这种角度的不同决定了单元测试和验收测试之间的区别。它们是对系统的不同的方面进行的测试,二者是互相补充的。不管我们在系统的构建中使用了多么聪明的方法,不管我们的系统是多么的灵活,但是首先我们的产品必须是可用的,否则我们所做的就是浪费时间,从这一点上来说验收测试要比单元测试显得更加重要。
还以上一小节给出的案例为例,案例中所使用的测试方法仅仅是从系统是否健壮的角度出发进行的,即使系统从不崩溃也不能证明那是一个可用的系统。因为测试根本就不是从用户使用的角度出发的,测试者本应该和用户一起来编写验收测试。单元测试保证我们把事情作对,而验收测试则保证我们做正确的事情。
关于单元测试和验收测试之间的明确划分,没有一个通用的标准,只有通过自己的不断实践来增加这方面的经验。你进行的有关测试的实践越多,你就会越清晰的感觉到单元测试和验收测试之间的界限所在。下面给出一些指导原则,在你编写测试代码时可能会有帮助。
如果一个单元测试要跨越类的边界,那么它可能应该是一个验收测试
如果一个单元测试变的非常复杂,那么它可能应该是一个验收测试
如果一个单元测试经常要随着用户需求的变化而改变,那么它可能应该是一个验收测试
如果一个单元测试比它要测试的代码本身要难以编写,那么它可能应该是一个验收测试
结论
测试是用来保证软件开发过程的高效性,以及保证开发出来的软件产品的高质量和可用性的。软件开发本身就是一件非常困难的事情,这也决定了有效的测试决不是简单的依靠一些测试工具就可以进行的。在使用工具的同时,我们更要加强关于测试的培训、教育,使大家对于测试首先有一个正确的认识。只有这样,我们才能够更加有效、高效的使用工具,才能够使测试真正起到它应有的作用。希望本文能够对大家在进行测试方面的工作时有所帮助。
文章来源于领测软件测试网 https://www.ltesting.net/