2012-03-04 66 views
4

我用一个具体的例子说明了一个普遍的问题。 当所有组件对象都已经过测试时,您会推荐多少测试组合对象?组件已经测试时测试复合对象 - >冗余?

作为一个具体的例子,考虑下面的NullTerminatedStringReader。它从bytebuffer中读取一个以空字符结尾的字符串。为此,它使用Javas Charset解码器。

我当然想测试我的NullTerminatedStringReader。它应该能够读取各种字符串,如UTF8,UTF16,ASCII等。

想象一下,我编写了CharsetDecoder并测试了它可以解码来自各种可能字符集的字符。它真的很好的测试和尝试,我毫不怀疑它的工作原理。现在我编写一个使用CharsetDecoder的NullTerminatedStringReader。理论上我希望NullTerminatedStringReader能够处理CharsetDecoder可以解码的所有字符串。如果我使用TDD我想开我的设计,所以我就写了很多的测试,测试每个字符集解码为NullTerminatedStringReader:

... 
void testNullTerminatedStringReaderCanDecodeUTF8String() 
void testNullTerminatedStringReaderCanDecodeASCIIString() 
... 

但是,这似乎是多余的,因为在测试CharsetDecoder我拥有所有这些测试:

... 
void testCharsetDecoderCanDecodeUTF8Char() 
void testCharsetDecoderCanDecodeASCIIChar() 
... 

我不知道这里做什么,因为没有为NullTerminatedStringReader测试,我怎么能驾驶它的设计支持所有这些解码的?我是否在NullTerminatedStringReader的错误级别上测试?如果我不做测试,它似乎也有些东西丢失,因为理论上我知道NullTerminatedStringReader正在使用CharsetDecoder,我知道它所做的只是附加字符来形成一个字符串,所以没有太多可以在这里出错的地方。如果CharsetDecoder工作,那么应该是NullTerminatedStringReader。但是如果它不使用CharsetDecoder呢 - 我认为更清楚的是假定对NullTerminatedStringReader的实现没有任何知识,然后编写测试,但是这会导致看起来像多余的测试。dillema?你打赌。

class NullTerminatedStringReader 
{ 
    private Charset charset; 

    public String read(ByteBuffer buffer) 
    { 
     StringBuilder sb = new StringBuilder(); 
     while (true) 
     { 
      char charVal = readChar(buffer, charset.newDecoder()); // unicode char, possibly span several bytes 
      if (charVal == '\0') 
       break; 
      sb.append(charVal); 
     } 

     return sb.toString(); 
    } 

    private char readChar(ByteBuffer buffer, CharsetDecoder decoder) {...} 
} 

回答

1

当测试复合宾语我一般只测试了两两件事:

  • 它支持复合终端到终端的使用情况,它是专为?
  • 复合对象添加的任何增量功能是否工作?

一般来说,我不会全面测试子对象,因为他们应该有自己的测试用例来做到这一点。即你应该假设你自己的子对象工作,就像你假设java.util.ArrayList有效。

所以在你的NullTerminatedStringReader的例子中,我可能只会测试它与一个或两个替代字符集(即证明它正在调用正确的CharsetDecoder)并且相信CharsetDecoder已经足够好的测试来工作了所有其他的字符集。

1

我认为你可以考虑这种情况作为某种集成测试:为了应付复杂性,你是模块化的。对于这一点,你

  • 需要知道组件的contract您重新使用(你在readChar使用CharsetDecoder的前置和后置条件),让您的NullTerminatedStringReader可以使用一些其他组件履行合同。但是你不需要知道你正在使用CharsetDecoder实现。
  • 无需重新测试您重新使用的组件的功能:只要您满足前提条件,就可以简单地假定后置条件。
  • 使用TDD的这些先决条件驱动您的NullTerminatedStringReader设计,但您可以假设后置条件成立。并且使用TDD的后置条件来推动你的设计的某些实现,例如CharsetDecoder,如果你仍然需要创建它。但为此,你可以假定前提条件将得到满足。
+0

术语是有争议的,但我认为是跨越流程边界的集成测试 - 例如,与远程Web服务,数据库甚至本地文件系统交谈。我会考虑在同一过程中测试多个类的组件测试。 – bryanbcook 2012-03-04 17:07:44

+0

是的,你说的对,bryanbcook,集成测试有这个内涵,并不适合。我的意思是测试两个组件的集成。不幸的是,我不认为“成分测试”是合适的,因为它通常具有隔离测试每个组件的意义,没有交互需要测试。 ISTQB将“组件测试”定义为单元测试的同义词,所以这也不是我想表达的内容。任何其他术语建议表示赞赏! – DaveFar 2012-03-04 18:44:59