Skip to content

TestNG Foundation is a lightweight collection of TestNG listeners, interfaces, and static utility classes that supplement and augment the functionality provided by the TestNG API.

License

Notifications You must be signed in to change notification settings

yaroslav-orel/TestNG-Foundation

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Maven Central

INTRODUCTION

TestNG Foundation is a lightweight collection of TestNG listeners, interfaces, and static utility classes that supplement and augment the functionality provided by the TestNG API. The facilities provided by TestNG Foundation include two types of runtime listener hooks, test artifact capture, and automatic test context attribute propagation.

Future releases of TestNG Foundation will add automatic retry of failed tests, test execution timeout management, and target platform support. See ExecutionFlowController for more information.

TestNG Listeners

  • ExecutionFlowController:
    ExecutionFlowController is a TestNG listener that propagates test context attributes:
    [before method] → [test method] → [after method]
    For test classes that implement the IInvokedMethodListenerEx interface, ExecutionFlowController forwards calls from its own invoked method listener implementation to the corresponding methods in the test class. In-bound attribute propagation is performed before forwarding the beforeInvocation(IInvokedMethod, ITestResult) call, and out-bound attribute propagation is performed after forwarding the afterInvocation(IInvokedMethod, ITestResult) call.
  • ListenerChain:
    ListenerChain is a TestNG listener that enables you to add other listeners at runtime and guarantees the order in which they're invoked. This is similar in behavior to a JUnit rule chain. ListenerChain also provides static methods that enable you to acquire references to listeners that are linked into the chain.
  • ArtifactCollector:
    ArtifactCollector is a TestNG test listener that serves as the foundation for artifact-capturing test listeners. This is a generic class, with the artifact-specific implementation provided by instances of the ArtifactType interface. See the Interfaces section below for more details.

Interfaces

  • LinkedListener:
    This is a marker interface for listeners that can be linked to the ListenerChain via its service loader.
  • IInvokedMethodListenerEx:
    Test classes that implement the IInvokedMethodListenerEx interface are hooked in by the invoked method listener implementation of ExecutionFlowController. See the TestNG Listeners section above for more details.
  • ArtifactType:
    Classes that implement the ArtifactType interface provide the artifact-specific methods used by the ArtifactCollector listener to capture and store test-related artifacts. The unit tests for this project include a reference implementation (UnitTestArtifact) provides a basic outline for a scenario-specific artifact provider. This artifact provider is specified as the superclass type parameter in the UnitTestCapture listener, which is a lightweight extension of ArtifactCollector. The most basic example is shown below:
Implementing ArtifactType
package com.example;

import java.nio.file.Path;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.ITestResult;

import com.nordstrom.automation.testng.ArtifactType;

public class MyArtifactType implements ArtifactType {
    
    private static final String ARTIFACT_PATH = "artifacts";
    private static final String EXTENSION = "txt";
    private static final String ARTIFACT = "This text artifact was captured for '%s'";
    private static final Logger LOGGER = LoggerFactory.getLogger(MyArtifactType.class);

    @Override
    public boolean canGetArtifact(ITestResult result) {
        return true;
    }

    @Override
    public byte[] getArtifact(ITestResult result) {
        return String.format(ARTIFACT, result.getName()).getBytes().clone();
    }

    @Override
    public Path getArtifactPath(ITestResult result) {
        return ArtifactType.super.getArtifactPath(result).resolve(ARTIFACT_PATH);
    }
    
    @Override
    public String getArtifactExtension() {
        return EXTENSION;
    }

    @Override
    public Logger getLogger() {
        return LOGGER;
    }
}
Creating a type-specific artifact collector
package com.example;

import com.nordstrom.automation.testng.ArtifactCollector;

public class MyArtifactCapture extends ArtifactCollector<MyArtifactType> {
    
    public MyArtifactCapture() {
        super(new MyArtifactType());
    }
    
}

The preceding code is an example of how the artifact type definition is assigned as the type parameter in a subclass of ArtifactCollector. Because TestNG listeners are specified solely by their class, type-specific artifact collectors must be declared this way.

Annotations

  • LinkedListeners:
    To attach listeners to an active ListenerChain, mark your test class with the @LinkedListeners annotation.

Static Utility Classes

  • PropertyManager:
    PropertyManager contains two static methods used to propagate attributes from one test context to another:
    • extractAttributes() - Extracts all of the attributes of the specified test context into a map.
    • injectAttributes() - Injects all of the entries of the specified map into the specified test context as attributes.

ExecutionFlowController, ListenerChain, and the ServiceLoader

If ExecutionFlowController is the only listener you need, or if the order in which your listeners are invoked is inconsequential, the TestNG @Listeners annotation is a perfectly fine method to activate your listeners. However, if you need to activate multiple listeners that must be invoked in a specific order, use ListenerChain and activate it via the ServiceLoader as described in the TestNG documentation:

org.testng.ITestNGListener
com.nordstrom.automation.testng.ListenerChain

In a Maven project, the preceding file is stored in the src/main/resources folder:

com.testng.ITestNGListener

Once this file is added to your project, ListenerChain will be loaded automatically whenever you run your tests. To link listeners into the chain, you have two options:

  1. Specify listeners to attach via the ListenerChain service loader.
  2. Mark your test class with the @LinkedListeners annotation.

These options are not mutually exclusive; you can freely apply both within the same project.

Specifying listeners to attach via the ListenerChain service loader

Listeners that you wish to attach via the ListenerChain service loader must implement the LinkedListener interface:

Service-loaded listener example
package com.example

import org.testng.IClassListener;

import com.nordstrom.automation.testng.LinkedListener;

public class ServiceLoadedListener implements IClassListener, LinkedListener {

    @Override
    public void onBeforeClass(ITestClass testClass) {
        ...
    }

    @Override
    public void onAfterClass(ITestClass testClass) {
        ...
    }
}

To specify the listener(s) you wish to attach via the ListenerChain service loader, create a file at location
META-INF/services/com.nordstrom.automation.testng.LinkedListener and indicate the listener(s) you want to be linked in:

com.nordstrom.automation.testng.LinkedListener
com.example.ServiceLoadedListener

In a Maven project, the preceding file is stored in the src/main/resources folder:

com.testng.ITestNGListener

In this example, we've specified a single listener (ServiceLoadedListener) that should be attached via the ListenerChain service loader. If additional listeners had been specified, each of them would be attached in the order they're specified.

Marking your test class with the @LinkedListeners annotation

With the @LinkedListeners annotation, you specify one or more listener types to attach to the ListenerChain:

LinkedListeners annotation
package com.example;
 
import com.nordstrom.automation.selenium.listeners.DriverListener;
import com.nordstrom.automation.testng.ExecutionFlowController;
import com.nordstrom.automation.testng.LinkedListeners;
import com.nordstrom.automation.testng.ListenerChain;
 
@LinkedListeners({DriverListener.class, ExecutionFlowController.class})
public class ExampleTest {
    
    ...
    
}

As shown above, we use the @LinkedListeners annotation to attach DriverListener and ExecutionFlowController. The order in which listener methods are invoked is determined by the order in which listener objects are added to the chain. Listener before methods are invoked in last-added-first-called order. Listener after methods are invoked in first-added-first-called order. Only one instance of any given listener class will be included in the chain.

About

TestNG Foundation is a lightweight collection of TestNG listeners, interfaces, and static utility classes that supplement and augment the functionality provided by the TestNG API.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%