@BeforeClass et de l'héritage - l'ordre d'exécution
J'ai une classe de base abstraite, que j'utilise comme base pour mes tests unitaires (TestNG 5.10). Dans cette classe, j'initialise l'ensemble de l'environnement pour mes tests, configuration des mappages de base de données, etc. Cette classe abstraite est une méthode avec un @BeforeClass
annotation qui ne l'initialisation.
Prochaine, j'étends la classe avec des classes spécifiques dans lesquels j'ai @Test
méthodes et @BeforeClass
méthodes. Ces méthodes spécifiques à la classe d'initialisation de l'environnement (par exemple, certains enregistrements dans la base de données).
Comment je peux faire respecter un ordre précis de la @BeforeClass
annoté méthodes? J'ai besoin de ceux de la classe de base abstraite pour être exécuté avant le celles de l'extension de la classe.
Exemple:
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@BeforeClass
doSpecificInitialization() {...}
@Test
doTests() {...}
}
Ordre attendu:
A.doInitialization
B.doSpecificInitialization
B.doTests
De la commande réelle:
B.doSpecificInitialization //<- crashes, as the base init is missing
(A.doInitialization //<---not executed
B.doTests) //<-/
Vous devez vous connecter pour publier un commentaire.
Ne pas mettre le
@BeforeClass
sur leabstract
classe. Appel à partir de chaque sous-classe.Semble TestNG a
@BeforeClass(dependsOnMethods={"doInitialization"})
- lui donner un essai.dependsOnMethods
solution de contournement a fait le tour. Bien que je préfère un "super-classe de première" approche ...edit: Réponse ci-dessous est pour JUnit, mais je laisse ici de toute façon, parce que ça pourrait être utile.
Selon la JUnit api: "Le @BeforeClass méthodes de super-classes sera exécuté avant ceux de la classe en cours."
J'ai testé, et il semble fonctionner pour moi.
Cependant, comme @Odys mentionne ci-dessous, pour JUnit, vous devez avoir la deux méthodes nommées différemment bien que le fait de faire autre résultat que dans la sous-classe de la méthode en cours d'exécution parce que le parent est dans l'ombre.
J'ai ajouté
public
à la classe abstraite et TestNG (6.0.1) a exécuté le doInitialization() avantdoTests
. TestNG ne pas exécuterdoInitialization()
si je supprimepublic
de la classe A.B
aussi est un@BeforeClass
-méthode annotée, comme dans le cas des OP cas.J'ai juste essayé votre exemple avec 5.11 et j'ai l' @BeforeClass de la classe de base d'abord appelée.
Vous pouvez poster votre testng.xml fichier? Peut-être que vous spécifiez à la fois A et B, tandis que B est nécessaire.
N'hésitez pas à suivre sur le testng-les utilisateurs de la liste de diffusion et nous pouvons prendre un coup d'oeil à votre problème.
--
Cédric
Je viens juste de passer à travers cela et trouvé un moyen de plus pour atteindre cet objectif. Utilisez simplement
alwaysRun
sur@BeforeClass
ou@BeforeMethod
dans la classe abstraite, fonctionne comme vous le souhaitez.Quand je le lance à partir de: JUnitCore.runClasses(TestClass.class);
Il va exécuter le parent correctement, avant même que l'enfant (Vous n'avez pas besoin super.SetUpBeforeClass();)
Si vous l'exécutez à partir d'Eclipse:
Pour une raison quelconque, il ne peut pas exécuter la classe de base.
Le travail autour de:
Appel de la classe de base explicitement: (BaseTest.setUpBeforeClass();)
Vous souhaitez avoir un drapeau dans la classe de base dans le cas où vous exécutez à partir d'une application, pour déterminer si elle est déjà en place ou pas. Donc il ne fonctionne que si vous l'exécuter via les deux méthodes possibles (comme eclipse pour les personnels de test, et par le biais de FOURMI pour une version release).
Ce qui semble être un bogue avec Eclipse, ou au moins des résultats inattendus..
Pour JUnit:
Comme @fortega a mentionné:
Selon la JUnit api: "Le @BeforeClass méthodes de super-classes sera exécuté avant ceux de la classe en cours."
Mais attention de ne pas citer les deux méthodes avec le même nom. Puisque dans ce cas la méthode parent sera caché par enfant des parents. Source.
Comment avoir votre @BeforeClass appel de méthode vide specificBeforeClass() méthode qui peut ou peut ne pas être écrasées par des sous-classes de la sorte:
dependsOnMethod
peut être utilisé.par exemple dans le cas du Printemps (
AbstractTestNGSpringContextTests
)Vérifier votre déclaration d'importation.
Il devrait être
import org.testng.annotations.BeforeClass;
pas
import org.junit.BeforeClass;
Pourquoi n'essayez-vous pas de créer une méthode abstraite doSpecialInit() dans votre classe super, appelés à partir de votre BeforeClass méthode annotée dans une superclasse.
Donc les développeurs d'hériter de votre classe est obligée de mettre en œuvre cette méthode.
Il y a une autre solution facile ici.
Mon cas en particulier, c'est que j'ai besoin d'injecter de se moquer des services de "BeforeClass" dans la sous-classe avant "BeforeClass" dans la super-classe est exécutée.
Pour ce faire, il suffit d'utiliser un
@ClassRule
dans la sous-classe.Par exemple:
J'espère que cette aide. Cela peut permettre de s'acquitter efficacement statique de l'installation dans l'ordre à l'envers".
J'ai été confronté à un problème similaire aujourd'hui, la seule différence, c'est une classe de Base n'a pas été abstrait
Voici mon cas
Il est déjà arrivé qu'un
@BeforeClass
méthode de la classe A n'a jamais été exécutée.De jouer avec la vie privée des modificateurs j'ai trouvé que TestNG de ne pas exécuter un
@BeforeClass
méthode annotée de classe héritée si une méthode n'est pas visible à partir d'une classe héritièreDe manière à ce travail:
Comme un résultat à la suite arrive:
Dans mon cas (JUnit) j'ai les mêmes méthodes appelé setup() dans la classe de base et la classe dérivée. Dans ce cas seulement la classe dérivée de la méthode est appelée, et je l'ai appeler la méthode de classe de base.
Une meilleure et plus propre façon d'atteindre cet objectif en utilisant l'héritage peut être de la forme suivante -