Possible bug: parallel=class with static nested classes

28 views
Skip to first unread message

Rich MacDonald

unread,
May 2, 2024, 8:23:32 PMMay 2
to testng-users
Before I do the work to set up a bug report, I wanted to run an issue by the developers:

A while back, I was struggling with setting up the tests globally to run with 'parallel=class'. I received some help at https://groups.google.com/g/testng-users/c/0bSMJo62Zqc

My solution was to write a file at META-INF/services/org.testing.ITestNGListener with a single line "com.mri.testng.listener.TestNgSuiteListener". That class is:

```
public class TestNgSuiteListener implements ISuiteListener {

@Override
public void onStart(ISuite suite) {
Object parallel = suite.getAttribute("parallel");
if (EqualUtils.equals(parallel, "classes")) {
return;
}
\\LogManager.getLogger(TestNgSuiteListener.class).info("changing suite={} parallel={} to parallel=classes", suite.getName(), parallel);
suite.setAttribute("parallel", "classes");
}
}
```

And it has worked very nicely. Thank you for the previous advice.

I have a convenience abstract superclass test class that lets me easily switch between "setup per class" and "setup per method".
(This class does a lot more environmental setup work which I am not showing.)I am just showing this for setup

```
public abstract class AbstractAppTest {
// either per class or per method
protected abstract boolean isSetupPerClass();

@BeforeClass(alwaysRun = true)
public final void beforeClass() {
if (isSetupPerClass()) {
System.out.println("setupHook-beforeClass="+getClass() + " thread="+Thread.currentThread());
setupHook();
}
beforeClassHook();
}

@BeforeMethod(alwaysRun = true)
public final void beforeMethod() {
if (!isSetupPerClass()) {
System.out.println("setupHook-beforeMethod="+getClass() + " thread="+Thread.currentThread());
setupHook();
}
beforeMethodHook();
}

@AfterClass(alwaysRun = true)
public final void afterClass() {
try {
afterClassHook();
} catch (Exception e) {
e.printStackTrace();
}
if (isSetupPerClass()) {
System.out.println("tearDownHook-afterClass="+getClass() + " thread="+Thread.currentThread());
tearDownHook();
}
}

@AfterMethod(alwaysRun = true)
public final void afterMethod() {
try {
afterMethodHook();
} catch (Exception e) {
e.printStackTrace();
}
if (!isSetupPerClass()) {
System.out.println("tearDownHook-afterMethod="+getClass() + " thread="+Thread.currentThread());
tearDownHook();
}
}

protected void beforeClassHook() {}
protected void afterClassHook() {}
protected void beforeMethodHook() {}
protected void afterMethodHook() {}
protected void setupHook() {}
protected void tearDownHook() {}
}
````

And then the following subclass:

```
public class ChildClass_Test extends AbstractAppTest {

@Override
protected boolean isSetupPerClass() {
return true;
}

//many test methods

public static class Grandchild_Test extends ChildClass_Test {

//a few overrides for different setup, but all the tests are inherited from ChildClass_Test
//Basically, I have a class hierarchy under test, and so a separate test class for each.
//I made this a static inner class because it is very minimal. It was an arbitrary decision.
}
}
```

The problem is that all the tests in ChildClass_Test succeed and all the tests for Grandchild_Test fail.
My app is pre-alpha with still many issues with ThreadLocals, so I have been franctically trying to figure out my bug.

Except that I finally wrote logging to show me the setup/tearDown activity, along with the Thread information. This is the System.out.println code you see in the AbstractAppTest.

And this is what I see in the console. Note that everything is running in a single thread. I am not actually using a testng.xml file here, where I would normally specify multiple threads.

```
setupHook-beforeClass=class Grandchild_Test thread=Thread[#1,main,5,main]
setupHook-beforeClass=class ChildClass_Test thread=Thread[#1,main,5,main]
tearDownHook-afterClass=class Grandchild_Test thread=Thread[#1,main,5,main]
tearDownHook-afterClass=class ChildClass_Test thread=Thread[#1,main,5,main]
```

Note that both classes start setup in the same thread, and run interleaved. This is the reason that my tests break.

After tearing much hair (i.e., before I was smart enough to add logging), I moved the Grandchild_Test class to its own separate file. And that was the fix. The test classes now run sequentially rather than simultaneously, and everything is fine.

So it seems to me that something in the testng code does not handle (1) 'parallel-classes' in a (2) single thread when (3) some classes are static inner classes.

Krishnan Mahadevan

unread,
May 2, 2024, 11:23:43 PMMay 2
to testng...@googlegroups.com
Rich,

I would request you to please help create a simple standalone project (that uses only TestNG), upload it to GitHub and share the link here, so that we can use that to reproduce the issue that you are experiencing.

Also, please add the expected output as well to the project’s README.md 

This will really help us figure out what is going on in your case.

PS: Please don’t forget to use the latest released version of TestNG ( 7.10.2 as of today)



Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/testng-users/7abb57e2-3ef8-4716-821a-cf9cd9ea0f78n%40googlegroups.com.

Rich MacDonald

unread,
May 3, 2024, 10:49:31 AMMay 3
to testng-users
Krishnan,


This is an eclipse plugin problem. As I was setting up this test repo, I discovered that the problem only occurs when selecting the file (or folder) and running testng. When I created a testng.xml file and ran that instead, the problem went away.

Rich MacDonald

Krishnan Mahadevan

unread,
May 3, 2024, 12:49:03 PMMay 3
to testng...@googlegroups.com
Rich,

If you are sure that this is a TestNG eclipse plugin problem, then can you please help file an issue here https://github.com/testng-team/testng-eclipse/issues along with the sample project so that it can be looked at ?



Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/
Reply all
Reply to author
Forward
0 new messages