Skip to content

[TestNG] Class-level <parameter> overrides from testng.xml are ignored — report shows the <test>-level value #1359

Description

@mmajcherczyk

What happened?

Describe the bug

TestNG resolves suite XML parameters with the most-specific scope winning: a <class>-level <parameter> overrides the <test>-level one, which overrides the <suite>-level one. Values injected via @Parameters (e.g. into @BeforeMethod/@Test methods) respect this correctly.

However, allure-testng attaches XML parameters to every test result using only the <test>-level map:

https://github.com/allure-framework/allure-java/blob/master/allure-testng/src/main/java/io/qameta/allure/testng/AllureTestNg.java#L1041-L1046

context.getCurrentXmlTest().getAllParameters()
        .forEach((name, value) -> result.put(name, createParameter(name, value)));

XmlTest#getAllParameters() merges suite + test parameters but knows nothing about XmlClass local parameters. As a result, for any test method that does not inject the parameter itself, the Allure report shows the <test>-level value even when the class overrides it — i.e. the report claims a configuration the test did not actually run with.

Real-world impact: our @BeforeMethod browser fixture consumes a headless parameter. One class overrides it to false at <class> level (and the browser really starts headed — verified), but every test of that class is reported in Allure / Allure TestOps with headless: true.

Steps to reproduce

testng.xml:

<suite name="Repro" parallel="methods" thread-count="2">
    <test name="Repro">
        <parameter name="headless" value="true"/>
        <classes>
            <class name="example.NoOverrideTest"/>
            <class name="example.OverrideTest">
                <parameter name="headless" value="false"/>
            </class>
        </classes>
    </test>
</suite>

NoOverrideTest.java:

package example;

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class NoOverrideTest {
    @Parameters("headless")
    @Test
    public void injectingTest(@Optional("missing") String headless) {
        System.out.println(headless); // prints "true"
    }
}

OverrideTest.java:

package example;

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class OverrideTest {
    @Parameters("headless")
    @Test
    public void injectingTest(@Optional("missing") String headless) {
        System.out.println(headless); // prints "false" — TestNG applies the class-level override
    }

    @Test
    public void plainTest() {
        // does not inject the parameter itself
    }
}

Run the suite and inspect allure-results/*-result.json:

Test Actual effective value parameters in result.json
NoOverrideTest.injectingTest true headless: true
OverrideTest.injectingTest false headless: false ✅ (method argument wins over the XML map)
OverrideTest.plainTest false (class-level override) headless: true

Expected behavior

OverrideTest.plainTest should be reported with headless: false. XML parameters attached to a test result should be resolved the same way TestNG resolves them, i.e. XmlClass local parameters should be merged over XmlTest parameters, for example:

context.getCurrentXmlTest().getAllParameters()
        .forEach((name, value) -> result.put(name, createParameter(name, value)));
final XmlClass xmlClass = method.getTestClass().getXmlClass();
if (Objects.nonNull(xmlClass)) {
    xmlClass.getLocalParameters()
            .forEach((name, value) -> result.put(name, createParameter(name, value)));
}

Versions

Component Version
allure-testng 2.35.4
TestNG 7.12.0
JDK 21
OS macOS (Darwin 25.5)

Originally observed in a Kotlin test project; reproduced identically with plain Java classes.

What Allure Integration are you using?

allure-testng

What version of Allure Integration you are using?

2.35.4

What version of Allure Report you are using?

2.35.1

Code of Conduct

  • I agree to follow this project's Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions