646 Stimmen

Bewährte Verfahren zur Benennung von Einheitstests

Was sind die besten Praktiken für die Benennung von Unit-Test-Klassen und Testmethoden?

Dies wurde bereits auf SO diskutiert, unter Was sind einige gängige Namenskonventionen für Unit Tests?

Ich weiß nicht, ob dies ein sehr guter Ansatz ist, aber derzeit habe ich in meinen Testprojekten Eins-zu-Eins-Zuordnungen zwischen jeder Produktionsklasse und einer Testklasse, z. B. Product et ProductTest .

In meinen Testklassen habe ich dann Methoden mit den Namen der Methoden, die ich teste, einen Unterstrich und dann die Situation und das, was ich erwarte, z. B. Save_ShouldThrowExceptionWithNullName() .

1 Stimmen

2 Stimmen

Dies ist zwar keine Antwort auf Ihre Frage, aber es lohnt sich, es zu lesen: haacked.com/archive/2012/01/02/structuring-unit-tests.aspx

6 Stimmen

Google Style Guide sagt: test<MethodUnderTest>_<state> z.B. testPop_emptyStack google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 Methodennamen. Im Zweifelsfall sollte man Google folgen.

606voto

Marc Climent Punkte 9414

Aktualisierung (Juli 2021)

Meine ursprüngliche Antwort ist schon eine ganze Weile her (fast 12 Jahre), und die bewährten Verfahren haben sich in dieser Zeit stark verändert. Daher fühle ich mich veranlasst, meine Antwort zu aktualisieren und den Lesern verschiedene Benennungsstrategien anzubieten.

In vielen Kommentaren und Antworten wird darauf hingewiesen, dass die von mir in meiner ursprünglichen Antwort vorgeschlagene Benennungsstrategie nicht resistent gegen Refactorings ist und zu schwer verständlichen Namen führt, und ich stimme dem voll und ganz zu.

In den letzten Jahren bin ich dazu übergegangen, ein besser lesbares Benennungsschema zu verwenden, bei dem der Testname beschreibt, was wir testen wollen, und zwar in der Zeile, die durch Wladimir Chorikow .

Einige Beispiele wären:

  • Add_credit_updates_customer_balance
  • Purchase_without_funds_is_not_possible
  • Add_affiliate_discount

Wie Sie sehen, ist es ein recht flexibles Schema, aber das Wichtigste ist, dass Sie beim Lesen des Namens wissen, worum es bei dem Test geht, ohne technische Details einzubeziehen, die sich im Laufe der Zeit ändern können.

Bei der Benennung der Projekte und Testklassen halte ich mich noch an das ursprüngliche Antwortschema.

Ursprüngliche Antwort (Oktober 2009)

Ich mag Roy Osheroves Strategie der Namensgebung . Es geht um Folgendes:

[UnitOfWork_StateUnderTest_ExpectedBehavior]

Sie enthält alle erforderlichen Informationen über den Namen der Methode und in strukturierter Form.

Die Arbeitseinheit kann so klein wie eine einzelne Methode, eine Klasse oder so groß wie mehrere Klassen sein. Sie sollte alle Dinge repräsentieren, die in diesem Testfall getestet werden sollen und unter Kontrolle sind.

Für Baugruppen verwende ich die typische .Tests Endung, die meines Erachtens recht weit verbreitet ist, und die gleiche für Klassen (die mit Tests ) :

[NameOfTheClassUnderTestTests]

Früher habe ich Fixture als Suffix anstelle von Tests verwendet, aber ich denke, letzteres ist gebräuchlicher, also habe ich die Benennungsstrategie geändert.

258 Stimmen

Für mich macht es keinen Sinn, den Methodennamen in die Testmethode aufzunehmen. Was ist, wenn Sie die Methode umbenennen? Kein Refactoring-Tool wird Tests für Sie umbenennen. Letzten Endes muss man die Testmethoden von Hand umbenennen oder hat wahrscheinlich falsch benannte Tests. Es ist wie mit den Kommentaren. Zu viel ist schlimmer, als gar keinen Code zu kommentieren.

4 Stimmen

@Peri: Sehr aufschlussreich. Das gleiche Problem tritt mit dem Klassennamen auf. Hypothetisch wäre es möglich, Tests in eine private verschachtelte Klasse mit dem Namen "Test" zu packen, aber kein Unit-Test-Framework unterstützt dies, und die meisten Programmierer weigern sich, Unit-Test-Code zu versenden. Ich habe einmal einen Unit-Test geschrieben, der alle Unit-Tests reflektiert und sicherstellt, dass sie korrekt benannt sind, aber dieser Code ist verloren gegangen.

96 Stimmen

@Peri, ich denke, es ist ein Kompromiss. Einerseits können Ihre Testnamen veraltet sein, andererseits können Sie nicht sagen, welche Methode Ihr Test testet. Ich finde, dass letzteres viel häufiger vorkommt.

151voto

Jack Ukleja Punkte 12596

Ich verfolge gerne die "Sollte" Benennungsstandard für Tests bei der Benennung der Prüfvorrichtung nach der zu testenden Einheit (d. h. der Klasse).

Zur Veranschaulichung (mit C# und NUnit):

[TestFixture]
public class BankAccountTests
{
  [Test]
  public void Should_Increase_Balance_When_Deposit_Is_Made()
  {
     var bankAccount = new BankAccount();
     bankAccount.Deposit(100);
     Assert.That(bankAccount.Balance, Is.EqualTo(100));
  }
}

Warum "Sollte" ?

Ich finde, dass es die Testautoren dazu zwingt, den Test mit einem Satz zu benennen, der in etwa so lautet: "Sollte [in irgendeinem Zustand sein] [nach/vor/wenn] [Aktion findet statt]".

Ja, wenn man überall "sollte" schreibt, wird es ein bisschen repetitiv, aber wie ich schon sagte, zwingt es die Schreiber, auf die richtige Art und Weise zu denken (was für Anfänger gut sein kann). Außerdem führt es im Allgemeinen zu einem lesbaren englischen Testnamen.

Update :

Ich habe bemerkt, dass Jimmy Bogard auch ein Fan von 'should' ist und sogar eine Unit-Test-Bibliothek namens Sollte .

Update (4 Jahre später...)

Für diejenigen, die es interessiert: Meine Herangehensweise an die Benennung von Tests hat sich im Laufe der Jahre weiterentwickelt. Eines der Probleme mit dem Sollte Muster, das ich oben beschrieben habe, da es nicht einfach ist, auf einen Blick zu erkennen, welche Methode getestet wird. Für OOP halte ich es für sinnvoller, den Testnamen mit der zu testenden Methode zu beginnen. Bei einer gut konzipierten Klasse sollte dies zu lesbaren Testmethodennamen führen. Ich verwende jetzt ein ähnliches Format wie <method>_Should<expected>_When<condition> . Je nach Kontext kann es sinnvoll sein, die Verben "sollte" und "wenn" durch etwas Passenderes zu ersetzen. Beispiel: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()

46 Stimmen

Noch besser und weniger redundant wäre es, einen Satz zu schreiben, der erklärt, was der Test bewirkt, vorausgesetzt, er funktioniert: increasesBalanceWhenDepositIsMade() .

3 Stimmen

Kürzlich sah ich einen Artikel, in dem eine ähnliche Namenskonvention erwähnt wurde (ich wünschte, ich hätte ihn als Lesezeichen gespeichert). Sie wurde entwickelt, um die Listen der Tests sehr lesbar zu machen, wenn sie nach Testvorrichtung sortiert sind. Sie sehen etwas wie "BankAccount" und darunter (in verschiedenen Zeilen) "Should_Increase_Balance_When_Deposit_Is_Made" "Should_Decrease_Balance_When_Withdrawal_Is_Made" usw. Liest sich sehr wie eine Spezifikation, und darum geht es bei TDD ja auch.

0 Stimmen

Ich habe den Artikel gefunden. Er steht im CodeThinked-Blog von Justin Etheredge Einführung in Mocking mit Moq 3 - Teil 1 .

89voto

Sklivvz Punkte 29602

Ich mag diese Art der Namensgebung:

OrdersShouldBeCreated();
OrdersWithNoProductsShouldFail();

und so weiter. So wird auch einem Nicht-Tester klar, wo das Problem liegt.

64 Stimmen

Aber @hotshot309, er benutzt vielleicht .NET - .NET-Kapitalisierungskonventionen

2 Stimmen

@Ace, ich stimme Ihnen vollkommen zu und bemerkte dies etwa eine Minute, nachdem ich diesen Kommentar abgegeben hatte. Ich habe geschworen, dass ich ihn gelöscht habe, als ich meinen Fehler sah, aber irgendwie habe ich das wohl nicht getan. Das tut mir leid.

0 Stimmen

Warum trennst du das dann nicht mit Unterstrichen? Du verwendest das gleiche Muster wie Roy O.

56voto

Sergio Acosta Punkte 11210

Kent Beck schlägt vor:

  • Eine Prüfvorrichtung pro "Einheit" (Klasse Ihres Programms). Testfixtures sind selbst Klassen. Der Name der Testfixture sollte lauten:

    [name of your 'unit']Tests
  • Testfälle (die Methoden der Testvorrichtungen) haben Namen wie:

    test[feature being tested]

Zum Beispiel, wenn Sie die folgende Klasse haben:

class Person {
    int calculateAge() { ... }

    // other methods and properties
}

Eine Testvorrichtung wäre das:

class PersonTests {

    testAgeCalculationWithNoBirthDate() { ... }

    // or

    testCalculateAge() { ... }
}

5 Stimmen

Ich wünschte, mehr Menschen würden diese Leitlinien befolgen. Vor nicht allzu langer Zeit musste ich mehr als 20 Testmethoden umbenennen, weil sie Namen wie "ATest", "BasicTest" oder "ErrorTest" hatten.

91 Stimmen

Wird das Methodenpräfix "test" angesichts des Suffixes der Klasse nicht überflüssig?

0 Stimmen

Ich möchte die Kompatibilität zu TestDox hinzufügen. agiledox.sourceforge.net

19voto

grundoon Punkte 235

Namen der Klassen . Was die Namen von Testvorrichtungen angeht, so finde ich, dass "Test" in der allgegenwärtigen Sprache vieler Bereiche recht verbreitet ist. Zum Beispiel in einem technischen Bereich: StressTest und in einem Kosmetikbereich: SkinTest . Tut mir leid, dass ich Kent widerspreche, aber die Verwendung von "Test" in meinen Testvorrichtungen ( StressTestTest ?) ist verwirrend.

"Einheit" wird auch häufig in Domänen verwendet. Z.B.. MeasurementUnit . Ist eine Klasse namens MeasurementUnitTest eine Prüfung von "Measurement" oder "MeasurementUnit"?

Deshalb verwende ich gerne das Präfix "Qa" für alle meine Testklassen. Z.B.. QaSkinTest y QaMeasurementUnit . Es wird nie mit Domänenobjekten verwechselt, und die Verwendung eines Präfixes anstelle eines Suffixes bedeutet, dass alle Testfixtures visuell zusammengehören (nützlich, wenn Sie Fakes oder andere Unterstützungsklassen in Ihrem Testprojekt haben)

Namespaces . Ich arbeite in C# und ich halte meine Testklassen im selben Namespace wie die Klasse, die sie testen. Das ist praktischer als getrennte Test-Namespaces zu haben. Natürlich befinden sich die Testklassen in einem anderen Projekt.

Namen der Prüfmethoden . Ich nenne meine Methoden gerne WhenXXX_ExpectYYY. Das macht die Vorbedingung klar und hilft bei der automatischen Dokumentation (a la TestDox). Dies ähnelt den Ratschlägen im Google Testing Blog, allerdings mit einer stärkeren Trennung von Vorbedingungen und Erwartungen. Zum Beispiel:

WhenDivisorIsNonZero_ExpectDivisionResult
WhenDivisorIsZero_ExpectError
WhenInventoryIsBelowOrderQty_ExpectBackOrder
WhenInventoryIsAboveOrderQty_ExpectReducedInventory

0 Stimmen

Sie sprachen über Namen von Testmethoden und Testvorrichtungen. Namen von Testvorrichtungen werden auf Produktionsklassen abgebildet. Wo schreiben Sie den Namen der Produktionsmethode in Ihren Test?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X