-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Groups in @BeforeMethod and @AfterMethod don't work as expected #549
Comments
I have the same problem. AfterMethod don't care about the group specified in groups="". |
@jeangb - I just now tried this in TestNG 6.10 and I cannot recreate the problem. Here's my sample class package org.rationale.emotions.github.issue549;
public class MyClass {
public void method1() {
System.out.println("Method 1 invocation");
}
public void method2() {
System.out.println("Method 2 invocation");
}
} Here's my test class package org.rationale.emotions.github.issue549;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class MyClassTest {
MyClass o = new MyClass();
@BeforeMethod (groups = "method1")
public void before1() {
System.out.println("Before1");
}
@BeforeMethod (groups = "method2")
public void before2() {
System.out.println("Before2");
}
@AfterMethod (groups = "method1")
public void after1() {
System.out.println("After1");
}
@AfterMethod (groups = "method2")
public void after2() {
System.out.println("After2");
}
@Test (groups = "method1")
public void testMethod1() throws Exception {
o.method1();
}
@Test (groups = "method2")
public void testMethod2() throws Exception {
o.method2();
}
} Here's how my suite xml looks like <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="1265_Suite" parallel="false" verbose="2">
<test name="92">
<groups>
<run>
<include name="method1"/>
</run>
</groups>
<classes>
<class name="org.rationale.emotions.github.issue549.MyClassTest"/>
</classes>
</test>
</suite>
and here's my output
|
@krmahadevan Could you try to include method2 too like this: <groups>
<run>
<include name="method1"/>
<include name="method2"/>
</run>
</groups> Does it work this way too for you? |
@apreg - If I do what you suggested above, then yes I can re-create what you are seeing. @juherr - Do you think that this is an issue ? I am a bit confused on this. Here's what TestNG is currently doing : When user chooses to run by 1 or more groups, TestNG ends up invoking all the |
Currently, it is how If you choose So, it is not a bug. But many persons don't understand it (some StackOverflow questions about it) because the behavior is not really logic. So, it could be a good idea to fix the issue. Ping @cbeust |
@juherr What is not logic about the current behavior? |
@cbeust In fact, many users expect to have groups activated when they select a test. For example, if they run Another example: if they run I'm not saying the current behavior is bad but it is not the most intuitive. |
Isn't this what |
No, it is not exactly the same goal IMO.
And if you check the sample of this issue, it goes a step further: it expects the group is only activated for the context of the test. |
Has this issue been resolved . i just tried with testng 6.9.14 and it didn't work for aftermethod groups . |
@madhukarashok - Can you please help clarify what did you try ? This is not resolved because there's some ambiguity in the expectation. Please feel free to include relevant java and xml samples. |
i think i overlooked a condition which caused that confusion and im might be able to rectify that. |
@madhukarashok - Am guessing that screenshot is from eclipse. But you still haven't shared an example that can be used to reproduce the problem. Can you please do that ? |
hi here is the code snippet package com.testCases;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class sampletest extends basetest {
private String EcommerceTestCase;
public Boolean iflag=false;
//private String ecommerceTestCases;
AppDataFromDB apdfdb = null;
cartTestartTest sCart =null;
cartOverlayTest bopisAddtoCart=null;
createOrderTest bopisCreateOrder = null;
sPage bopisPage = null;
sCart cart=null;
private String ecomID;
public BopisRegressionTests(){
}
@Factory(dataProvider = "DP4")
public BopisRegressionTests(String testCaseID){
this.EcommerceTestCase = testCaseID;
}
@BeforeMethod(groups={"atc"})
public void setUp(){
common.setInsertResults(insertResults);
apdfdb = new AppDataFromDB(insertResults);
EcommerceTestCases ecommerceTestCases = apdfdb.getNewTestCaseFROMDB(EcommerceTestCase);
ecomID = ecommerceTestCases.getTestCaseDescription();
cart = new ShoppingCart(common);
bopisPage = new BopisPage(common);
bopisCreateOrder = new BopisCreateOrderTest(EcommerceTestCase, common);
bopisAddtoCart = new BopisAddtoCartOverlayTest();
}
@BeforeGroups(groups={"cart","atc"})
public void Login(){
LoginSetup();
}
@Test(groups={"atc"})
public void baddToCartOverLayVerification(){
if (ecomID.contains("AddToOverLay")) {
bopisAddtoCart.addToCartOverlay(EcommerceTestCase, common);
bopisAddtoCart.overlayverification(EcommerceTestCase,apdfdb);
}
}
@Test(groups={"cart"})
public void cartverfiy (){
if (ecomID.contains("Cart")) {
sCart = new BopisCartTest();
sCart.cart(EcommerceTestCase, common);
}
}
@AfterMethod(dependsOnGroups={"cart"},dependsOnMethods="cartverfiy ")
public void addToCart1(){
if (ecomID.contains("Cart")) {
sCart.addToCart();
}
}
@AfterMethod(dependsOnGroups={"cart"},dependsOnMethods="addToCart1")
public void cstoreHeaderValidation1(){
if (sCart != null ) {
sCart.storeHeaderValidation();
}
}
} here is the xml <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Sherwin Williams Chrome Suite" verbose="0" parallel="none"
thread-count="3" configfailurepolicy="continue" preserve-order="true">
<parameter name="configFile" value="config/chrome.win.properties" />
<parameter name="logLevel" value="info" />
<test name="bRegressionRun">
<groups>
<run>
<include name="atc"/>
<include name="cart"/>
</run>
</groups>
<classes>
<class name="com.sw.testcases.BopisRegressionTests" />
</classes>
</test>
</suite> my base execution flow is i hav two groups "atc" & "cart" and i have different methods for respective groups which needs to get kicked off when @test is executed. but im having hard time running dependonmethods in conjuncture with @AfterMethod as it keeps spitting out this error "com.sw.testcases.BopisRegressionTests.addToCart1() is depending on method public void com.sw.testcases.BopisRegressionTests.cartverfiy (), which is not annotated with @test or not included." i jus need one execution for each of this groups in the following order
let me know if it makes sense ? |
hi i tried dependOnGroups & dependOnMethods annotations like shown below and was unsuccesfull import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import com.ecommerce.store.dataaccess.EcommerceTestCases;
import com.sw.datahelper.AppDataFromDB;
import com.sw.pages.BopisPage;
import com.sw.pages.ShoppingCart;
public class BopisRegressionTests extends SWBaseTest {
private String EcommerceTestCase;
public Boolean iflag=false;
//private String ecommerceTestCases;
AppDataFromDB apdfdb = null;
BopisCartTest sCart =null;
BopisAddtoCartOverlayTest bopisAddtoCart=null;
BopisCreateOrderTest bopisCreateOrder = null;
BopisPage bopisPage = null;
ShoppingCart cart=null;
private String ecomID;
public BopisRegressionTests(){
}
@Factory(dataProvider = "DP4")
public BopisRegressionTests(String testCaseID){
this.EcommerceTestCase = testCaseID;
}
@BeforeMethod(alwaysRun = true)
public void setUp(){
common.setInsertResults(insertResults);
apdfdb = new AppDataFromDB(insertResults);
EcommerceTestCases ecommerceTestCases = apdfdb.getNewTestCaseFROMDB(EcommerceTestCase);
ecomID = ecommerceTestCases.getTestCaseDescription();
cart = new ShoppingCart(common);
bopisPage = new BopisPage(common);
bopisCreateOrder = new BopisCreateOrderTest(EcommerceTestCase, common);
bopisAddtoCart = new BopisAddtoCartOverlayTest();
}
@Test(groups={"cart"})
public void aLogin(){
LoginSetup();
}
@Test(groups={"atc"})
public void baddToCartOverLayVerification(){
if (ecomID.contains("AddToOverLay")) {
bopisAddtoCart.addToCartOverlay(EcommerceTestCase, common);
bopisAddtoCart.overlayverification(EcommerceTestCase,apdfdb);
}
}
@Test(groups="cart",dependsOnMethods="aLogin")
public void d1 (){
if (ecomID.contains("Cart")) {
sCart = new BopisCartTest();
sCart.cart(EcommerceTestCase, common);
}
}
@AfterMethod(dependsOnGroups={"cart"},dependsOnMethods="d1")
public void addToCart1(){
if (ecomID.contains("Cart")) {
sCart.addToCart();
}
}
@AfterMethod(dependsOnGroups={"cart"},dependsOnMethods="addToCart1")
public void cstoreHeaderValidation1(){
if (sCart != null ) {
sCart.storeHeaderValidation();
}
}
} The execution stops at d1 and it doesn't enter the aftermethod annotations which is dependent on groups & dependentonmethod = "d1". any help would be appreciated . |
How is this not a bug? If BeforeMethod with assigned groups also run on tests not assigned to those groups, what's the groups assignment for? Sorry, I just don't see the logic here. |
As I said, groups are used for the test selection. As an alternative, you can split your tests in many classes. |
The functionality you are looking for is BeforeGroup.
Output: Before1 The BeforeMethod or AfterMethod will run for EVERY method in the test class IF its group is enabled. Since you choose to run the class with groups 'method1' and 'method2', methods before1(), before2(), after1(), and after2() are ALL flagged as true. Therefore, both before1() AND before2() will run before EVERY method, and both after1() AND after2() will run after every method. |
No, I propose to add a kind of group filter to And as far as I can see, issue #780 is very similar, so this should fix it too. |
@stachenov - Please go ahead and raise a PR with your changes. That would help facilitating the discussion on the actual changes more aptly. |
I tried both 6.10 and 7.0.0-beta, the test result is not expected. Here is the wiki page with details. If groups cannot group Before and After methods, why don't remove it to avoid confusions. I am quite confused why we need to add one more attribute onlyForGroups rather than fix groups attribute to make it workable in the expected way. (@juherr, if groups is used for test selection, why did we add it to Before/After Method annotation also?) But anyway, onlyForGroups can work in 7.0.0-beta7. |
The wiki page is broken. Opens up a error page instead. I also find it confusing, but I understand the historical reasons behind it. If groups are used for test selection, it makes perfect sense that they work in exactly the same way for before/after methods. You may have, say, a “slow” group that also includes rather slow startup, and therefore mark the appropriate before method as belonging to the same group, to avoid expensive startup if the slow tests aren't selected. And once groups are defined as test selection mechanism, it makes little sense to use them for method invocation control. The problem is that maybe it is wrong to have |
Maybe a better name for TestNG groups could be "tags". But as @stachenov said: historical reason. |
I find the documentation lacking for the use of onlyForGroups on AfterMethods. Currently it says:
src: https://testng.org/doc/documentation-main.html In reality, for onlyForGroup to work, it must be accompanied with a "alwaysRun = true". |
What happens if you don't specify |
@stachenov |
?! I was replying to @CoryKniefel about |
@stachenov |
Oh. But it was apparently broken more than a year ago. I don't think it matters now whether it was indeed so. |
If we exclude the groups or do not use groups tag in testng.xml file, then @BeforeMethod/@AfterMethod(onlyForGroups) methods run. But if we include the groups, then the @BeforeMethod/@AfterMethod(onlyForGroups) methods do not run. After some research, I found out that both of the above behaviour is TestNG design behaviour. So, as a workaround, when we include any groups, then we need to club onlyForGroups with alwaysRun=true i.e. @BeforeMethod/@AfterMethod(onlyForGroups, alwaysRun=true). But in this case, if there is any SkipException in the preceding/parent config methods, then it is forced to execute the @BeforeMethod/@AfterMethod methods, even when the test method is going to be skipped. So, to avoid this issue, we need to club groups flag with onlyForGroups flag as suggested here. There is a similar issue logged here, when the preceding/parent config methods has failed. |
Either I'm misinterpreting or misusing TestNG-6.8.8, but it seems like the groups attribute in the @BeforeMethod and @AfterMethod aren't working as expected.
Consider following class:
and following test
I would expect the output to be
However, the output is
The text was updated successfully, but these errors were encountered: