2010-02-19 13 views
14

Hier finden Sie praktische Ratschläge und Erfahrungen, die Menschen in einer ähnlichen Situation gemacht haben.TDD: "Nur Test" -Methoden

Wir verwenden eine BDD/TDD Methode für den Aufbau unserer Software (ziemlich große/komplexe Anwendung) Das Endergebnis ist .. Verhaltensspezifikationen (Gegeben/Wann/Dann Stil) abgeleitet von Geschäftsanforderungen, Unit Tests, die diese widerspiegeln und Code, der die Anforderungen von Tests widerspiegelt.

Unsere Testabteilung hat jedoch vor kurzem damit begonnen, Integrationstests durchzuführen, und verständlicherweise wollen sie unseren (bereits bestehenden) Business-Logik-Code verwenden, um den Teststatus einzurichten und abzubauen (anstatt direkt mit einer Datenbank zu arbeiten) Sie befassen sich hauptsächlich mit dem Testen über die Benutzeroberfläche der Anwendung und möchten nicht den ganzen Tag mit Datenbanken streiten.

Das Problem ist, dass einige der Entity-Repositorys keine Löschmethoden haben, da für diese noch keine Geschäftsanforderungen vorliegen. Viele haben Archive/Wiederherstellen/Backup usw. (und möglicherweise löschen für das Backlog ausstehend).

So jetzt haben wir eine Testabteilung. Anforderung zum Löschen (aber eine, die mit Business-User Stories konfligiert)

Also .... meine Frage ist ... wenn ich Methoden speziell für die Testabteilung hinzufügen würde ... was ist die beste Art der Handhabung diese. Ich verstehe, dass dies in "TDD Utopia" allgemein als schlechte Praxis angesehen wird, aber realistisch gesehen, wie haben Sie sich mit dieser Art von Konflikt auseinandergesetzt?

Die ersten Gedanken, die ich gehabt haben, sind entweder die Verwendung Namensgebung ...

void TestOnly_Delete(Guid id){} 

... Attribute ...

[TestOnly] 
void Delete(Guid id){} 

... oder Compiler-Direktiven ...

#if TESTBUILD 
void Delete(Guid id){} 
#endif 

So können Entwickler mindestens wissen, TestOnly-Methoden nicht aufzurufen, und Testmethoden werden maximal nicht in Produktionsaufstellungen bereitgestellt.

... oder einfach nur betrügen und eine User Story hinzufügen, dass es so ;-)

Jede Erfahrung oder Ratschläge dankbar geschätzt zu verwalten?

Vielen Dank im Voraus.

Antwort

4

Ihre erste Sorge sollte sein fügt das Hinzufügen dieser Funktionalität verbessern oder verschlechtern die aktuelle API? Ein typisches Szenario in TDD ist, dass ein Klassenmitglied (zunächst) nur aus Gründen der Testbarkeit benötigt wird, aber es entspricht allen normalen API Design Richtlinien, so dass es nicht schadet (und oft später eine wertvolle Ergänzung im Produktionscode darstellt) auch).

Wenn das stimmt, dann fügen Sie es auf alle Fälle einfach hinzu , wenn Sie so einfach tun können.

Manchmal ist das Gegenteil der Fall. In diesem Fall müssen Sie dem Drang widerstehen, das Mitglied hinzuzufügen. Sie können jedoch häufig der Open/Closed Principle folgen und Ihre API öffnen, damit andere die gewünschte Funktionalität hinzufügen können. Testability is really just another word for the Open/Closed Principle.

In Ihrem Fall besteht die einfachste Lösung einfach darin, sicherzustellen, dass die betreffenden Klassen entsiegelt sind, und dann die Testabteilung aufzufordern, von diesen Klassen abzuleiten und die Funktionalität selbst zu implementieren. Wenn sie diese Fähigkeit nicht haben, können Sie dies für sie tun, während Sie die Unterklassen weiterhin testweise halten.

1

In meinem Code, erstelle ich eine Unterklasse: zum Beispiel, wenn ich eine DataLayer Klasse haben, die die Datenschicht Zugriff auf alle öffentlichen Methoden muss, dann könnte ich es mit einem Test_DataLayer Unterklasse Unterklasse, die Methoden von DataLayer erbt und die darüber hinaus beliebige zusätzliche Methoden wie Delete implementiert und deren Implementierung auf interne oder geschützte Methoden der Basisklasse zugreifen kann.

1

Normalerweise endet ich mit einem "test-only" -Projekt/einer Bibliothek, die alle Mock-/Hilfsklassen enthält, die ich für meine Tests benötige. Das Hinzufügen der erforderlichen Klassen/Methoden in dieser Mock-Bibliothek - die nicht im Produktionscode enthalten ist - scheint für diese Anforderung eine natürliche Lösung zu sein. Wenn Sie noch keine solche Bibliothek haben und diese nicht erstellen wollen, dann würde ich - wenn möglich - die internen Methoden markieren und sie nur dem Testframework aussetzen. Sie geben keine Plattform an, aber ich weiß, dass dies mit C# /. NET möglich ist, und ich verwende diese Fähigkeit oft, um meinen Tests Zugriff auf Methoden zu geben, die sonst außerhalb der Bibliothek nicht verfügbar wären.

In einem anderen Hinweis, würde ich sagen, dass die Tester so ein Teil Ihrer Anforderungsanalyse als die tatsächlichen Kunden sind. Genau wie wir einige Anforderungen haben, die nur für unsere Entwicklungsbedürfnisse sind, haben wir einige Anforderungen für das Testen. Der Trick, wie Sie feststellen, besteht darin, den Code so zu entwickeln, dass die Anforderungen der Stakeholder so weit wie möglich erfüllt werden. Wenn es zu Konflikten kommt, versuchen wir den bestmöglichen Kompromiss zu finden. IMO, die es ermöglicht, aus Test-only-Bibliotheken zu löschen, ist ein vernünftiger Kompromiss mit dem Bedürfnis des Kunden nach Datensicherheit (kein Löschen).

0

Dies ist eine interessante Frage. Ich habe einige Gedanken, aber ich bin mir nicht sicher, ob es eine Antwort auf dein Problem sein wird.

Ich werde persönlich eine explizite Gruppe von Interfaces erstellen, die von dem, was Sie bereits für die Entität haben, wie zB IIntTest_Customer: ICustomer erben und dort die Delete-Methode definieren. Wenn möglich, versuchen Sie, alle diese Schnittstelle in ein separates Projekt zu setzen, so dass der Entwickler nicht einmal einen Bezug zu ihm vom üblichen Projekt hat und die versehentliche Verwendung vermeidet. Die Testabteilung wird dann diese spezifischen internen Testschnittstellen für ihren Testzweck verwenden.

Um dies zu erreichen, müssen Sie möglicherweise Ihren aktuellen Code umgestalten und die Entität ändern, um stattdessen diese internen Testschnittstellen zu implementieren, und mit der Vererbungshierarchie sollte noch der gesamte vorhandene Code funktionieren, der sich auf die Basisschnittstelle bezieht.

0

Ich werde meinem Code niemals Lösch- oder andere Bereinigungsmethoden hinzufügen, um das automatisierte Testen zu unterstützen.

Es gibt so viele Alternativen, vom intelligenten Transaktionsmanagement bis zur automatischen Wiederherstellung von Datenbanken.