In der NUnit-Dokumentation ist nicht angegeben, wann eine Methode mit a verwendet werden soll TestFixtureSetup
und wann das Setup im Konstruktor durchgeführt werden soll.
public class MyTest
{
private MyClass myClass;
public MyTest()
{
myClass = new MyClass();
}
[TestFixtureSetUp]
public void Init()
{
myClass = new MyClass();
}
}
Gibt es gute / schlechte Praktiken bezüglich des TestFixtureSetup
Versus gegenüber dem Standardkonstruktor oder gibt es keinen Unterschied?
c#
unit-testing
nunit
Paco
quelle
quelle
MSTest
). Achten Sie jedoch auf die Nebenwirkungen von Gerätekonfigurationen auf die Testlesbarkeit (siehe hier und hier ).Antworten:
Ich denke, dies war eines der Probleme, die vom nUnit-Team nicht angesprochen wurden. Es gibt jedoch das hervorragende xUnit-Projekt , bei dem genau dieses Problem festgestellt wurde und bei dem entschieden wurde, dass Konstruktoren eine gute Sache für die Initialisierung von Testvorrichtungen sind .
Für nunit, meine beste Praxis in diesem Fall war , die verwendet werden
TestFixtureSetUp
,TestFixtureTearDown
,SetUp
undTearDown
Methoden wie in der Dokumentation beschrieben.Ich denke, es hilft mir auch, wenn ich mir ein nUnit-Testgerät nicht als normale Klasse vorstelle, obwohl Sie es mit diesem Konstrukt definieren. Ich betrachte sie als Spielpaarungen, und das bringt mich über die mentale Hürde und ermöglicht mir, dieses Problem zu übersehen.
quelle
Setup
s (sowie Konstruktoren) im Allgemeinen eine schlechte Idee sind, die es schwierig macht , Testcode zu befolgen , NICHT, dass Konstruktoren besser sind alsSetup
s. Parameterlose Konstruktoren sind jedoch das letzte Mittel für diejenigen, die es wirklich brauchen. Siehe auch: Teststile und Vermeidung von Setup / TeardownWarum sollten Sie in Ihren Testklassen einen Konstruktor verwenden müssen?
Ich verwende
[SetUp]
und[TearDown]
markiere Methoden für Code, der vor und nach jedem Test ausgeführt werden soll, und ähnliche[TestFixtureSetUp]
und[TestFixtureTearDown]
markierte Methoden für Code, der nur einmal ausgeführt werden soll, bevor und nachdem alle Tests im Fixture ausgeführt wurden.Ich denke, Sie könnten wahrscheinlich den
[TestFixtureSetUp]
Konstruktor durch einen ersetzen (obwohl ich es nicht versucht habe), aber dies scheint nur von der klaren Konvention zu brechen, die die markierten Methoden bieten.quelle
Eine Sache
[TestFixtureSetup]
, die Sie im Konstruktor nicht tun können, ist das Empfangen von Parametern von der[TestFixture]
.Wenn Sie Ihr Testgerät parametrisieren möchten, müssen Sie den Konstruktor für mindestens einen Teil des Setups verwenden. Bisher habe ich dies nur für Integrationstests verwendet, z. B. zum Testen einer Datenzugriffsschicht mit mehreren Datenanbietern:
[TestFixture("System.Data.SqlClient", "Server=(local)\\SQLEXPRESS;Initial Catalog=MyTestDatabase;Integrated Security=True;Pooling=False"))] [TestFixture("System.Data.SQLite", "Data Source=MyTestDatabase.s3db")])] internal class MyDataAccessLayerIntegrationTests { MyDataAccessLayerIntegrationTests( string dataProvider, string connectionString) { ... } }
quelle
Es gibt einen Unterschied zwischen Konstruktor und Methode, die mit
[TestFixtureSetUp]
Attribut markiert sind . Laut NUnit-Dokumentation:Wenn Sie also eine teure Initialisierung haben, ist es besser, diese zu verwenden
TestFixtureSetUp
.quelle
Ich habe mich oft gefragt, was nötig
[TestFixtureSetUp]
ist, da es ein einfaches, gut verstandenes erstklassiges Sprachkonstrukt gibt, das genau das Gleiche tut.Ich bevorzuge die Verwendung von Konstruktoren, um das schreibgeschützte Schlüsselwort zu nutzen und sicherzustellen, dass Mitgliedsvariablen nicht neu initialisiert werden können.
quelle
[TestFixtureSetUp]
und[TestFixtureTearDown]
sind für die gesamte Testklasse. läuft nur einmal.[SetUp]
und[TearDown]
sind für jede Testmethode (Test). läuft für jeden Test.quelle
Ein wichtiger Unterschied zwischen Konstruktor und TestFixtureSetUp besteht darin, dass zumindest in NUnit 2 der Konstruktorcode tatsächlich bei der Testaufzählung ausgeführt wird und nicht nur bei der Testausführung. Sie möchten also den Ctor-Code darauf beschränken, nur schreibgeschützte, dh Parameterwerte zu füllen. Alles, was Nebenwirkungen verursacht oder tatsächliche Arbeit leistet, muss entweder in Lazy verpackt oder in TestFixtureSetUp / OneTimeSetUp ausgeführt werden. Sie können sich den Konstruktor also nur als einen Ort zum Konfigurieren des Tests vorstellen. Während im TestFixtureSetUp das Testgerät installiert ist, wird der erforderliche Anfangszustand des Systems vor dem Ausführen der Tests initialisiert.
quelle
Ich glaube, ich habe eine negative gute Antwort - der Grund, einen Konstruktor anstelle des Attributs zu verwenden, ist, wenn Sie eine Vererbung zwischen Testklassen haben.
Es wird nur eine mit Annotationen versehene Methode
[TestFixtureSetup]
aufgerufen (nur für die konkrete Klasse), die anderen Fixture-Initialisierer jedoch nicht. In diesem Fall würde ich die Initialisierung lieber in den Konstruktor einfügen, der eine genau definierte Semantik für die Vererbung hat :)quelle
Der Konstruktor und die
SetUp
Methoden werden unterschiedlich verwendet:Der Konstruktor wird nur einmal ausgeführt.
Die
SetUp
Methoden werden jedoch mehrmals ausgeführt, bevor jeder Testfall ausgeführt wird.quelle
[SetUp]
, während sich das OP bezieht[TestFixtureSetUp]
.