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

> Learn to use FrameworkAnnotation for test case metadata in anhtester/automationframeworkselenium. Attach author and category info to TestNG test methods for filtered reporting.

- Repository: [Anh Tester/automationframeworkselenium](https://github.com/anhtester/automationframeworkselenium)
- Tags: how-to-guide
- Published: 2026-02-24

---

**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`](https://github.com/anhtester/automationframeworkselenium/blob/main/src/main/java/com/anhtester/annotations/FrameworkAnnotation.java) with runtime retention to support reflection-based access during test execution.

```java
@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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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.

```java
// 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.

```java
@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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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:

```java
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:

```java
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:

```java
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:

```java
@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:

```java
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:

```java
@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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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`](https://github.com/anhtester/automationframeworkselenium/blob/main/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.