2010-07-31 1 views
12

Angenommen, ich fange an, ein Spiel mit TDD zu machen. Ist das ein guter erster Test?Erster TDD-Test ohne Bestätigung/erwartete Ausnahme. Ist es das wert?

[TestMethod] 
public void Can_Start_And_End_Game() 
{ 
    Tetris tetris = new Tetris(); 
    tetris.Start(); 
    tetris.End(); 
} 

Es besteht im Wesentlichen zwingt mich drei Dinge zu definieren: die Tetris Klasse und ihre Start() und End() Methoden, aber davon abgesehen, dass es ziemlich nutzlos. Es könnte sein Interesse sofort haben, da ich mit ihnen diese Klasse und diese Methoden definieren kann, aber später wird es wahrscheinlich keinen Zweck mehr erfüllen. Sein einziger Zweck würde vielleicht zeigen, dass es möglich sein muss, ein Spiel zu beginnen und es zu beenden, ohne eine Ausnahme in der Mitte zu bekommen.

Was sind Ihre Gedanken dazu?

+0

in Java, sind Methoden nicht aktiviert. Daher 'tetris.start()' und 'tetris.end()' –

+3

Sicher. Aber in C# sind sie. –

+0

Technisch ist dies ein Integrationstest, weil Sie mehr als eine Sache testen. Sie sollten Tests für Start, Tests für End und diesen Integrationstest haben. –

Antwort

19

Es zwingt mich im Grunde drei Dinge zu definieren: die Tetris-Klasse und ihr Start() und End() Methoden,

Wahr.

aber abgesehen davon ist es ziemlich nutzlos.

Falsch.

später wird es wahrscheinlich nicht jede Art von Zweck

Falsch, auch dienen.

Seine ... Zweck [ist] zeigen, dass es möglich sein muss, um ein Spiel zu starten und beenden, ohne eine Ausnahme in der Mitte zu bekommen

Und das ist riesig. Epos. Monumental.

In der Tat wird dieser Test so oft scheitern, dass Sie es hassen werden. Jede nicht behandelte, nicht erfasste Ausnahme von allen zufälligen Stellen in Ihrem Programm wird diesen Test nicht bestehen. Sie werden aufgrund dieses Tests sorgfältige Protokollierung und Debugging erstellen.

Dieser Test ist EPIC.

+0

Wow, daran hatte ich nicht gedacht. –

+0

EPIC !!!!!!!!!!! – strager

+2

"Dieser Test ist EPIC" +1 :) – Skilldrick

1

Ich denke, dass der Zweck des Tests kann klarer gemacht werden, indem alle Ausnahmen zu kontrollieren und den Test ausdrücklich versagt, wenn es happpens:

[TestMethod] 
public void Can_Start_And_End_Game() 
{ 
    try 
    { 
     Tetris tetris = new Tetris(); 
     tetris.Start(); 
     tetris.End(); 
    } 
    catch (Exception ex) 
    { 
     Assert.Fail("Unexpected exception thrown: " + ex.ToString()); 
    } 
} 
+2

Es gibt eine Assert.DoesNotThrow-Methode, die dies tut. – strager

+0

Ist das nicht redundant wie "let x = x" oder "if (true == true)"? Ich dachte, es sei eine Xunit-Konvention, dass die "DoesNotThrow" -Idee immer implizit ist und verstanden wird, mit oder ohne Behauptungen jeglicher Art, unabhängig vom Namen der Methode. – apollodude217

3

Ich bin kein großer Fan von diesem Test. Ja, es hat geholfen, die Schnittstelle zu definieren, aber es ist nicht sehr stark für das Definieren (und Testen) von Verhalten.

Ich denke, es könnte besser sein, einen Test zu haben, der den Start behandelt. Es würde wahrscheinlich die Standardeinstellungen oder Scoring-Werte geltend machen. Dann hätte ich zusätzliche Tests, um zu sehen, ob Sie ein Spiel beenden können.

Idealerweise muss jede Testmethode ein Verhalten ausführen.

+3

+1. Ein guter Test hat eine einzige Aussage; dieser hat keinen. – TrueWill

1

Ja, der Test bestätigt, dass im Konstruktor keine Ausnahme ausgelöst wird, die Start() und die Stop() Methode.

Ich sehe wenig Wert in einem zusätzlichen try/catch-Block innerhalb des Tests, um Ausnahmen zu fangen. Das Tool, das den Test ausführt, fängt diese ab und meldet sie. Nach dem Prinzip TSTTCPW kann der Test ohne den try/catch-Block auskommen.

Sie können den Test etwas aussagekräftiger machen, indem Sie am Ende Assertionen hinzufügen, z. B. den Wert der Eigenschaften des Objekts tetris überprüfen.

Bitte beachten Sie den Unterschied zwischen dem Schreiben eines Komponententests und der Verwendung von TDD. Der Wert kommt davon, diesen Unterschied zu verstehen.

7

Mit diesem Test treiben Sie die Entwicklung der Tetris-Klasse nicht wirklich voran - Sie haben entschieden, wie die API sein soll, was in Ordnung ist, aber warum nicht einen Test schreiben, der etwas testet, was er eigentlich tun sollte?

Die Tests sollten die API informieren, nicht umgekehrt (imho).

+0

Ich denke du hast es geschafft. Aber werfen Sie auch einen Blick auf S. Lott's Antwort. –

+0

@devoured - Danke. Ich bevorzuge eigentlich S. Lott's :) – Skilldrick

1

Wie S. Lott sagte, deckt dieser Test eine TON Masse ab. Es ist so „es wert“, dass es sich lohnt, in mindestens 3 Tests Aufbrechen und das Hinzufügen von entsprechenden Behauptungen zu jeder:

[TestMethod] 
public void Test_Contructor() 
{ 
    Tetris tetris = new Tetris(); 
    // make assertions 
} 

[TestMethod] 
public void Test_Start() 
{ 
    // setup 
    Tetris tetris = new Tetris(); 

    // exercise 
    tetris.Start(); 

    // make assertions 
} 

[TestMethod] 
public void Test_End() 
{ 
    // setup 
    Tetris tetris = new Tetris(); 
    tetris.Start(); 

    // exercise 
    tetris.End(); 

    // make assertions 
}