¿Cuándo uso el atributo TestFixtureSetUp en lugar de un constructor predeterminado?

StackOverflow https://stackoverflow.com/questions/212718

  •  03-07-2019
  •  | 
  •  

Pregunta

La documentación de NUnit no me dice cuándo usar un método con TestFixtureSetup y cuándo hacer la configuración en el constructor.

public class MyTest
{
    private MyClass myClass;

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

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

¿Hay alguna buena / mala práctica sobre el TestFixtureSetup versus el constructor predeterminado o no hay ninguna diferencia?

¿Fue útil?

Solución

Creo que este ha sido uno de los problemas que el equipo de nUnit no ha abordado. Sin embargo, existe el excelente xUnit project que vio este problema exacto y decidió que los constructores eran algo bueno de usar en inicialización del dispositivo de prueba .

Para nunit, mi mejor práctica en este caso ha sido utilizar TestFixtureSetUp , TestFixtureTearDown , SetUp y TearDown métodos como se describe en la documentación.

Creo que también me ayuda cuando no pienso en un dispositivo de prueba nUnit como una clase normal, aunque lo esté definiendo con esa construcción. Pienso en ellos como accesorios, y eso me lleva al obstáculo mental y me permite pasar por alto este problema.

Otros consejos

¿Por qué necesitarías usar un constructor en tus clases de prueba?

Utilizo los métodos marcados [SetUp] y [TearDown] para que el código se ejecute antes y después de cada prueba, y de manera similar [TestFixtureSetUp] y [TestFixtureTearDown] marcó los métodos para que el código se ejecute solo una vez y después de que se hayan ejecutado todas las pruebas en el dispositivo.

Supongo que probablemente podrías sustituir el [TestFixtureSetUp] por un constructor (aunque no lo he intentado), pero esto solo parece romper con la clara convención que proporcionan los métodos marcados.

Una cosa que no puede hacer con [TestFixtureSetup] que puede hacer en el constructor es recibir parámetros del [TestFixture] .

Si desea parametrizar su dispositivo de prueba, deberá utilizar el constructor durante al menos algunos de la configuración. Hasta ahora, solo he usado esto para pruebas de integración, por ejemplo, para probar una capa de acceso a datos con múltiples proveedores de datos:

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

A menudo me he preguntado cuál era la necesidad de [TestFixtureSetUp] , dado que existe una construcción de lenguaje de primera clase simple y bien entendida que hace exactamente lo mismo.

Mi preferencia es usar constructores, para aprovechar la palabra clave de solo lectura, lo que garantiza que las variables de los miembros no puedan reinicializarse.

Hay una diferencia entre el constructor y el método marcado con el atributo [TestFixtureSetUp] . De acuerdo con la documentación de NUnit:

  

Es aconsejable que el constructor no tenga ningún efecto secundario, ya que NUnit puede construir el objeto varias veces en el transcurso de una sesión.

Por lo tanto, si tiene una inicialización costosa, es mejor usar TestFixtureSetUp .

[TestFixtureSetUp] y [TestFixtureTearDown] son para toda la clase de prueba. se ejecuta solo una vez.

[SetUp] y [TearDown] son para cada método de prueba (prueba). se ejecuta para cada prueba.

Una diferencia importante entre el constructor y TestFixtureSetUp es que, al menos en NUnit 2, el código del constructor se ejecuta realmente en la enumeración de la prueba, no solo en la ejecución de la prueba, por lo que básicamente desea limitar el código de ctor a solo valores de solo lectura, es decir, parámetros . Cualquier cosa que cause efectos secundarios o que haga algún trabajo real debe envolverse en un Lazy o hacerse en TestFixtureSetUp / OneTimeSetUp. Por lo tanto, puede pensar en el constructor como el único lugar para configurar la prueba. Mientras que TestFixtureSetUp es donde se inicializa el dispositivo de prueba, el estado inicial requerido del sistema antes de que se ejecuten las pruebas.

Creo que tengo una buena respuesta negativa: la razón para usar un constructor en lugar del atributo es cuando tienes una herencia entre las clases de prueba.

Solo se llamará a un método anotado con [TestFixtureSetup] (solo en la clase concreta), pero los otros inicializadores de fixture no. En este caso, prefiero poner la inicialización en el constructor, que tiene una semántica bien definida para la herencia :)

El constructor y los métodos SetUp se usan de manera diferente:
El constructor se ejecuta solo una vez.
Sin embargo, los métodos de SetUp se ejecutan varias veces, antes de que se ejecute cada caso de prueba.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top