webentwicklung-frage-antwort-db.com.de

Best Practices für die Benennung von Komponententests

Was sind die Best Practices für die Benennung von Unit-Testklassen und Testmethoden?

Dies wurde am SO vorher um Was sind einige beliebte Namenskonventionen für Unit-Tests? besprochen

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. Product und ProductTest.

In meinen Testklassen habe ich dann Methoden mit den Namen der Methoden, die ich teste, einem Unterstrich und dann der Situation und dem, was ich erwarten würde, z. Save_ShouldThrowExceptionWithNullName().

516

Ich mag Roy Osheroves Namensstrategie , es ist die folgende:

[UnitOfWork_StateUnderTest_ExpectedBehavior]

Es enthält alle erforderlichen Informationen zum Methodennamen und ist strukturiert.

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

Für Baugruppen verwende ich das typische .Tests Endung, die meiner Meinung nach ziemlich weit verbreitet ist und auch für Klassen gilt (Endung mit Tests):

[NameOfTheClassUnderTestTests]

Früher habe ich Fixture als Suffix anstelle von Tests verwendet, aber ich denke, dass letzteres häufiger vorkommt, dann habe ich die Benennungsstrategie geändert.

475
Marc Climent

Ich folge gerne dem "Sollte" Benennungsstandard für Tests, während ich die Testvorrichtung benenne nach dem Prüfling (dh 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 zwingt, den Test mit einem Satz nach dem Motto "Sollte [in einem bestimmten Zustand sein] [nach/vor/wann] [Handlung stattfindet]" zu benennen.

Ja, das Schreiben von "Sollte" wiederholt sich zwar überall, aber wie gesagt, zwingt es die Autoren, richtig zu denken (kann also für Anfänger gut sein). Außerdem führt dies in der Regel zu einem lesbaren englischen Testnamen.

Update:

Ich habe bemerkt, dass Jimmy Bogard auch ein Fan von "sollte" ist und sogar eine Unit-Test-Bibliothek namens Should hat.

Update (4 Jahre später ...)

Für Interessenten hat sich mein Ansatz zur Benennung von Tests im Laufe der Jahre weiterentwickelt. Eines der Probleme mit dem Sollte Muster, das ich oben beschrieben habe, ist es nicht einfach, auf einen Blick zu erkennen, welche Methode getestet wird. Für OOP Ich halte es für sinnvoller, den Testnamen mit der zu testenden Methode zu beginnen. Für eine gut gestaltete Klasse sollte dies zu lesbaren Testmethoden-Namen führen. Ich verwende jetzt ein Format ähnlich <method>_Should<expected>_When<condition>. Natürlich möchten Sie je nach Kontext die Should/When-Verben durch etwas passenderes ersetzen. Beispiel: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()

102
Schneider

Ich mag diesen Benennungsstil:

OrdersShouldBeCreated();
OrdersWithNoProductsShouldFail();

und so weiter. Es macht einem Nicht-Tester wirklich klar, worin das Problem besteht.

75
Sklivvz

Kent Beck schlägt vor:

  • Eine Testvorrichtung pro 'Einheit' (Klasse Ihres Programms). Test Fixtures sind Klassen. Der Name der Testvorrichtung sollte lauten:

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

    test[feature being tested]
    

Zum Beispiel mit der folgenden Klasse:

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

    // other methods and properties
}

Eine Testvorrichtung wäre:

class PersonTests {

    testAgeCalculationWithNoBirthDate() { ... }

    // or

    testCalculateAge() { ... }
}
49
Sergio Acosta

Klassennamen. Bei den Namen von Testgeräten finde ich, dass "Test" in der allgegenwärtigen Sprache vieler Domänen häufig vorkommt. Zum Beispiel in einer technischen Domäne: StressTest und in einer kosmetischen Domäne: SkinTest. Es tut mir leid, Kent nicht zuzustimmen, aber die Verwendung von "Test" in meinen Testgeräten (StressTestTest?) Ist verwirrend.

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

Deshalb verwende ich für alle meine Testklassen gerne das Präfix "Qa". Z.B. QaSkinTest und QaMeasurementUnit. Es wird nie mit Domänenobjekten verwechselt, und die Verwendung eines Präfixes anstelle eines Suffixes bedeutet, dass alle Test-Fixtures visuell zusammenleben (nützlich, wenn Sie Fälschungen oder andere Support-Klassen in Ihrem Testprojekt haben).

Namespaces. Ich arbeite in C # und behalte meine Testklassen im gleichen Namespace wie die Klasse, die sie testen. Dies ist praktischer als separate Testnamespaces. Natürlich befinden sich die Testklassen in einem anderen Projekt.

Name der Testmethode. Ich möchte meine Methoden WhenXXX_ExpectYYY nennen. Es verdeutlicht die Voraussetzung und hilft bei der automatisierten Dokumentation (a la TestDox). Dies ist vergleichbar mit den Hinweisen im Google-Testblog, jedoch mit einer stärkeren Trennung von Voraussetzungen und Erwartungen. Zum Beispiel:

WhenDivisorIsNonZero_ExpectDivisionResult
WhenDivisorIsZero_ExpectError
WhenInventoryIsBelowOrderQty_ExpectBackOrder
WhenInventoryIsAboveOrderQty_ExpectReducedInventory
17
grundoon

Ich verwende das Given-When-Then Konzept. Schauen Sie sich diesen kurzen Artikel an http://cakebaker.42dh.com/2009/05/28/given-when-then/ . Artikel beschreibt dieses Konzept in Bezug auf BDD, aber Sie können es auch in TDD ohne Änderungen verwenden.

10
Pashec

Siehe: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html

Für Namen von Testmethoden finde ich die Verwendung von ausführlichen und selbstdokumentierten Namen sehr nützlich (neben Javadoc-Kommentaren, die weiter erläutern, was der Test tut).

8
Ates Goral

Ich habe mir kürzlich die folgende Konvention ausgedacht, um meine Tests, ihre Klassen und enthaltenen Projekte zu benennen, um ihre Beschreibung zu maximieren:

Nehmen wir an, ich teste die Klasse Settings in einem Projekt im Namespace MyApp.Serialization.

Zuerst erstelle ich ein Testprojekt mit dem Namespace MyApp.Serialization.Tests.

In diesem Projekt und natürlich im Namespace werde ich eine Klasse namens IfSettings (gespeichert als IfSettings.cs) erstellen.

Nehmen wir an, ich teste die SaveStrings () -Methode. -> Ich werde den Test benennen CanSaveStrings ().

Wenn ich diesen Test durchführe, wird die folgende Überschrift angezeigt:

MyApp.Serialization.Tests.IfSettings.CanSaveStrings

Ich denke das sagt mir sehr gut, was es testet.

Natürlich ist es nützlich, dass im Englischen das Substantiv "Tests" dasselbe ist wie das Verb "tests".

Der Kreativität bei der Benennung der Tests sind keine Grenzen gesetzt, sodass wir vollständige Satzüberschriften für sie erhalten.

Normalerweise müssen die Testnamen mit einem Verb beginnen.

Beispiele beinhalten:

  • Erkennt (z. B. DetectsInvalidUserInput)
  • Würfe (z. B. ThrowsOnNotFound)
  • Will (z. B. WillCloseTheDatabaseAfterTheTransaction)

usw.

Eine andere Option ist die Verwendung von "that" anstelle von "if".

Letzteres spart mir allerdings Tastatureingaben und beschreibt genauer, was ich tue, da ich nicht weiß, das das getestete Verhalten ist vorhanden, aber testet - if es ist.

[ Edit]

Nachdem ich die obige Namenskonvention nun etwas länger verwendet habe, habe ich festgestellt, dass das Präfix If bei der Arbeit mit Schnittstellen verwirrend sein kann. Es ist nur so, dass die Testklasse IfSerializer.cs der Schnittstelle ISerializer.cs im "Open Files Tab" sehr ähnlich sieht. Dies kann beim Hin- und Herwechseln zwischen den Tests, der getesteten Klasse und ihrer Schnittstelle sehr ärgerlich werden. Als Ergebnis würde ich jetzt That anstelle von If als Präfix wählen.

Außerdem benutze ich jetzt - nur für Methoden in meinen Testklassen, da dies nirgendwo sonst als Best Practice angesehen wird - das "_", um Wörter in meinen Testmethoden-Namen wie folgt zu trennen:

  • [Test] public void erkennt_invalid_User_Input () *

Ich finde das leichter zu lesen.

[ Edit beenden]

Ich hoffe, dass dies weitere Ideen hervorbringt, da ich die Benennung von Tests für sehr wichtig halte, da dies Ihnen viel Zeit ersparen kann, die Sie sonst aufgewendet hätten, um zu verstehen, was die Tests tun (z. B. nach Wiederaufnahme eines Projekts nach einer längeren Unterbrechung). .

7
Thorsten Lorenz

Ich denke, eines der wichtigsten Dinge ist, dass Ihre Namenskonvention konsistent ist (und dass Sie es mit anderen Mitgliedern Ihres Teams vereinbaren). Zu oft sehe ich eine Menge verschiedener Konventionen, die im selben Projekt verwendet werden.

7
bytedev

In VS + NUnit erstelle ich normalerweise Ordner in meinem Projekt, um Funktionstests zu gruppieren. Dann erstelle ich Unit-Test-Fixture-Klassen und benenne sie nach der Art der Funktionalität, die ich teste. Die [Test] -Methoden sind in Anlehnung an Can_add_user_to_domain:

- MyUnitTestProject   
  + FTPServerTests <- Folder
   + UserManagerTests <- Test Fixture Class
     - Can_add_user_to_domain  <- Test methods
     - Can_delete_user_from_domain
     - Can_reset_password
2
Kev

Ich sollte hinzufügen, dass das Beibehalten Ihrer Tests im selben Paket, jedoch in einem parallelen Verzeichnis zur zu testenden Quelle, das Aufblähen des Codes beseitigt, sobald Sie bereit sind, ihn bereitzustellen, ohne eine Reihe von Ausschlussmustern ausführen zu müssen.

Ich persönlich mag die in "JUnit Pocket Guide" beschriebenen Best Practices. Es ist schwer, ein Buch zu schlagen, das vom Co-Autor von JUnit geschrieben wurde!

2
Steve Moyer

der Name des Testfalls für die Klasse Foo sollte FooTestCase oder so ähnlich lauten (FooIntegrationTestCase oder FooAcceptanceTestCase) - da es sich um einen Testfall handelt. Unter http://xunitpatterns.com/ finden Sie einige Standardbenennungskonventionen wie Test, Testfall, Testvorrichtung, Testmethode usw.

0
Ray Tayek