Menu

Base Test Infrastructure

Relevant source files

Purpose and Scope

The Base Test Infrastructure provides the foundational test class and lifecycle management for all test cases in the framework. This document covers the BaseTest class, its role in WebDriver lifecycle management, test method setup and teardown hooks, and integration patterns with the broader framework.

For information about test listeners and event handling, see Test Listeners and Event Handling. For TestNG suite configuration, see TestNG Suite Configuration. For data-driven testing patterns, see Data-Driven Testing.


BaseTest Class Overview

The BaseTest class serves as the base class for all test cases in the framework. It provides standardized WebDriver initialization, cleanup, and integration with the framework's listener infrastructure.

Class Structure

BaseTest ├── Extends: CommonPageCMS ├── Listeners: TestListener ├── Methods: │ ├── createDriver(@BeforeMethod) │ ├── closeDriver(@AfterMethod) │ └── createBrowser(utility) 

Key Characteristics:

AspectImplementationPurpose
InheritanceExtends CommonPageCMSProvides access to common page object functionality
Listener Registration@Listeners({TestListener.class})Enables automatic test event handling and reporting
Thread SafetyUses ThreadGuard.protect()Ensures WebDriver instance safety in parallel execution
Lifecycle Management@BeforeMethod / @AfterMethodStandardizes test setup and teardown

Sources: src/test/java/com/anhtester/common/BaseTest.java1-39


BaseTest Inheritance and Integration

Diagram: BaseTest Class Relationships and Framework Integration

The BaseTest class serves as the central integration point between test classes and the framework's core infrastructure. It extends CommonPageCMS to inherit common page interaction methods, registers TestListener for test event handling, and manages WebDriver instances through TargetFactory and DriverManager.

Sources: src/test/java/com/anhtester/common/BaseTest.java1-39 README.md236-588


Test Lifecycle Management

@BeforeMethod: Driver Initialization

The createDriver() method executes before each test method, ensuring a fresh browser instance for every test.

Method Signature and Implementation:

src/test/java/com/anhtester/common/BaseTest.java17-23

Key Operations:

  1. Parameter Acceptance: @Parameters("BROWSER") allows TestNG XML suites to specify browser type
  2. Default Browser: @Optional("chrome") sets Chrome as the default if no parameter is provided
  3. Thread Safety: ThreadGuard.protect() wraps the WebDriver instance to prevent cross-thread access
  4. Driver Creation: new TargetFactory().createInstance(browser) creates the WebDriver based on configuration
  5. Driver Registration: DriverManager.setDriver(driver) stores the driver in ThreadLocal storage
  6. Window Maximization: driver.manage().window().maximize() ensures consistent viewport size

Parameter Resolution:

SourcePriorityExample
TestNG XML <parameter>High<parameter name="BROWSER" value="edge"/>
Method Default @OptionalLow"chrome"

@AfterMethod: Driver Cleanup

The closeDriver() method executes after each test method, ensuring proper resource cleanup.

Method Signature and Implementation:

src/test/java/com/anhtester/common/BaseTest.java25-29

Key Operations:

  1. Soft Assert Finalization: WebUI.stopSoftAssertAll() validates all accumulated soft assertions
  2. Driver Termination: DriverManager.quit() closes the browser and releases resources
  3. Always Execute: alwaysRun = true ensures cleanup occurs even if test fails

Sources: src/test/java/com/anhtester/common/BaseTest.java17-29


Test Execution Lifecycle Flow

Diagram: Test Method Execution Lifecycle in BaseTest

This sequence illustrates the complete lifecycle of a single test method, from WebDriver initialization through test execution to cleanup. The ThreadGuard protection ensures thread safety during parallel execution, while ThreadLocal storage in DriverManager isolates driver instances per thread.

Sources: src/test/java/com/anhtester/common/BaseTest.java17-29


Thread Safety and Parallel Execution

ThreadGuard Protection

The framework uses Selenium's ThreadGuard to prevent cross-thread WebDriver access, which is critical for parallel test execution.

Implementation Pattern:

src/test/java/com/anhtester/common/BaseTest.java20

Thread Safety Mechanism:

ComponentRoleThread Safety Feature
ThreadGuard.protect()Wraps WebDriverThrows exception if accessed from different thread
DriverManager (ThreadLocal)Stores WebDriverMaintains separate instance per thread
@BeforeMethodInitializes per testCreates new driver for each test method

Parallel Execution Support:

TestNG suite files can configure parallel execution levels:

Each thread receives its own WebDriver instance through the ThreadLocal storage pattern, preventing resource contention.

Sources: src/test/java/com/anhtester/common/BaseTest.java20 src/test/resources/suites/CMS/ProfileCMS.xml1-20


Browser Configuration and Parameterization

Parameter-Based Browser Selection

The framework supports dynamic browser selection through TestNG parameters, enabling the same test class to run against multiple browsers.

Configuration Hierarchy:

Diagram: Browser Selection Configuration Flow

Configuration Examples:

TestNG XML Suite:

src/test/resources/suites/CMS/ProfileCMS.xml10

Method Declaration:

src/test/java/com/anhtester/common/BaseTest.java17-19

Sources: src/test/java/com/anhtester/common/BaseTest.java17-19 src/test/resources/suites/CMS/ProfileCMS.xml10


Alternative Initialization: createBrowser() Utility

The BaseTest class provides an alternative driver initialization method for scenarios requiring manual control over the driver lifecycle.

Method Implementation:

src/test/java/com/anhtester/common/BaseTest.java31-37

Key Differences from createDriver():

AspectcreateDriver() (@BeforeMethod)createBrowser() (Utility)
InvocationAutomatic (TestNG lifecycle)Manual (test code calls it)
ScopePer test methodOn-demand
Properties LoadingImplicit (via TargetFactory)Explicit (PropertiesHelpers.loadAllFiles())
Return Valuevoid (driver stored in DriverManager)Returns WebDriver reference
Use CaseStandard test executionCustom setup, multi-driver scenarios

Usage Pattern:

This method is useful for:

  • Tests requiring multiple WebDriver instances
  • Custom initialization sequences
  • Integration tests with specific setup requirements

Sources: src/test/java/com/anhtester/common/BaseTest.java31-37


Integration with Test Classes

Extending BaseTest Pattern

Test classes extend BaseTest to inherit driver lifecycle management and page object access.

Typical Test Class Structure:

Inheritance Benefits:

Inherited FromProvidesUsage
BaseTestDriver lifecycle managementAutomatic setup/teardown
CommonPageCMS (via BaseTest)Common page methodsShared page interactions
Framework accessWebUI keywords, DriverManagerTest implementation

Framework Integration Points:

Diagram: Test Class Integration with BaseTest

Sources: src/test/java/com/anhtester/common/BaseTest.java1-39 README.md318-378


Listener Registration

The BaseTest class uses the @Listeners annotation to automatically register TestListener with all extending test classes.

Listener Registration Pattern:

src/test/java/com/anhtester/common/BaseTest.java14

Listener Responsibilities:

EventTestListener ActionImpact on Tests
onTestStartInitialize ExtentTest, start loggingTest tracking begins
onTestSuccessLog success, capture screenshot (if configured)Success recorded
onTestFailureLog failure, capture screenshot/videoFailure evidence captured
onTestSkippedLog skip reasonSkip recorded
onFinishGenerate reports, send notificationsTest results distributed

Alternative Registration:

TestNG XML suites can also register listeners globally:

src/test/resources/suites/CMS/ProfileCMS.xml5-7

Sources: src/test/java/com/anhtester/common/BaseTest.java14 src/test/resources/suites/CMS/ProfileCMS.xml5-7


WebDriver Lifecycle State Machine

Diagram: WebDriver Lifecycle State Transitions in BaseTest

This state machine illustrates the complete lifecycle of a WebDriver instance managed by BaseTest, from creation through test execution to cleanup. The alwaysRun=true parameter ensures that cleanup occurs even when tests fail, preventing resource leaks.

Sources: src/test/java/com/anhtester/common/BaseTest.java17-29


Common Test Setup Patterns

Pattern 1: Standard Test Execution

The most common pattern leverages automatic driver lifecycle management.

Structure:

Characteristics:

  • Driver automatically initialized before test
  • Driver automatically cleaned up after test
  • No manual driver management required
  • Suitable for 95% of test scenarios

Pattern 2: Parameterized Browser Testing

Tests can run against multiple browsers using TestNG XML parameters.

TestNG Suite:

Characteristics:

  • Same test class runs with different browsers
  • No code changes required
  • Browser specified in suite XML
  • Supports cross-browser testing strategies

Pattern 3: Data-Driven Tests with BaseTest

Data-driven tests combine BaseTest lifecycle with TestNG data providers.

Structure:

Characteristics:

  • @BeforeMethod executes for each data set
  • New driver instance per data iteration
  • Data isolation between test runs
  • Suitable for user journey testing with different inputs

Sources: src/test/java/com/anhtester/common/BaseTest.java1-39 src/test/resources/suites/CMS/ProfileCMS.xml1-20


Summary

The BaseTest class provides the foundation for all test execution in the framework through:

ComponentResponsibilityImplementation
Driver InitializationCreate and configure WebDriver before each test@BeforeMethod createDriver()
Thread SafetyProtect driver from cross-thread accessThreadGuard.protect()
Driver StorageIsolate driver instances per threadDriverManager.setDriver() (ThreadLocal)
Driver CleanupTerminate browser and release resources@AfterMethod closeDriver()
Browser ConfigurationSupport multiple browsers via parameters@Parameters("BROWSER") with @Optional
Listener IntegrationEnable test event handling and reporting@Listeners({TestListener.class})
Page Object AccessProvide common page methods to testsextends CommonPageCMS

Key Files:

Related Pages: