|
我曾经在CSDN上看到过一个帖子,就是单元测试中的黑盒测试。当时作者的大意就是将一个要被测试的函数或者接口,从这个函数的功能去考虑,而不一定完全考虑这个函数的内在逻辑。
我在做单元测试的时候,遇到过一个这样的问题。就是说单元测试如果仅仅从逻辑或者路径等方面考虑的话,确实会有些不足。出现用例不全面的情况。
举个例子吧,用C++
比如说有这样的字符串,A=B或者A = B,我要转化成(A,B)这样的pair并且保存入map中
void f(const CString& strLine, CString& strLeft, CString& strRight)
{
int nPos = strLine.find('='); // 查找=
strLeft = strLine.Left(nPos); // 得到等号左边的字符串
strRight = strLine.Right(strLine.GetLength() - nPos - 1); // 得到等号右边的字符串
strLeft = strLeft.Trim(); // 除去左边字符串前后空格
strRight = strRight.Trim(); // 除去右边字符串前后的空格
}
比如说这个很简单的函数,我设计用例的话,那么只准备一个字符串A=B,就可以做到100%的路径覆盖,但是如果只有这一个case,那么仍然是不足的,因为实际上会有两种字符串。
因为我曾经遇到过这样的bug,即上个函数,最后两行,开发漏掉了
strLeft = strLeft.Trim(); // 除去左边字符串前后空格
strRight = strRight.Trim(); // 除去右边字符串前后的空格
如果上面的函数缺少最后两行,那么可以正确解析A=B,但是不能解析A = B。但是他提供的case只有A=B一个,缺少A = B,所以这个测试用例执行通过了。
好在最后在系统测试中发现了问题,没有铸成大错。
所以如果只看覆盖情况的话,是可以达到100%的覆盖,但实际上却并不完善,有很大的漏洞。
如果从功能的角度,就可以弥补这一点。比如说事先知道会处理这两种字符串,那么这样就可以设计两个case。
而且在实际中做单元测试的时候,发现在底层的测试是可以做到路径或者逻辑的很好的覆盖率,然而一旦到了上面,即越来越趋向集成测试的时候,类特别多,这时候做一些覆盖比较困难,当时我就主要是采取黑盒测试的想法。当然前提是底层的这些类的接口或者函数都做过非常全面的单元测试。 |
|