add by zhj:没找到原文
黑盒测试是从用户的角度针对功能及外部结构进行测试,而不考虑程序内部逻辑结构。白盒测试只关注程序的内部逻辑,会通过语句覆盖,分支覆盖等去测试,它不关心程序对用户而言实现的功能。黑盒与白盒的主要区分是,前者是从使用者的角度去测试,后者不关心程序的功能,它只关心内部的逻辑。单元测试如果仅仅从逻辑或者路径等方面考虑的话(即白盒测试),确实会有些不足。出现用例不全面的情况。
比如说有这样的字符串,A=B或者A = B,我要将A和B取出来
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。
而且在实际中做单元测试的时候,发现在底层的测试是可以做到路径或者逻辑的很好的覆盖率,然而一旦到了上面,即越来越趋向集成测试的时候,类特别多,这时候做一些覆盖比较困难,当时我就主要是采取黑盒测试的想法。当然前提是底层的这些类的接口或者函数都做过非常全面的单元测试。