c# asp.net xunit xunit.net

c# - Cómo ejecutar el código de configuración solo una vez en una prueba de xUnit.net



asp.net (3)

Estoy tratando de configurar mis pruebas usando Xunit. Tengo el requisito de eliminar todas las imágenes en una carpeta al inicio de las pruebas, y luego cada método hace un cambio de tamaño de imagen y guarda una copia de su salida en la carpeta. La carpeta solo debe vaciarse una vez, y luego cada método guardará su propia imagen en la carpeta.

Cuando uso IUseFixture<T> , la función IUseFixture<T> todavía se está llamando antes de cada prueba, por lo que solo termino con una imagen en la carpeta.

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 } }

Si pongo el ClearVisualTestResultFolder en el constructor, también se llama una vez para cada método de prueba. Necesito que esto se ejecute solo una vez antes de que se ejecuten todos los métodos de prueba, ¿cómo puedo lograr esto?

Si importa, uso el corredor de prueba ReSharper.


La antigua IUseFixture<T> en xUnit.net v1.x ha sido reemplazada por dos nuevas interfaces: IClassFixture<T> y ICollectionFixture<T> . Además, el mecanismo para inyectar valores de aparatos en sus pruebas ha cambiado de establecedores de propiedades a argumentos de constructores. Los dispositivos de clase se crean una vez y se comparten entre todas las pruebas en la misma clase (como el antiguo IUseFixture). Los dispositivos de recolección funcionan de la misma manera, excepto que la instancia única se comparte entre todas las pruebas en la misma colección de pruebas.


Siguiendo la guía en este tema de discusión de xUnit , parece que necesita implementar un constructor en el Fixture y también implementar IDisposable. Aquí hay una muestra completa que se comporta como tú quieres:

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"); } } }

Cuando ejecutes esto desde el corredor de la consola, verás el siguiente resultado:

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

xunit.dll: Versión 1.9.1.1600 Ensamblaje de prueba: test.dll

SomeFixture ctor: esto solo debe ejecutarse una vez

Pruebas completas: 2 de 2

SomeFixture: Disposición de SomeFixture

2 en total, 0 fallidos, 0 omitidos, tomaron 0.686 segundos

Luego, cuando abra el archivo de salida de prueba foo.htm, verá la otra salida de prueba.


IUseFixture<T>.SetFixture se llama una vez para cada prueba. El accesorio en sí solo se crea una vez.

En otras palabras, no deberías estar haciendo nada en tu método SetFixture, sino que deberías estar activándolo en el constructor de Fixture.

Para una limpieza única, implemente un IDisposable.Dispose en el accesorio (aunque no es obligatorio)

Tenga en cuenta que es una mala idea compartir (incluso potencialmente) el estado entre pruebas. Lo mejor es utilizar un TemporaryDirectoryFixture como este .