2012-04-12 3 views
5

F: Wie erkennt man eine echte Testabdeckung?Abdeckung gegen erreichbaren Code

Ich habe ein Problem mit Code Coverage Metrik und Testqualität festgestellt: 100% Codeabdeckung bedeutet nicht, dass Code wirklich getestet wird.

Manchmal gibt Test 100% Deckung sogar, dass es nicht alles abdeckt. Das Problem liegt in der Definition der Abdeckung, wir gehen davon aus, Abdeckung == erreichbar Code.

Aber es ist nicht wahr, Code könnte zu 100% erreichbar sein, aber nicht zu 100% mit dem Test abgedeckt.

Werfen Sie einen Blick in Beispiel, dieser Test gibt 100% Abdeckung (EMMA), aber in Wirklichkeit deckt es nicht Werte, die an Service-Schein übergeben werden. Wenn also der Wert geändert wird, wird der Test nicht fehlschlagen.

Beispiel:

public class User { 
    public static final int INT_VALUE = 1; 
    public static final boolean BOOLEAN_VALUE = false; 
    public static final String STRING_VALUE = ""; 
    private Service service; 

    public void setService(Service service) { 
     this.service = service; 
    } 

    public String userMethod() { 
     return service.doSomething(INT_VALUE, BOOLEAN_VALUE, STRING_VALUE); 
    } 
} 

Und zu testen:

public class UserTest { 

    private User user; 
    private Service easyMockNiceMock; 

    @Before 
    public void setUp() throws Exception { 
     user = new User(); 
     easyMockNiceMock = EasyMock.createNiceMock(Service.class); 
    } 

    @Test 
    public void nonCoverage() throws Exception { 
     // given 
     user.setService(easyMockNiceMock); 
     expect(easyMockNiceMock.doSomething(anyInt(), anyBoolean(), (String) anyObject())).andReturn(""); 
     replay(easyMockNiceMock); 
     // when 
     user.userMethod(); 
     // then 
     verify(easyMockNiceMock); 
    } 
} 

Antwort

4

Werfen Sie einen Blick auf Jester, die mutation testing führt. Von der Seite:

Jester findet Code, der nicht durch Tests abgedeckt wird. Jester macht einige Änderung an Ihrem Code, führt Ihre Tests, und wenn die Tests bestanden Jester zeigt eine Nachricht, die besagt, was es geändert hat. Jester enthält ein Skript zum Generieren von Webseiten, die die vorgenommenen Änderungen anzeigen, die nicht dazu geführt haben, dass die Tests fehlgeschlagen sind.

Jester unterscheidet sich von Code-Coverage-Tools, da er den Code finden kann, der beim Ausführen von Tests ausgeführt wird, aber nicht tatsächlich getestet wird. Jester Ansatz wird Mutationstest oder automatisierten Fehler Seeding genannt. Jester ist jedoch nicht als Ersatz für die Code-Tools gedacht, sondern lediglich als ergänzender Ansatz.

+0

Schade, dass es für die aktuelle Version von .net nicht funktioniert. Ich hätte es gerne für eine Runde genommen. – Gishu

+0

Ich habe versucht, über Mutationsframeworks zu googlen, aber keiner von ihnen hat Integration mit IDE (vorzugsweise IDEA). –

+0

Jester nahm einen ziemlich naiven Ansatz für Mutationstests und war daher eiszeitlich langsam. Wenn Sie sich Mutationstests ansehen, können Sie ein moderneres System ausprobieren, wie zum Beispiel http://pitest.org oder javalanche – henry

2

100% Abdeckung hat noch nie 100% getestet bedeutet, und jeder, der behauptet hat, hat es entweder nicht verstanden oder belügt. Die Coverage-Messung misst einfach, welcher Produktcode während des Tests ausgeführt wurde. Es gibt Dutzende von Möglichkeiten, Tests zu schreiben, die eine 100% ige Abdeckung erzielen, und dann Ihren Code nicht vollständig zu testen.

Die einfachste Möglichkeit besteht darin, einen Test zu schreiben, der die Produktfunktion aufruft und dann keine Aussagen über den Rückgabewert macht!

Hier ist ein Blogbeitrag, den ich über dieses Thema schrieb: Flaws in Coverage Measurement, es ist Python-centric, aber die Konzepte sind alle gleich.

+1

Coverage sagt Ihnen genau eins: was _nicht_ getestet wurde. Wenn ich auf ein Coverage-Diagramm schaue, ist mir egal, was grün ist, mir ist wichtig, was rot ist. –