Tengo una clase base abstracta, que uso como base para mis pruebas unitarias (TestNG 5.10). En esta clase, inicializo todo el entorno para mis pruebas, configurando mapeos de base de datos, etc. Esta clase abstracta tiene un método con una @BeforeClass
anotación que hace la inicialización.
A continuación, extiendo esa clase con clases específicas en las que tengo @Test
métodos y también @BeforeClass
métodos. Estos métodos realizan la inicialización del entorno específica de la clase (por ejemplo, colocan algunos registros en la base de datos).
¿Cómo puedo hacer cumplir un orden específico de los @BeforeClass
métodos anotados? Necesito que los de la clase base abstracta se ejecuten antes que los de la clase extensible.
Ejemplo:
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@BeforeClass
doSpecificInitialization() {...}
@Test
doTests() {...}
}
Orden esperada:
A.doInitialization
B.doSpecificInitialization
B.doTests
Orden real:
B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization // <---not executed
B.doTests) // <-/
fuente
dependsOnMethods
solución hizo el truco. Aunque prefiero un enfoque de "primera superclase" ...editar: La respuesta a continuación es para JUnit , pero la dejaré aquí de todos modos, porque podría ser útil.
Según la API de JUnit : "Los métodos @BeforeClass de superclases se ejecutarán antes que los de la clase actual".
Probé esto y parece funcionar para mí.
Sin embargo, como @Odys menciona a continuación, para JUnit debe tener los dos métodos nombrados de manera diferente, aunque de lo contrario, solo se ejecutará el método de subclase porque el padre será sombreado.
fuente
He añadido
public
a la clase abstracta y TestNG (6.0.1) ejecuta el doInitialization () antesdoTests
. TestNG no se ejecutadoInitialization()
si eliminopublic
de la clase A.fuente
B
también tiene un@BeforeClass
método anotado, como en el caso del OP.Acabo de probar su ejemplo con 5.11 y obtengo el @BeforeClass de la clase base invocado primero.
¿Puedes publicar tu archivo testng.xml? Tal vez esté especificando tanto A como B allí, mientras que solo B es necesario.
No dude en hacer un seguimiento de la lista de correo de testng-users y podremos analizar más de cerca su problema.
- Cedric
fuente
Acabo de pasar por esto y encontré una forma más de lograrlo. Solo use
alwaysRun
en@BeforeClass
o@BeforeMethod
en la clase abstracta, funciona como es de esperar.fuente
Cuando ejecuto desde: JUnitCore.runClasses (TestClass.class); Ejecutará el padre correctamente, antes que el hijo (no necesita super.SetUpBeforeClass (); ) Si lo ejecuta desde Eclipse: por alguna razón, no puede ejecutar la clase base. La solución alternativa : Llame explícitamente a la clase base: ( BaseTest.setUpBeforeClass (); ) Es posible que desee tener una marca en la clase base en caso de que la ejecute desde una aplicación, para determinar si ya está configurada o no. Por lo tanto, solo se ejecuta una vez si lo ejecuta a través de ambos métodos posibles (como desde eclipse para pruebas personales y a través de ANT para una versión de compilación).
Esto parece ser un error con Eclipse, o al menos resultados inesperados.
fuente
Para JUnit : Como ha mencionado @fortega: Según la api de JUnit: "Los métodos @BeforeClass de superclases se ejecutarán antes que los de la clase actual".
Pero tenga cuidado de no nombrar ambos métodos con el mismo nombre . Dado que en este caso el método principal estará oculto por el padre secundario. Fuente .
fuente
¿Qué tal si tu método @BeforeClass llama a un método específicoBeforeClass () vacío que puede o no ser sobrescrito por subclases como este?
fuente
dependsOnMethod
puede ser usado.por ejemplo, en el caso de Spring (
AbstractTestNGSpringContextTests
)fuente
Verifique su declaración de importación. Debería ser
import org.testng.annotations.BeforeClass;
no
import org.junit.BeforeClass;
fuente
Esto funciona para mí
fuente
¿Por qué no intentas crear un método abstracto doSpecialInit () en tu superclase, llamado desde tu método anotado BeforeClass en la superclase?
Entonces, los desarrolladores que heredan su clase se ven obligados a implementar este método.
fuente
Aquí hay otra solución sencilla.
Mi situación particular es que necesito inyectar servicios simulados de "BeforeClass" en la subclase antes de que se ejecute "BeforeClass" en la superclase.
Para hacer esto, simplemente use a
@ClassRule
en la subclase.Por ejemplo:
Espero que esto ayude. Esto puede ejecutar de forma eficaz la configuración estática en orden "inverso".
fuente
Hoy me he enfrentado a un problema similar, la única diferencia era que una clase base no era abstracta
Este es mi caso
Ocurrió que un
@BeforeClass
método de la clase A nunca se ejecutó.Jugando con modificadores de privacidad, encontré que TestNG no ejecutará un
@BeforeClass
método anotado de una clase heredada si un método no es visible desde un heredero de claseEntonces esto funcionará:
Como resultado, sucede lo siguiente:
fuente
En mi caso (JUnit) tengo los mismos métodos llamados setup () en la clase base y la clase derivada. En este caso, solo se llama al método de la clase derivada, y lo hago llamar al método de la clase base.
fuente
Una forma mejor y más limpia de lograr esto usando la herencia puede ser la siguiente:
fuente