Domanda

La documentazione di NUnit non mi dice quando utilizzare un metodo con un TestFixtureSetup e quando eseguire l'installazione nel costruttore.

public class MyTest
{
    private MyClass myClass;

    public MyTest()
    {
        myClass = new MyClass();
    }

    [TestFixtureSetUp]
    public void Init()
    {
        myClass = new MyClass();
    }
}

Esistono buone / cattive pratiche sul TestFixtureSetup rispetto al costruttore predefinito o non c'è alcuna differenza?

È stato utile?

Soluzione

Penso che questo sia stato uno dei problemi che non è stato affrontato dal team di nUnit. Tuttavia, c'è l'eccellente progetto xUnit che ha visto questo problema esatto e ha deciso che i costruttori erano una buona cosa da usare su inizializzazione del dispositivo di prova .

Per nunit, la mia migliore pratica in questo caso è stata quella di utilizzare TestFixtureSetUp , TestFixtureTearDown , SetUp e TearDown metodi come descritto nella documentazione.

Penso che mi aiuti anche quando non penso a un dispositivo di prova nUnit come una classe normale, anche se lo stai definendo con quel costrutto. Li considero come infissi, e questo mi fa superare l'ostacolo mentale e mi permette di ignorare questo problema.

Altri suggerimenti

Perché dovresti usare un costruttore nelle tue classi di test?

Uso i metodi contrassegnati [SetUp] e [TearDown] per eseguire il codice prima e dopo ogni test, e allo stesso modo [TestFixtureSetUp] e [TestFixtureTearDown] hanno contrassegnato i metodi per eseguire il codice una sola volta prima e dopo aver eseguito tutti i test nel dispositivo.

Suppongo che probabilmente potresti sostituire il [TestFixtureSetUp] per un costruttore (anche se non l'ho provato), ma questo sembra solo discostarsi dalla chiara convenzione fornita dai metodi contrassegnati.

Una cosa che non puoi fare con [TestFixtureSetup] che puoi fare nel costruttore è ricevere parametri da [TestFixture] .

Se vuoi parametrizzare il tuo dispositivo di prova, dovrai usare il costruttore per almeno alcuni del set-up. Finora l'ho usato solo per test di integrazione, ad es. per testare un livello di accesso ai dati con più fornitori di dati:

[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)
    {
        ...
    }
}

Mi sono spesso chiesto quale fosse la necessità di [TestFixtureSetUp] , dato che esiste un costrutto di linguaggio di prima classe semplice e ben compreso che fa esattamente la stessa cosa.

La mia preferenza è quella di utilizzare i costruttori, per sfruttare la parola chiave di sola lettura garantendo che le variabili dei membri non possano essere reinizializzate.

Esiste una differenza tra costruttore e metodo contrassegnati con l'attributo [TestFixtureSetUp] . Secondo la documentazione di NUnit:

  

È consigliabile che il costruttore non abbia effetti collaterali, poiché NUnit può costruire l'oggetto più volte nel corso di una sessione.

Quindi, se si dispone di un'inizializzazione costosa, è meglio utilizzare TestFixtureSetUp .

[TestFixtureSetUp] e [TestFixtureTearDown] sono per l'intera classe di test. funziona una sola volta.

[SetUp] e [TearDown] sono per ogni metodo di test (test). funziona per ogni test.

Una differenza importante tra costruttore e TestFixtureSetUp è che, almeno in NUnit 2, il codice costruttore viene effettivamente eseguito sull'enumerazione del test, non solo nel test in esecuzione, quindi in pratica si desidera limitare il codice ctor solo al popolamento in sola lettura, ovvero parametro, valori . Tutto ciò che causa effetti collaterali o qualsiasi lavoro effettivo deve essere racchiuso in un Pigro o fatto in TestFixtureSetUp / OneTimeSetUp. Quindi, puoi pensare al costruttore solo come un luogo per configurare il test. Mentre TestFixtureSetUp è il punto in cui viene inizializzato l'apparecchiatura di test, lo stato iniziale richiesto del sistema prima dell'esecuzione dei test.

Penso di avere una buona risposta negativa - il motivo per usare un costruttore invece dell'attributo è quando hai un'eredità tra le classi di test.

Verrà chiamato solo un metodo annotato con [TestFixtureSetup] (solo sulla classe concrete), ma non gli altri inizializzatori del dispositivo. In questo caso preferirei inserire l'inizializzazione nel costruttore, che ha una semantica ben definita per l'ereditarietà :)

Il costruttore e i metodi SetUp sono usati in modo diverso:
Il costruttore viene eseguito una sola volta.
Tuttavia, i metodi SetUp vengono eseguiti più volte, prima che venga eseguito ogni caso di test.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top