2012-09-12 9 views
18

Sto provando a configurare i miei test usando Xunit. Ho l'obbligo di eliminare tutte le immagini all'inizio di una cartella dei test, quindi ogni metodo esegue il ridimensionamento delle immagini e ne salva una copia nella cartella. La cartella dovrebbe essere svuotata solo una volta, quindi ogni metodo salverà la propria immagine nella cartella.Come eseguire il codice di configurazione solo una volta in un test xUnit.net

Quando si utilizza IUseFixture<T>, la funzione ClearVisualTestResultFolder viene ancora chiamata prima di ogni test, quindi mi ritrovo con una sola immagine nella cartella.

public class Fixture 
{ 
    public void Setup() 
    { 
     ImageHelperTest.ClearVisualTestResultFolder(); 
    } 
} 

public class ImageHelperTest : IUseFixture<EngDev.Test.Fixture> 
{ 
    public void SetFixture(EngDev.Test.Fixture data) 
    { 
     data.Setup(); 
    } 

    public static void ClearVisualTestResultFolder() 
    { 
     // Logic to clear folder 
    } 
} 

Se metto il ClearVisualTestResultFolder nel costruttore, è anche essere chiamato una volta per ogni metodo di prova. Ho bisogno di questo basta eseguire una volta prima di eseguire tutti i metodi di prova, come posso ottenere questo?

Se è importante, utilizzo il runner di prova ReSharper.

risposta

25

Seguendo la guida in questo xUnit discussion topic, sembra che sia necessario implementare un costruttore sul dispositivo e implementare anche IDisposable. Ecco un esempio completo che si comporta nel modo desiderato:

using System; 
using System.Diagnostics; 
using Xunit; 
using Xunit.Sdk; 

namespace xUnitSample 
{ 
    public class SomeFixture : IDisposable 
    { 
     public SomeFixture() 
     { 
      Console.WriteLine("SomeFixture ctor: This should only be run once"); 
     } 

     public void SomeMethod() 
     { 
      Console.WriteLine("SomeFixture::SomeMethod()"); 
     } 

     public void Dispose() 
     { 
      Console.WriteLine("SomeFixture: Disposing SomeFixture"); 
     } 
    } 

    public class TestSample : IUseFixture<SomeFixture>, IDisposable 
    { 
     public void SetFixture(SomeFixture data) 
     { 
      Console.WriteLine("TestSample::SetFixture(): Calling SomeMethod"); 
      data.SomeMethod(); 
     } 

     public TestSample() 
     { 
      Console.WriteLine("This should be run once before every test " + DateTime.Now.Ticks); 
     } 

     [Fact] 
     public void Test1() 
     { 
      Console.WriteLine("This is test one."); 
     } 

     [Fact] 
     public void Test2() 
     { 
      Console.WriteLine("This is test two."); 
     } 

     public void Dispose() 
     { 
      Console.WriteLine("Disposing"); 
     } 
    } 
} 

Quando si esegue questo dal corridore console, vedrete il seguente output:

D: \ xUnit> xunit.console.clr4 .exe test.dll/html foo.htm xUnit.net console test runner (64-bit .NET 4.0.30319.17929) Copyright (C) 2007-11 Microsoft Corporation.

xunit.dll: versione 1.9.1.1600 montaggio di prova: test.dll

SomeFixture ctor: Questo dovrebbe essere eseguito solo una volta

Test completo: 2 su 2

SomeFixture: Smaltimento SomeFixture

2 totali, 0 fallito, 0 saltati, ha preso 0,686 secondi

Quindi, quando apri il file di output di prova foo.htm, vedrai l'altro output di test.

6

IUseFixture<T>.SetFixture viene chiamato una volta per ogni test. La Fixture stessa viene creata solo una volta.

In altre parole, non dovresti fare nulla nel tuo metodo SetFixture, ma dovresti invece attivarlo nel costruttore Fixture.

Per la pulizia di una volta, implementare un IDisposable.Dispose sul proiettore (non è necessario però)

Si noti che si tratta di una cattiva idea quella di essere (anche potenzialmente) stato di condivisione tra i test. Meglio usare uno TemporaryDirectoryFixturelike this one.

11

La vecchia interfaccia IUseFixture<T> in xUnit.net v1.x è stato sostituito da da due nuove interfacce: IClassFixture<T> e ICollectionFixture<T>. Nell'aggiunta , il meccanismo per l'iniezione dei valori delle fixture nei test è stato modificato dai parametri di proprietà agli argomenti del costruttore. Gli apparecchi della classe vengono creati una volta e condivisi tra tutti i test nella stessa classe (molto simile alla vecchia IUseFixture). Gli apparecchi di raccolta funzionano allo allo stesso modo, con la differenza che la singola istanza è condivisa tra tutti i test nella stessa raccolta di test.

Problemi correlati