Skip to content

Commit

Permalink
Streamline AfterClass invocation
Browse files Browse the repository at this point in the history
Closes #2726
  • Loading branch information
krmahadevan committed May 9, 2022
1 parent b937a1d commit 6b2e466
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
@@ -1,5 +1,6 @@
Current
7.6.0
Fixed: GITHUB-2726: @AfterClass config method is executed for EACH @Test method when parallel == methods (Krishnan Mahadevan)
Fixed: GITHUB-2752: TestListener is being lost when implenting both IClassListener and ITestListener (Krishnan Mahadevan)
New: GITHUB-2724: DataProvider: possibility to unload dataprovider class, when done with it (Dzmitry Sankouski)
Fixed: GITHUB-217: Configure TestNG to fail when there's a failure in data provider (Krishnan Mahadevan)
Expand Down
3 changes: 2 additions & 1 deletion testng-core/src/main/java/org/testng/ClassMethodMap.java
Expand Up @@ -51,7 +51,8 @@ public ClassMethodMap(List<ITestNGMethod> methods, XmlMethodSelector xmlMethodSe
public boolean removeAndCheckIfLast(ITestNGMethod m, Object instance) {
Collection<ITestNGMethod> l = classMap.get(instance);
if (l == null) {
throw new AssertionError("l should not be null");
throw new IllegalStateException(
"Could not find any methods associated with test class instance " + instance);
}
l.remove(m);
// It's the last method of this class if all the methods remaining in the list belong to a
Expand Down
Expand Up @@ -127,7 +127,9 @@ && doesTaskHavePreRequistes()
try {
invokeTestMethods(testMethod, testMthdInst.getInstance());
} finally {
invokeAfterClassMethods(testMethod.getTestClass(), testMthdInst);
synchronized (testMethod.getInstance()) {
invokeAfterClassMethods(testMethod.getTestClass(), testMthdInst);
}
}
}
}
Expand Down
@@ -1,9 +1,13 @@
package test.configuration;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;
import org.testng.Assert;
import org.testng.TestNG;
import org.testng.annotations.Test;
import org.testng.xml.XmlSuite;
import test.configuration.issue2726.TestClassSample;
import test.configuration.issue2743.SuiteRunnerIssueTestSample;
import test.configuration.sample.ConfigurationTestSample;
import test.configuration.sample.ExternalConfigurationClassSample;
Expand Down Expand Up @@ -39,4 +43,14 @@ public void testSuiteRunnerWithDefaultConfiguration() {

Assert.assertEquals(testNG.getStatus(), 0);
}

@Test(description = "GITHUB-2726")
public void testAfterClassCalledOnlyOnceForParallelTestMethods() {
TestNG testng = create(TestClassSample.class);
testng.setParallel(XmlSuite.ParallelMode.METHODS);
testng.setVerbose(2);
testng.run();
assertThat(TestClassSample.beforeLogs).hasSize(1);
assertThat(TestClassSample.afterLogs).hasSize(1);
}
}
@@ -0,0 +1,29 @@
package test.configuration.issue2726;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestClassSample {

public static final List<String> beforeLogs = new CopyOnWriteArrayList<>();
public static final List<String> afterLogs = new CopyOnWriteArrayList<>();

@BeforeClass
public void setup() {
beforeLogs.add("BEFORE_" + Thread.currentThread().getName());
}

@AfterClass
public void tearDown() {
afterLogs.add("AFTER_" + Thread.currentThread().getName());
}

@Test
public void testA() {}

@Test
public void testB() {}
}

0 comments on commit 6b2e466

Please sign in to comment.