How to Use FrameworkAnnotation for Test Case Metadata in the Selenium Automation Framework

The FrameworkAnnotation is a custom Java annotation that attaches author and category metadata directly to TestNG test methods, enabling filtered reporting and traceability in the anhtester/automationframeworkselenium repository.

The anhtester/automationframeworkselenium repository provides a robust TestNG-based automation framework that uses custom annotations to streamline test metadata management. By attaching author and category information directly to test methods using the FrameworkAnnotation interface, teams can generate detailed reports filtered by ownership or test type without external configuration files.

FrameworkAnnotation Structure and Definition

The custom annotation is defined in src/main/java/com/anhtester/annotations/FrameworkAnnotation.java with runtime retention to support reflection-based access during test execution.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FrameworkAnnotation {
    AuthorType[] author();          // one or more authors
    CategoryType[] category();      // one or more categories
}

The @Retention(RUNTIME) policy ensures the annotation persists through the JVM execution phase, while @Target(METHOD) restricts usage to method declarations. This design aligns with TestNG test method requirements and allows the framework's listeners to extract metadata via Java reflection.

Supporting Enums for Metadata Values

The annotation relies on two enumeration classes to maintain consistent metadata values across the test suite.

AuthorType (src/main/java/com/anhtester/enums/AuthorType.java) enumerates possible test owners such as AnhTester, AnVo, or James. CategoryType (src/main/java/com/anhtester/enums/CategoryType.java) defines test classifications including REGRESSION, SMOKE, and SANITY. Using enums prevents typos and ensures consistent reporting categories across large test suites.

Applying FrameworkAnnotation to Test Methods

To use the annotation, place it directly above any TestNG @Test method and supply the desired enum values as array elements.

// src/test/java/com/anhtester/projects/crm/testcases/ClientTest.java
@FrameworkAnnotation(
        author   = {AuthorType.AnhTester, AuthorType.AnVo},
        category = {CategoryType.REGRESSION})
@Test(priority = 1, description = "Test Add New Client",
      dataProvider = "getClientDataHashTable",
      dataProviderClass = DataProviderManager.class)
public void testAddClient(Hashtable<String, String> data) {
    // test steps …
}

You can assign multiple values to either field by separating enum constants with commas. This flexibility allows tests to appear in multiple report categories simultaneously.

@FrameworkAnnotation(
        author   = {AuthorType.James},
        category = {CategoryType.SANITY, CategoryType.REGRESSION})
@Test(priority = 2, description = "TC06_testSearchClient")
public void testSearchClient() {
    // test steps …
}

Consuming Metadata with the TestListener

The TestListener class (src/test/java/com/anhtester/listeners/TestListener.java) reads the annotation at runtime using reflection and injects the metadata into reporting layers including Allure and ExtentReports.

The listener extracts author information through the getAuthorType method:

public AuthorType[] getAuthorType(ITestResult iTestResult) {
    if (iTestResult.getMethod().getConstructorOrMethod()
            .getMethod().getAnnotation(FrameworkAnnotation.class) == null) {
        return null;
    }
    return iTestResult.getMethod().getConstructorOrMethod()
            .getMethod().getAnnotation(FrameworkAnnotation.class).author();
}

Similarly, the getCategoryType method retrieves category data:

public CategoryType[] getCategoryType(ITestResult iTestResult) {
    if (iTestResult.getMethod().getConstructorOrMethod()
            .getMethod().getAnnotation(FrameworkAnnotation.class) == null) {
        return null;
    }
    return iTestResult.getMethod().getConstructorOrMethod()
            .getMethod().getAnnotation(FrameworkAnnotation.class).category();
}

During the onTestStart lifecycle event, the listener forwards these values to the reporting utilities:

ExtentReportManager.addAuthors(getAuthorType(iTestResult));
ExtentReportManager.addCategories(getCategoryType(iTestResult));

This integration ensures that generated HTML reports display author attribution and category tags for every test method, enabling filtered views by owner or test type.

Practical Implementation Examples

Single Author and Category Assignment

Assign one author and one category for straightforward test classification:

@FrameworkAnnotation(
        author   = {AuthorType.AnhTester},
        category = {CategoryType.SMOKE})
@Test
public void verifyLoginPageTitle() {
    // test steps …
}

Manual Reflection Access

Access annotation values programmatically outside the standard listener flow:

Method method = this.getClass()
        .getMethod("verifyLoginPageTitle");
if (method.isAnnotationPresent(FrameworkAnnotation.class)) {
    FrameworkAnnotation meta = method.getAnnotation(FrameworkAnnotation.class);
    System.out.println("Authors: " + Arrays.toString(meta.author()));
    System.out.println("Categories: " + Arrays.toString(meta.category()));
}

Custom Logging Integration

Extend the listener to log categories upon test completion:

@Override
public void onTestSuccess(ITestResult result) {
    CategoryType[] cats = getCategoryType(result);
    if (cats != null) {
        LogUtils.info("Test passed with categories: " + Arrays.toString(cats));
    }
    // existing success handling …
}

Summary

  • FrameworkAnnotation is defined in src/main/java/com/anhtester/annotations/FrameworkAnnotation.java with runtime retention and method-level targeting.
  • The annotation accepts arrays of AuthorType and CategoryType enums, supporting multiple values per test.
  • TestListener (src/test/java/com/anhtester/listeners/TestListener.java) extracts metadata via reflection using getAuthorType() and getCategoryType() methods.
  • Extracted metadata feeds directly into ExtentReportManager for HTML reporting and filtering capabilities.
  • Co-locating metadata with test code improves maintainability and eliminates separate configuration management.

Frequently Asked Questions

What is the primary purpose of FrameworkAnnotation in the automation framework?

The annotation attaches descriptive metadata—specifically author ownership and test category classification—directly to TestNG test methods. This enables the framework to generate reports filtered by team member or test type (smoke, regression, sanity) without requiring external CSV or XML configuration files.

Can multiple authors be assigned to a single test case?

Yes. The author() element in FrameworkAnnotation is defined as AuthorType[], allowing you to specify multiple authors using array syntax: author = {AuthorType.AnhTester, AuthorType.AnVo}. The TestListener processes all values and associates them with the test in the final report.

How does the framework handle tests without FrameworkAnnotation?

The getAuthorType() and getCategoryType() methods in TestListener return null when the annotation is absent. The reporting utilities handle null values gracefully, typically omitting author or category labels for those specific test cases rather than throwing exceptions.

Where should new test categories be defined when extending the framework?

New categories must be added to the CategoryType enum in src/main/java/com/anhtester/enums/CategoryType.java. Adding values to this enum automatically makes them available to the FrameworkAnnotation without requiring changes to the listener or reporting logic, as the reflection-based extraction works with any enum constant defined in the class.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →