Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TestNG BeforeMethod with groups

Tags:

java

testng

I am wondering about @BeforeMethod's usage with groups. In http://testng.org/javadoc/org/testng/annotations/BeforeMethod.html it says:

alwaysRun: If set to true, this configuration method will be run regardless of what groups it belongs to.

So I have the following class:

public class BeforeTest {
private static final Logger LOG = Logger.getLogger(BeforeTest.class);
@BeforeMethod(groups = {"g1"}, alwaysRun = false)
public void setUpG1(){
    sleep();
    LOG.info("BeforeMethod G1");
}

@Test(groups = {"g1"})
public void g1Test(){
    sleep();
    LOG.info("g1Test()");
}

@BeforeMethod(groups = {"g2"}, alwaysRun = false)
public void setUpG2(){
    sleep();
    LOG.info("BeforeMethod G2");
}

@Test(groups = {"g2"})
public void g2Test(){
    sleep();
    LOG.info("g2Test()");
}


private void sleep(){
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

Which outputs:

BeforeMethod G1
BeforeMethod G2
g1Test()
BeforeMethod G1
BeforeMethod G2
g2Test()

Aside the fact that I think awaysRun is false by default, can anyone explain to me why both before methods are called before each test, disregarding the groups? Something like @Test(skipBeforeMethod = "setUpG1") would work too.

I am using IntelliJ IDEA CE 10.5.2. I've run it with gradle 1.0-milestone-3, too.

like image 708
rweng Avatar asked Oct 29 '11 15:10

rweng


3 Answers

That is because the groups flag only indicates if a method belongs to a group. When that group is enabled, it is executed always, i.e. before all tests methods irrespective of the group the test methods belong to. By default all groups are enabled.

If you want to have the method only executed for the tests of certain groups, you would need to specify onlyForGroups.

public class BeforeTest {

    private static final Logger LOG = Logger.getLogger(BeforeTest.class);

    @BeforeMethod(onlyForGroups = { "g1" })
    public void setUpG1() {
        sleep();
        LOG.info("BeforeMethod G1");
    }

    @Test(groups = { "g1" })
    public void g1Test() {
        sleep();
        LOG.info("g1Test()");
    }

    @BeforeMethod(onlyForGroups = { "g2" }, alwaysRun = false)
    public void setUpG2() {
        sleep();
        LOG.info("BeforeMethod G2");
    }

    @Test(groups = { "g2" })
    public void g2Test() {
        sleep();
        LOG.info("g2Test()");
    }

    private void sleep() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

The output is

BeforeMethod G1
g1Test()
BeforeMethod G2
g2Test()
like image 159
kap Avatar answered Nov 15 '22 02:11

kap


How are you invoking TestNG? Are you running any groups?

If you run none, both @BeforeMethods will run. If you run "g1", only setupG1 will run, etc...

like image 42
Cedric Beust Avatar answered Nov 15 '22 01:11

Cedric Beust


I would recommend not to use alwaysRun=true, but create a special group for config methods (we use "config"), and annotate all before*() and after*() methods with groups = "config".

All test methods can be annotated with whatever group you like, e.g. "foo" and "bar".

Then, in your run, you do:

-Dgroups=config,foo

or

-Dgroups=config,bar

If you then add another group, "newGroup", you don't have to go through all the config methods and add "newGroup" to them, you just run:

-Dgroups=config,newGroup

This makes management of groups way easier!

If you (by mistake?) ran something like:

-Dgroups=config,nonExistingGroup

No tests (and no config methods) would run as you actually don't have any tests annotated for "nonExistingGroup" and config methods only run if there are "matching tests" that require those config methods to run.

like image 24
mac Avatar answered Nov 15 '22 01:11

mac