Completely stumped here - BeforeClass running BeforeGroups - also best practice?

322 views
Skip to first unread message

rickcr

unread,
Oct 17, 2008, 10:49:25 AM10/17/08
to testng-users
Ok, I've been searching the forums here and looking at online docs.
I'm stumped now on things.

First off, what I want:

"I'll have some tests that will need access to a static member - and
EntityManager, while other test classes will need access to a
different static EntityManager"

To accomplish this I thought it made sense to:
1) For simplicity in this example, two groups created "group1"
"group2"
2) classes that are in group1 need to have a class initialized that
runs before any tests in group1 are run
3) classes that are in group2 need to have a class initialized that
runs before any tests in group2 are run

I thought it would make sense to use @BeforeGroups for this.

I also need a @BeforeClass to run for each class.

What I notice happening is that the @BeforeClass method (even if
assigned groups) is always running BEFORE the @BeforeGroups.

Why is this? (I'm running this from Maven2 if it matters?)

Here is the current code (not much)

http://pastie.org/294673

When the test run the order in the logs is

UsersTest runBeforeClass
BaseTest setUp
UsersTest getUsers
BaseTest tearDown

I'm not sure why the BaseTest setUp isn't run first?

Lastly, is there a better way to do things then using BeforeGroups? I
thought about BeoreSuite but I think BeforeGroups would be good in my
case, since I could assign different classes to different groups
easily (which could happen if a different EntityManager is neeeed.)

Also do I need to use 'value" like I have it in the @BeforeGroups? The
docs don't seem to be too clear on it, yet I've read on some posts
that you do need it?

Thanks for any help



Cédric Beust ♔

unread,
Oct 17, 2008, 11:56:36 AM10/17/08
to testng...@googlegroups.com
Quick partial answer:  the value attribute of @BeforeGroups is important since it defines which groups the method will run before.  The groups attribute simply specifies what group that method belongs too. 

Therefore, if you want a method to be run before "group1", you need to say:

@BeforeGroups(value = "group1")
...

--
Cedric

--
Cédric


Rick

unread,
Oct 17, 2008, 1:21:02 PM10/17/08
to testng...@googlegroups.com
On Fri, Oct 17, 2008 at 11:56 AM, Cédric Beust ♔ <cbe...@google.com> wrote:
Quick partial answer:  the value attribute of @BeforeGroups is important since it defines which groups the method will run before.  The groups attribute simply specifies what group that method belongs too. 

Therefore, if you want a method to be run before "group1", you need to say:

@BeforeGroups(value = "group1")
 

Ok thanks for your time Cédric, although this is interesting and maybe it has something to do with my original problem,... if I just use the value="group1" without defining groups="group1" I don't get the @BeforeGroups running at all? Is that normal? (in my example  the groups is test-hsqldb http://pastie.org/294673 ),

(Of course I'm still stumped on the @BeforeGroups and why it's running after my @BeforeClass. I'm trying all different combinations of things and can't get it to work. It's driving me nuts:)

Thanks again.

Cédric Beust ♔

unread,
Oct 17, 2008, 1:29:58 PM10/17/08
to testng...@googlegroups.com
Hi Rick,

On Fri, Oct 17, 2008 at 10:21 AM, Rick <ric...@gmail.com> wrote:


Ok thanks for your time Cédric, although this is interesting and maybe it has something to do with my original problem,... if I just use the value="group1" without defining groups="group1" I don't get the @BeforeGroups running at all? Is that normal? (in my example  the groups is test-hsqldb http://pastie.org/294673 ),

Yes, if you have no group "group1", methods annotated with @BeforeGroups("group1") will not run.  Not sure why you would want them to?

 

(Of course I'm still stumped on the @BeforeGroups and why it's running after my @BeforeClass. I'm trying all different combinations of things and can't get it to work. It's driving me nuts:)

The order of execution for @BeforeGroups and @BeforeClass methods is non-deterministic, and I can't really come up with a good reason why one should always run before the other, to be honest.

If you need such a guarantee, you can always hard code it yourself:

@BeforeGroups("group1")
public void bg() {
  alwaysRun();
  //  rest of the method
}

@BeforeClass
  public void bc() {
    alwaysRun();
   // rest of the method
 }

and in alwaysRun(), put some code to make sure it only gets run once, in case it matters...

--
Cédric


Rick

unread,
Oct 17, 2008, 2:00:59 PM10/17/08
to testng...@googlegroups.com
On Fri, Oct 17, 2008 at 1:29 PM, Cédric Beust ♔ <cbe...@google.com> wrote:
Hi Rick,

On Fri, Oct 17, 2008 at 10:21 AM, Rick <ric...@gmail.com> wrote:


Ok thanks for your time Cédric, although this is interesting and maybe it has something to do with my original problem,... if I just use the value="group1" without defining groups="group1" I don't get the @BeforeGroups running at all? Is that normal? (in my example  the groups is test-hsqldb http://pastie.org/294673 ),

Yes, if you have no group "group1", methods annotated with @BeforeGroups("group1") will not run.  Not sure why you would want them to?

What I meant was that if I "just" have
@BeforeGroups(value="group1") it doesn't run, even though there are some tests annotated with groups="group1".

I don't mind adding the @BeforeGroups as @BeforeGroups(value="group1", groups="group1"), I was just a bit unclear of the behavior since in your email response you only included @BeforeGroups(value="group1").  (I also didn't see anything about using value="xyz" in the docs http://testng.org/doc/documentation-main.html, is it only talked about in the API docs maybe?)

 


 

(Of course I'm still stumped on the @BeforeGroups and why it's running after my @BeforeClass. I'm trying all different combinations of things and can't get it to work. It's driving me nuts:)

The order of execution for @BeforeGroups and @BeforeClass methods is non-deterministic, and I can't really come up with a good reason why one should always run before the other, to be honest.

If you need such a guarantee, you can always hard code it yourself:

@BeforeGroups("group1")
public void bg() {
  alwaysRun();
  //  rest of the method
}

@BeforeClass
  public void bc() {
    alwaysRun();
   // rest of the method
 }

and in alwaysRun(), put some code to make sure it only gets run once, in case it matters...
 

Ok, I see what you are doing there, and thanks, but I think I'm missing a best practice that must come up quite often, so I'd appreciate your input on 'the way you'd do it" since you're the master:)

I'll speak genically...

//group1
Class FooA  w/ test1 test2 test3.
Class FooB w/ test4 test5 test 6
.. others

//group2
Class FooC w/ test7, 8, 9
Class FooD w/test 10, 11, 12
...others

In each of the Classes there is an object (ok if static),  that needs to be be initalized ONCE per class, which each of the tests in the class will use. (This is what I thought @BeforeClass would be good for.)

However, that object in each class that gets initialized (just once) is dependent on something that all the classes in the group share, which is why I thought a BeforeGroups would work.

To be more specific, I'm working on completing this lesson on using Maven with EJB3 http://learntechnology.net/content/ejb/maven-ejb3.jsp and want to add the testing portion and would like to demonstrate the testing of the JPA components with TestNG. I almost have it once I get this nailed down.

Each TestClass which will have CRUD methods which needs a POJO(the dao) that is initialized with an EntityManager. In real life we might have different EntityManagers since we will be going against different DBs for some of the code. So some of the tests will use POJOs initialized with one EM the other ones will have POJO initialized with a different EM.

I took out the loggin so you can quickly see what I'm trying to accomplish:
http://pastie.org/294815

Maybe I'll just @BeforeGroups to initialize the correct static EntityManager and then in each Class use @BeforeTest to initialize the DAO each time with the EntityManager. (Just seemed a waste to do that for each test in the class when it really only needs to be done per class instance.)

Thanks again for your time. I don't want to put a lesson up on the web and steer others in the wrong direction, so I'd like to nail down the best approach.


rickcr

unread,
Oct 17, 2008, 5:29:55 PM10/17/08
to testng-users
Actually it looks like @BeforeGroups isn't even guaranteed to run
before the @BeforeTest either? What's odd (in my opinion) is that
@BeforeSuite does run before anything in the suite, wouldn't it maybe
make sense to have a hierarchy of when the different @BeforeXXX events
fire? @BeforeSuite -->@BeforeGroups --> @BeforeClass -->
@BeforeTest?

rickcr

unread,
Oct 17, 2008, 6:03:26 PM10/17/08
to testng-users
Ok here is what I finally come up and would appreciate any
recommendations on a better approach:

http://pastie.org/294961

Basically the subclass @BeforeClass is responsible for calling it's
parent's setUp(correctEntityManagerName) method.

It should work ok I guess. I still think it would be cleaner toggling
that setup somehow based off of the group that the test class is
assigned to. I'll have to see if that's possible (which is what I
thought I'd be doing with @BeforeGroups.)

Thanks again for feedback/ comments.
Reply all
Reply to author
Forward
0 new messages