Frage

Ich verwende derzeit eine einfache Konvention für meine Unit-Tests. Wenn ich eine Klasse „EmployeeReader“ genannt, erstelle ich eine Testklasse mit dem Namen „EmployeeReader.Tests ich dann für die Klasse in der Testklasse mit Namen alle Tests erstellen, wie:.

  • Reading_Valid_Employee_Data_Correctly_Generates_Employee_Object
  • Reading_Missing_Employee_Data_Throws_Invalid_Employee_ID_Exception

und so weiter.

Ich habe das Lesen vor kurzem über eine Konvention der Namensgebung in BDD verwendet. Ich mag die Lesbarkeit dieser Namensgebung, mit einer Liste von Tests, um am Ende so etwas wie:

  • When_Reading_Valid_Employee (Halterung)
    • Employee_Object_Is_Generated (Methode)
    • Employee_Has_Correct_ID (Methode)
  • When_Reading_Missing_Employee (Halterung)
    • An_Invalid_Employee_ID_Exception_Is_Thrown (Methode)

und so weiter.

Hat jemand verwendet beide Stile der Namensgebung? Können Sie irgendwelche Ratschläge bieten, Vorteile, Nachteile, gotchas usw. mir zu helfen, zu entscheiden, ob für mein nächstes Projekt wechseln oder nicht?

War es hilfreich?

Lösung

Ihr zweites Beispiel (mit einer Halterung für jede logische „Aufgabe“, anstatt ein für jede Klasse) hat den Vorteil, dass Sie verschiedene Auf- und Abbau Logik für jede Aufgabe haben können, damit Ihre individuellen Prüfverfahren vereinfachen und sie mehr lesbar.

Sie brauchen nicht auf dem einen oder anderen als Standard zu begleichen. Wir verwenden eine Mischung aus beidem, je nachdem, wie viele andere „Aufgaben“ haben wir für jede Klasse zu testen.

Andere Tipps

Die Namenskonvention Ich habe mit ist:

  

functionName_shouldDoThis_whenThisIsTheSituation

Zum Beispiel, diese würden für ein ‚Pop‘ Funktion Stack einige Testnamen sein

  

pop_shouldThrowEmptyStackException_whenTheStackIsEmpty

     

pop_shouldReturnTheObjectOnTheTopOfTheStack_whenThereIsAnObjectOnTheStack

Ich fühle mich der zweite ist besser, weil es Ihr Gerät macht den anderen Tests besser lesbar als lange Linien der Code aussehen desto schwieriger ist es zu lesen oder erschweren zu überfliegen. Wenn Sie immer noch das Gefühl gibt irgendeine Zweideutigkeit als für das, was der Test funktioniert, können Sie Kommentare hinzufügen, dies zu klären.

Ein Teil der Argumentation hinter der zweiten Namenskonvention auf die Sie verweisen, dass Sie Tests und Verhaltensspezifikationen zur gleichen Zeit schaffen. Sie stellen den Kontext, in dem Dinge geschehen und was sollte eigentlich dann in diesem Kontext geschehen. (Nach meiner Erfahrung, die Beobachtungen / Test-Methoden oft mit Start "should_", so dass Sie einen Standard "When_the_invoicing_system_is_told_to_email_the_client," get "should_initiate_connection_to_mail_server" -Format.)

Es gibt Tools, die über Ihre Prüfvorrichtungen und Ausgang eine schön formatierte HTML-Datenblatt, Strippen die Unterstrichen widerspiegeln. Am Ende haben Sie die Menschen lesbare Dokumentation auf, die synchron mit dem eigentlichen Code ist (solange Sie Ihre Testabdeckung hoch und präzise halten).

In Abhängigkeit von der Geschichte / Feature / Subsystem, auf das Sie arbeiten, können diese Spezifikationen zu und durch Nicht-Programmierer Beteiligten zur Überprüfung und Feedback verstanden gezeigt werden, die im Herzen der agilen und BDD insbesondere ist.

Ich verwende zweite Methode, und es hilft wirklich mit zu beschreiben, was die Software tun sollte. Ich benutze auch verschachtelte Klassen ausführlichere Kontext zu beschreiben.

Im Wesentlichen sind Testklassen Kontexte, die verschachtelt werden können, und Methoden sind alle eine Zeile Behauptungen. Zum Beispiel:

public class MyClassSpecification
{
    protected MyClass instance = new MyClass();

    public class When_foobar_is_42 : MyClassSpecification 
    {
        public When_foobar_is_42() {
            this.instance.SetFoobar( 42 ); 
        }

        public class GetAnswer : When_foobar_is_42
        {
            private Int32 result;

            public GetAnswer() {
                this.result = this.GetAnswer();
            }

            public void should_return_42() {
                Assert.AreEqual( 42, result );
            }
        }
    }
}

, die mir gibt in meinem Test-Läufer folgende Ausgabe:

MyClassSpecification+When_foobar_is_42+GetAnswer
    should_return_42

Ich habe die beiden Straßen gewesen unten Sie in Ihrer Frage beschreiben sowie ein paar andere ... Ihre erste Alternative ist ziemlich geradlinig und einfach für die meisten Menschen zu verstehen. Ich mag persönlich den BDD Stil (Ihr zweites Beispiel) mehr, weil es unterschiedliche Kontexte und Gruppen Beobachtungen auf diesen Kontexten isoliert. Th einziger wirklicher Nachteil ist, dass es mehr Code so beginnen erzeugt, es zu tun fühlt sich etwas umständlicher, bis Sie die ordentlich Tests zu sehen. Auch wenn Sie Vererbung Befestigung Setup wiederverwenden möchten Sie eine testrunner, die die Vererbungskette ausgibt. Betrachten wir eine Klasse „An_empty_stack“ und Sie wollen es wieder zu verwenden, so dass Sie dann eine andere Klasse tun: „When_five_is_pushed_on: An_empty_stack“ Sie wollen, dass als Ausgangs und nicht nur „When_five_is_pushed_on“. Wenn Ihr testrunner dies nicht unterstützt Ihre Tests enthalten redundante Informationen wie: „When_five_is_pushed_on_empty_stack: An_empty_stack“. Nur die Ausgabe schön zu machen

ich wähle den Testfall-Klasse für den Aufruf: EmployeeReaderTestCase und die Methoden () aufrufen, wie http: // xunitpatterns. com / Organization.html und http://xunitpatterns.com/Organization. html # Test% 20Naming% 20Conventions

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top