2012-03-04 53 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