2010-02-23 13 views
11

Tengo un problema con NUnit, preguntándome si alguien tiene alguna idea.NUnit no obedece herencia de atributo

Estamos usando NUnit 2.5.3.9345 y C# 3.5.

Tome el siguiente código:

public class UnitTestBase 
{ 
    [TestFixtureSetUp] 
    public void SetUpTestFixture() 
    { 
     //Do something in base 
    } 
} 

[TestFixture] 
public class SomeTestClass : UnitTestBase 
{ 
    [TestFixtureSetUp] 
    public void FixtureSetUp() 
    { 
     //Do something in test class 
    } 

    [Test] 
    public void SomeTest() 
    { 
     //Some assertion 
    } 
} 

De acuerdo con la documentation, si me quedo SomeTestClass.SomeTest(), UnitTestBase.SetUpTestFixture() debe ser llamado antes SomeTestClass.FixtureSetUp().

Este no es el caso; el método base solo se invocará si no proporciono un método [TestFixtureSetUp] en la clase derivada.

¿Alguna idea por favor? ¿Realmente me ha desconcertado?

Gracias.

+1

Esto también se trata en la lista de correo de nunit: http://groups.google.com/group/nunit-discuss/browse_thread/thread/be59e1152773a456 –

Respuesta

2

No tengo el problema. Probé el resultado de lo siguiente:

de las pruebas obtenidos

[TestFixture] 
public class DerivedTest : TestBase 
{ 

    [TestFixtureSetUp] 
    public void FixtureSetup() 
    { 

     File.AppendAllText("Out.txt", string.Format("TestFixtureSetUp From DerivedTest{0}", Environment.NewLine)); 
    } 

    [TestFixtureTearDown] 
    public void FixtureTearDown() 
    { 
     File.AppendAllText("Out.txt", string.Format("TestFixtureTearDown Down From DerivedTest{0}", Environment.NewLine)); 
    } 

    [SetUp] 
    public void Setup() 
    { 
     File.AppendAllText("Out.txt", string.Format("Setup From DerivedTest{0}", Environment.NewLine)); 
    } 
    [TearDown] 
    public void Down() 
    { 
     File.AppendAllText("Out.txt", string.Format("TearDown From DerivedTest{0}", Environment.NewLine)); 
    } 

    [Test] 
    public void DoATest() 
    { 
     File.AppendAllText("Out.txt", string.Format("Did a Test{0}", Environment.NewLine)); 
    } 
} 

TestBase

public class TestBase 
{ 

    [TestFixtureSetUp] 
    public void BaseTestFixtureSetUp() 
    { 
     File.AppendAllText("Out.txt", string.Format("TestFixtureSetUp From TestBase{0}", Environment.NewLine)); 
    } 

    [TestFixtureTearDown] 
    public void BaseTestFixtureTearDown() 
    { 
     File.AppendAllText("Out.txt", string.Format("TestFixtureTearDown From TestBase{0}", Environment.NewLine)); 
    } 

    [SetUp] 
    public void BaseSetup() 
    { 
     File.AppendAllText("Out.txt", string.Format("Setup From TestBase{0}", Environment.NewLine)); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     File.AppendAllText("Out.txt", string.Format("TearDown From TestBase{0}", Environment.NewLine)); 
    } 
} 

Esto produce el siguiente resultado:

TestFixtureSetUp From TestBase 
TestFixtureSetUp From DerivedTest 
Setup From TestBase 
Setup From DerivedTest 
Did a Test 
TearDown From DerivedTest 
TearDown From TestBase 
TestFixtureTearDown Down From DerivedTest 
TestFixtureTearDown From TestBase 

estoy podido probar la salida con ReSharper 5 beta y Nunit GUI v 2.5.3.9345 (32 bits)

Editar Mientras que en el trabajo del corredor de prueba en ReSharper 4.5 no funcionó correctamente, sin embargo la ejecución del proyecto de prueba construida en x86 y x64 con el correspondiente NUnit.exe/NUnit-86.exe producido salida válida.

+0

¿Estaba usando ReSharper 5 por casualidad? – Michael

+0

Sí, estoy usando beta 5 en casa. –

+0

Marcado como una respuesta - parece un problema de ReSharper y TeamCity - presionando para obtener nuestro ReSharper (una vez que se haya lanzado 5) y TeamCity NUnit actualizado para que pueda aprovechar al máximo esta función. – Michael

0

¿Ha intentado darle a la clase base el atributo [TestFixture]? No sé si eso lo arreglará, pero parece que valdría la pena intentarlo ... la idea es que NUnit puede estar ignorando los atributos de la clase base si no es un TestFixture.

+0

Sí, el mismo comportamiento con nuestro sin [TestFixture] en la clase base. Si tomo el atributo [TestFixtureSetUp] fuera del método de clase derivada, se llama a la base. – Michael

0

Sí, he estado jugando con esto durante la última media hora y definitivamente es un error. Intenté agregar TestFixture a todas las clases y tener diferentes combinaciones. También probé métodos estáticos y de instancia. ¡Simplemente no parece querer jugar bien! :-(

De todos modos, la mejor solución que pude encontrar es poner el código TestFixtureSetUp en los constructores de su clase de prueba y clase base. Al menos entonces puede estar seguro de la herencia y es más claro para otros lectores de su código que quizá no conocen el funcionamiento interno de NUnit :-)

+0

Por cierto, lo intenté con NUnit v2.5.0.9122 y tampoco funciona con esta versión, así que esto no es algo que se haya introducido recientemente. –

+0

Lo intenté en la aplicación de NUnit para Windows y con el corredor de Resharper, ninguno funcionó. :-( –

+0

Acabo de ejecutar el código exacto de la respuesta de Marks y solo muestra el resultado de la prueba de las clases derivadas, nada de la clase base. Estoy empezando a agarrar pajas ahora, pero me acabo de dar cuenta de que estaba ejecutando 32- Estoy ejecutando 64 bits. ¿Podría ser esta la diferencia que está causando diferentes resultados? –

1

Una forma solución/diferente de hacerlo:

en lugar de confiar en el comportamiento que no es inmediatamente evidente, hacer algo como esto en lugar de utilizar el patrón de método de la plantilla para hacer que el pedido sea explícito utilizando las características normales del lenguaje:

public class UnitTestBase 
{ 
    protected abstract void PerFixtureSetUp(); 

    [TestFixtureSetUp] 
    public void SetUpTestFixture() 
    { 
     PerFixtureSetUp(); 
    } 
} 

[TestFixture] 
public class SomeTestClass : UnitTestBase 
{ 
    protected override void PerFixtureSetUp() 
    { 

    } 

    [Test] 
    public void SomeTest() 
    { 
     //Some assertion 
    } 
} 

Cada vez que he tenido motivos para utilizar dispositivos heredados o contextos de prueba, esta forma ha funcionado bastante bien. :)

Mi problema al basarme en los atributos es que, dado que estos tipos se crean e invocan mediante reflexión en el corredor sin relación entre los métodos, (sin polimorfismo) es más difícil razonar sobre el orden en que están llamado. El uso de características de lenguaje estándar ayuda a simplificar esto un poco.

+0

Creo que esta es una buena manera de abordar la situación, sí, simplemente me apetece usar las funciones incorporadas de NUnit. El pedido no está disponible. Demasiado problema, siempre y cuando solo defina uno de cada método en la base y uno de cada uno en la clase derivada, de esa manera hay alguna garantía de que se ordene (siempre que no haya una excepción). s se lanzan durante la instalación/desmontaje) – Michael

0

¿Con qué estás realizando tus pruebas? El comportamiento que está experimentando no está relacionado con NUnit (framework), sino con el corredor que está utilizando. ¿Estás utilizando testrunner integrado Resharper?

+0

He intentado tanto la GUI de NUnit como el corredor de Resharper con el mismo resultado. –

+0

¿Eso cambia algo si coloca un TestFixtureTearDown en la base o en el derivado o en ambos? – Simone

+0

Parece que usar la GUI NUnit 2.5.3 funciona y funciona ReSharper 5 beta 2. ReSharper 4.5.1 parece ser el problema, junto con nuestra compilación de TeamCity (5.0.10669) – Michael

Cuestiones relacionadas