2008-10-17 5 views
64

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.¿Cuándo uso el atributo TestFixtureSetUp en lugar de un constructor predeterminado?

public class MyTest 
{ 
    private MyClass myClass; 

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

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

¿Hay buenas malas prácticas/sobre la TestFixtureSetup frente al constructor por defecto o no ¿Hay alguna diferencia?

+0

Como esta es siempre una pregunta frecuente, considere [esto] (https://stackoverflow.com/a/4970076/908336) y [este] (https://stackoverflow.com/a/8689398/908336) (las mismas discusiones para 'MSTest'). Pero tenga cuidado con los efectos secundarios de las configuraciones de los dispositivos en la legibilidad de las pruebas (vea [aquí] (http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html) y [aquí] (https: //lostechies.com/jimmybogard/2013/09/26/test-styles-and-avoiding-setupteardown/)). –

Respuesta

13

Creo que este ha sido uno de los problemas que no ha sido abordado por el equipo de nUnit. Sin embargo, está el excelente xUnit project que vio este problema exacto y decidió que los constructores eran buenos para usar en test fixture initialization.

Para nunit, mi mejor práctica en este caso ha sido la utilización de los 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 elementos fijos, y eso me supera el obstáculo mental y me permite pasar por alto este tema.

+0

Tenga en cuenta que el [artículo de xUnit] (https://xunit.github.io/docs/comparisons.html) está sugiriendo que los 'Setup's (así como los constructores) son generalmente una mala idea que hace que el código de prueba [difícil de siga] (http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html), NO que los constructores sean mejores que los 'Setup's. Sin embargo, los constructores paramétricos son el último recurso para aquellos que realmente lo necesitan. También vea esto: [Probar estilos y evitar configuración/desmontaje] (https://lostechies.com/jimmybogard/2013/09/26/test-styles-and-avoiding-setupteardown/) –

62

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

utilizo [SetUp] y [TearDown] métodos marcados para el código que se ejecutará antes y después de cada prueba, y de manera similar [TestFixtureSetUp] y [TestFixtureTearDown] métodos marcados para el código que se ejecutará sólo una vez antes y después de todas las pruebas en el accesorio de haber sido ejecutado.

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

+4

No tenía idea de por qué necesito un constructor, pero tampoco tengo idea de por qué necesito TestFixtureSetUp. Sé acerca de los atributos de configuración, desmontaje y testfixtureteardowndown. Simplemente no sé la diferencia entre el constructor y el atributo testfixturesetup. – Paco

+3

Solo para responder su pregunta. Necesita utilizar un constructor en sus clases de prueba si tiene dispositivos de prueba parametrizados. –

9

A menudo me he preguntado cuál era la necesidad de [TestFixtureSetUp], dado que hay 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 readonly, asegurando que las variables miembro no puedan reiniciarse.

+4

La palabra clave de solo lectura no asegura que un miembro no se modifica Si el miembro es una clase, el estado interno de la clase se puede modificar en una prueba, y este estado se transferirá al siguiente método de prueba (porque nunit no recrea la clase entre cada ejecución de prueba) – Pete

2

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.

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

+2

Esto ha cambiado desde NUnit 2.5 Ahora se invocarán todos los métodos anotados con [TestFixtureSetup]. –

12

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

Si desea parametrizar su accesorio de prueba, tendrá que usar el constructor para al menos algunos de la configuración. Hasta ahora, solo he usado esto para pruebas de integración, p. para probar una capa de acceso a datos con varios 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) 
    { 
     ... 
    } 
} 
8

Hay diferencia entre el constructor y el método marcado con [TestFixtureSetUp] atributo.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.

Si tiene una inicialización costosa, es mejor usar TestFixtureSetUp.

+1

Esto supone que el método marcado TestFixtureSetUp es estático. De lo contrario, sería imposible llamar al constructor más a menudo, a menos que la instancia de prueba se descarte sin ser utilizada por NUnit, lo que dudo. – jpierson

-2

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

+1

Se refiere a '[SetUp]', mientras que OP se refiere a '[TestFixtureSetUp]'. – onedaywhen

2

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

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

1

Una diferencia importante entre el constructor y TestFixtureSetUp es que, al menos en NUnit 2, el código constructor se ejecuta en la enumeración de prueba, no solo en la ejecución de prueba, por lo que básicamente se quiere limitar el código de ctor a solo valores. Todo lo que causa efectos secundarios o hace un trabajo real necesita ser envuelto en un Lazy o hecho en el TestFixtureSetUp/OneTimeSetUp. Por lo tanto, puede pensar en el constructor como un lugar exclusivo para configurar la prueba. Mientras que TestFixtureSetUp es donde se inicia el dispositivo de prueba, se inicializa el estado inicial requerido del sistema antes de ejecutar las pruebas.

Cuestiones relacionadas