Skip to content

a-oleynik/testng-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TestNG 7 Workshop Examples

Java Maven TestNG AssertJ Hamcrest Lombok License

Companion code for the IT Talk "JUnit 6 vs TestNG 7". Previous edition: TestNG vs. JUnit 4 slides · TestNG vs. JUnit 4 webinar

Related projects:


📋 Table of Contents


👥 Who Is This For?

Audience What you will get
QA engineers new to TestNG A guided tour of every major feature with runnable examples
Java developers migrating from JUnit 4 / JUnit 5+ Side-by-side comparison of patterns and idioms
Senior / lead engineers Deep-dives into listeners, retry strategies, parallel execution, and groups
Workshop facilitators A ready-made project you can hand to attendees

📦 Prerequisites

Tool Minimum version Notes
JDK 21 LTS
Maven 3.9+
IDE Any (IntelliJ IDEA recommended) Lombok plugin required for IDE support
Lombok plugin Latest IntelliJ: Settings → Plugins → Lombok

🚀 Quick Start

git clone https://github.com/a-oleynik/testng-workshop.git
cd testng-workshop
mvn clean test

🧩 Supported Versions

Library Version used
TestNG 7.12.0
AssertJ 3.27.7
Hamcrest 3.0
Lombok 1.18.42
OpenCSV 5.12.0
SLF4J 2.0.17
Java source / target 21

🌍 Feature Map

Package / folder Feature demonstrated Test class(es)
general Basic assertions (assertEquals, assertTrue, assertNull, assertSame, …) AssertTest
general Exception testing (expectedExceptions, expectedExceptionsMessageRegExp) ExceptionTest
general Test fixtures (@BeforeSuite, @AfterSuite, @BeforeClass, @AfterClass, @BeforeTest, @AfterTest, @BeforeMethod, @AfterMethod) FixturesTest
general Hamcrest matchers HamcrestTest
general Timeouts (timeOut attribute on @Test) TimeoutTest
general Disabling & skipping tests (enabled = false, SkipException) DisabledTest
general Test descriptions (description attribute on @Test) DescriptionTest
group/asserts Soft assertions (SoftAssert) SoftAssertTest
conditional Assumptions via AssertJ (assumeThat) per method AssumeTest
conditional Assumptions in @BeforeClass to skip entire class AssumeBeforeClassTest
ddt Static inline @DataProvider StaticDataProviderTest
ddt Dynamic CSV-file @DataProvider (Iterator-based) DynamicDataProviderTest
ddt External @DataProvider class (dataProviderClass) OuterDataProviderTest
nested Inner test classes grouped under a parent class NestedTest
grouping Groups (@Test(groups = …)), @BeforeGroups, @AfterGroups GroupTest
dependencies Method & group dependencies (dependsOnMethods, dependsOnGroups) DependenciesTest
execution/order Test execution ordering via priority attribute ExecutionOrderTest
listeners ITestListener — observe test start, success, failure, skip TestListenerTest
listeners IInvokedMethodListener — intercept before/after every method invocation MethodListenerTest
retry Retry with IRetryAnalyzer + custom @Retries annotation RetryTest
retry Retry with IAnnotationTransformer (RetryTransformer) applied globally via XML RetryTransformerTest
repeat Repeated execution (invocationCount attribute on @Test) RepeatedTest

🌱 Learning Path — Beginners

Work through these topics in order; each builds on the previous one.

  1. Basic assertionsAssertTest
    Learn assertEquals, assertTrue, assertNull, assertSame, assertNotSame, and fail.

  2. Test lifecycleFixturesTest
    Understand the full TestNG fixture hierarchy: @BeforeSuite@BeforeTest@BeforeClass@BeforeMethod (and their After* counterparts).

  3. Exception testingExceptionTest
    Use expectedExceptions and expectedExceptionsMessageRegExp on @Test to assert thrown exceptions.

  4. Disabling & skipping testsDisabledTest
    Disable tests with @Test(enabled = false) or skip them dynamically by throwing SkipException.

  5. Test descriptionsDescriptionTest
    Add human-readable descriptions to tests with @Test(description = "…") for better report output.

  6. Hamcrest matchersHamcrestTest
    Write expressive assertions with assertThat, equalTo, is, closeTo, both…and, and more.

  7. Soft assertionsSoftAssertTest
    Collect all assertion failures with SoftAssert before reporting — no early bail-out.

  8. AssumptionsAssumeTest
    Skip tests dynamically when preconditions aren't met using AssertJ's assumeThat.

  9. Parameterized testsStaticDataProviderTest
    Drive one test method with multiple data rows using an inline @DataProvider.

  10. GroupsGroupTest
    Mark tests as Smoke or Regression and run subsets from the command line or via XML suites.

Run the whole beginner suite:

mvn clean test

🎯 Advanced Topics — Path for Senior Engineers

These topics assume familiarity with TestNG basics.

1. Groups, @BeforeGroups / @AfterGroups

GroupTestgrouping/ package
Assign tests to named groups. Use @BeforeGroups and @AfterGroups for group-scoped setup/teardown.
Run groups from the command line:

mvn clean test -Dgroups=Regression,Smoke

Or target a specific XML suite that filters by group:

# Run only Smoke tests via XML
mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testnggroups2.xml

# Run groups-of-groups (Smoke + Regression + Fail) via XML
mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testnggroups1.xml

2. Test Dependencies

DependenciesTestdependencies/ package
Chain tests so that a downstream test is skipped (not failed) when its upstream dependency fails, using dependsOnMethods or dependsOnGroups.

3. CSV & External Data Providers

DynamicDataProviderTest, OuterDataProviderTestddt/ package

  • Load test data lazily from CSV files via an Iterator-based @DataProvider.
  • Separate data-provider logic into a dedicated MyDataProvider class and reference it with dataProviderClass.
  • Use the custom @DataSource(path = "…") annotation to bind a CSV file path to a test method at runtime.

4. Nested Test Classes

NestedTestnested/ package
Group related scenarios (Multiply, Divide, Add) as public inner classes inside a parent class. Run them via testnested.xml:

mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testnested.xml

5. Test Execution Order

ExecutionOrderTestexecution/order/ package
Control method execution order with the priority attribute on @Test (lower value = earlier execution). Methods without a priority run before prioritized ones.

6. Listeners

TestListenerTest, MethodListenerTestlisteners/ package

  • ITestListener (MyTestListener) — react to test start, success, failure, and skip events. Ideal for screenshot capture on failure.
  • IInvokedMethodListener (MyMethodListener) — intercept every method invocation (including @Before* / @After*).
  • TestListenerAdapter (MyExtendedTestListener) — extend the adapter and override only the callbacks you need.
    Attach listeners declaratively with @Listeners(value = MyTestListener.class) or globally via a testng.xml <listeners> block.

7. Retry Strategies

RetryTestIRetryAnalyzer + custom @Retries(limit = N) annotation applied per test method
RetryTransformerTestIAnnotationTransformer (RetryTransformer) injects RetryAnalyzer globally for every test in the suite without touching test source code

Run the transformer-based retry suite:

mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testngretrylistener.xml

8. Parallel Execution

Configured globally in pom.xml via Surefire:

<parallel>methods</parallel>
<threadCount>3</threadCount>

Tests run concurrently by default. Fine-tune parallelism per suite with parallel="classes" or parallel="tests" and a custom thread-count in any testng.xml.

9. TestNG XML Suites

All suite XML files live in src/test/resources/. They demonstrate:

File What it shows
testng1.xml Include / exclude specific test methods per class
testng2.xml Run a fixed set of classes in parallel
testnggroups1.xml Groups-of-groups — combine named groups under one alias
testnggroups2.xml Include only the Smoke group
testngretrylistener.xml Register RetryTransformer listener globally
testnested.xml Run all tests from a package (including inner classes)

Run any suite directly:

mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testng1.xml

10. Surefire HTML Report Generation

mvn clean surefire-report:report
# or
mvn clean site

Reports are written to target/site/surefire-report.html


💻 Command Examples

Run all tests (and generate the reports)

mvn clean test

Reports are written to:

  • Surefire report: target/surefire-reports/index.html
  • TestNG emailable report: target/surefire-reports/emailable-report.html

Run a single test class

mvn clean test -Dtest=AssertTest

Run a single test method

mvn clean test -Dtest=AssertTest#assert_equals_multiplication_test

Run multiple test classes

mvn clean test -Dtest=AssertTest,HamcrestTest

Run test methods matching a pattern

mvn clean test -Dtest=AssertTest#assert_equals*

Run test methods matching multiple patterns

mvn clean test -Dtest=AssertTest#assert_equals*+assert_boolean*

Run tests by group

mvn clean test -Dgroups=Regression,Smoke

Run a specific TestNG XML suite

mvn clean test -Dsurefire.suiteXmlFiles=src/test/resources/testng1.xml

Compile, test, package, and install to local repo

mvn clean install

Skip tests (compile + package + install to local repo without running tests)

mvn clean install -DskipTests

Generate Surefire HTML report (quick)

mvn clean surefire-report:report

Surefire report is written to:

  • Surefire report: target/reports/surefire.html

Enable full debug logging for troubleshooting

mvn clean test -X

📁 Project Structure

src/
├── main/java/com/oleynik/qa/workshop/testng/
│   ├── model/           # Domain model (User, MyDoubleWrapper)
│   ├── annotations/     # Custom annotations (@Retries, @DataSource)
│   ├── dataproviders/   # Reusable data provider (MyDataProvider)
│   ├── listeners/       # ITestListener, IInvokedMethodListener, IAnnotationTransformer
│   ├── retry/           # IRetryAnalyzer implementation (RetryAnalyzer)
│   ├── Factorial.java   # Utility class used by data-driven tests
│   └── Utils.java       # Shared test utilities (e.g. waitFor)
└── test/java/com/oleynik/qa/workshop/testng/
    ├── general/         # Core assertions, fixtures, exceptions, descriptions, timeouts
    ├── group/asserts/   # Soft assertions
    ├── conditional/     # Assumptions (AssertJ assumeThat)
    ├── ddt/             # Data-driven tests (@DataProvider, CSV, external provider)
    ├── nested/          # Inner-class test grouping
    ├── grouping/        # TestNG groups (@Test(groups = …))
    ├── dependencies/    # Test dependencies (dependsOnMethods / dependsOnGroups)
    ├── execution/order/ # Test execution ordering (priority)
    ├── listeners/       # Tests demonstrating listener hooks
    ├── retry/           # Retry strategies (IRetryAnalyzer, IAnnotationTransformer)
    └── repeat/          # Repeated execution (invocationCount)

📝 License

This project is licensed under the MIT License — see the LICENSE file for details.


📚 Additional Resources


🔗 Useful Links

About

TestNG examples for IT talk "JUnit 6 vs. TestNG 7"

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages