horizon-test: Support for Parallel execution & report fix.
parent
823c84c95d
commit
823c8cfcd5
|
|
@ -13,27 +13,31 @@ import com.utopiadeals.framework.BrowserContextManager;
|
|||
import org.junit.jupiter.api.extension.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ExtentReportExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, TestWatcher, TestExecutionExceptionHandler {
|
||||
public class ExtentReportExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, TestWatcher, TestExecutionExceptionHandler {
|
||||
|
||||
private static ExtentReports extent;
|
||||
private static final Map<String, ExtentTest> suite = new ConcurrentHashMap<>();
|
||||
private static final ThreadLocal<ExtentTest> test = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
if (extent == null) {
|
||||
createExtentReports();
|
||||
}
|
||||
|
||||
suite.computeIfAbsent(getClassName(context), k -> extent.createTest(getClassName(context)));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws Exception {
|
||||
public void afterAll(ExtensionContext context) {
|
||||
if (extent != null) {
|
||||
extent.flush();
|
||||
}
|
||||
|
|
@ -48,13 +52,23 @@ public class ExtentReportExtension implements BeforeAllCallback, AfterAllCallbac
|
|||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) throws Exception {
|
||||
String className = context.getTestClass().map(Class::getSimpleName).orElse("Unknown");
|
||||
String testName = context.getTestMethod().map(m -> m.getName()).orElse("Unknown Test");
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String className = getClassName(context);
|
||||
String methodName = getMethodName(context);
|
||||
|
||||
ExtentTest extentTest = extent.createTest(testName)
|
||||
.assignCategory(className);
|
||||
test.set(extentTest);
|
||||
ExtentTest testSuite = suite.get(className);
|
||||
if (testSuite != null) {
|
||||
ExtentTest extentTestNode = testSuite.createNode(methodName);
|
||||
test.set(extentTestNode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) {
|
||||
// Do not clear the ThreadLocal here because JUnit invokes TestWatcher callbacks
|
||||
// (testSuccessful/testFailed/testAborted) after AfterEach, which would make test.get() null
|
||||
// inside those callbacks and cause NPEs. The ThreadLocal will be overwritten in beforeEach
|
||||
// for the next test method and cleared at JVM end.
|
||||
}
|
||||
|
||||
private void createExtentReports() {
|
||||
|
|
@ -152,5 +166,17 @@ public class ExtentReportExtension implements BeforeAllCallback, AfterAllCallbac
|
|||
}
|
||||
}
|
||||
|
||||
private String getClassName(ExtensionContext context) {
|
||||
return context.getTestClass()
|
||||
.map(Class::getSimpleName)
|
||||
.orElse("UnknownClass");
|
||||
}
|
||||
|
||||
private String getMethodName(ExtensionContext context) {
|
||||
return context.getTestMethod()
|
||||
.map(Method::getName)
|
||||
.orElse("UnknownMethod");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
package apitestsuites;
|
||||
|
||||
import com.utopiadeals.api.RestWebCall;
|
||||
import com.utopiadeals.framework.extensions.ExtentReportExtension;
|
||||
import com.utopiadeals.utils.config.Constants;
|
||||
import io.restassured.response.Response;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
@ExtendWith(ExtentReportExtension.class)
|
||||
@Tag("access-mgmt-api")
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class AccessManagementApiTest {
|
||||
private static final String BASE_URL = Constants.getApiBaseUrl();
|
||||
private static final String USERS_ENDPOINT = "/api/access-management/users";
|
||||
|
|
@ -20,6 +26,7 @@ public class AccessManagementApiTest {
|
|||
private static Integer userId;
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void addUser_WithValidData_ShouldReturnSuccess() {
|
||||
// Arrange
|
||||
apiClient = new RestWebCall(BASE_URL, Constants.getApiTestUserName(), Constants.getApiTestPassword());
|
||||
|
|
@ -50,6 +57,7 @@ public class AccessManagementApiTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void getUsers_WithValidEmailId_ShouldReturnSuccess() {
|
||||
// Act
|
||||
apiClient = new RestWebCall(BASE_URL, Constants.getApiTestUserName(), Constants.getApiTestPassword());
|
||||
|
|
@ -62,6 +70,7 @@ public class AccessManagementApiTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void getUsers_WithValidId_ShouldReturnSuccess() {
|
||||
// Act
|
||||
apiClient = new RestWebCall(BASE_URL, Constants.getApiTestUserName(), Constants.getApiTestPassword());
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import com.utopiadeals.framework.annotations.JsonTestDataExtension;
|
|||
import com.utopiadeals.utils.TestDataProvider;
|
||||
import com.utopiadeals.web.pages.LoginPage;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
public class LoginTest extends WebTestSuiteBase {
|
||||
|
||||
|
||||
@DisplayName("Login Test")
|
||||
@Tag("LoginTest")
|
||||
@ParameterizedTest()
|
||||
@JsonTestDataExtension("dataSet-0,dataSet-1")
|
||||
public void loginTest(TestDataProvider testDataProvider) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
junit.jupiter.execution.parallel.enabled = true
|
||||
# Run test METHODS sequentially within each class to preserve intended order
|
||||
junit.jupiter.execution.parallel.mode.default = same_thread
|
||||
# Allow different test classes to run in parallel
|
||||
junit.jupiter.execution.parallel.mode.classes.default = concurrent
|
||||
|
||||
# Fixed parallelism for class-level concurrency
|
||||
junit.jupiter.execution.parallel.config.strategy = fixed
|
||||
junit.jupiter.execution.parallel.config.fixed.parallelism = 4
|
||||
|
||||
# Execute test methods in the order specified by @Order annotations
|
||||
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$OrderAnnotation
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"dataSets": {
|
||||
"dataSet-0": {
|
||||
"username": "utest@utopiadeals.com",
|
||||
"password": "utest0001"
|
||||
"password": "utest001"
|
||||
},
|
||||
"dataSet-1": {
|
||||
"username": "abdullah@utopiadeals.com",
|
||||
|
|
|
|||
Loading…
Reference in New Issue