Search code examples
javatestng

Java with TestNG lose initialized variable


There is surprising situation, which I can't understand. I have test automation with RestAssured (pet project). I want to prepare RequestSpecification spec variable in @BeforeSuite method, in parent class. Then I want to use spec variable in tests of child class. Here is code of parent class

public class BaseTest {

private String baseUrl = "https://api.thecatapi.com/v1/";
protected RequestSpecification spec;

@BeforeSuite
public void beforeSuite() {
    String apiKey = System.getProperty("api_key");
    spec = new RequestSpecBuilder()
            .setContentType(ContentType.JSON)
            .setBaseUri(baseUrl)
            .addHeader("x-api-key", apiKey)
            .addFilter(new ResponseLoggingFilter())
            .addFilter(new RequestLoggingFilter())
            .addFilter(new AllureRestAssured())
            .build();
    }
}

And here is a test in child class'

public class OurLittleTest extends BaseTest {

@Test
public void test() {
    //1
    String id = Breeds.search(spec, "Scottish Fold").then().extract().body().jsonPath().get("[0].id");

problem is that spec variable in test is null, while I was waiting it won't be null...

Why it happens? Why spec is null ?

I've recordered a screencast where you can see my problem

UPDATE Everything is fine with Junit 5. The spec variable is not null in child classes anymore. So here are me build.gradle files:

With TestNG:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "io.qameta.allure:allure-gradle:2.8.1"
    }
}

plugins {
    id 'java'
    id 'io.qameta.allure' version '2.8.1'
}

sourceCompatibility = JavaVersion.VERSION_1_8

allure {
    configuration = 'testImplementation'
    version = '2.7.0'
    allureJavaVersion = '2.7.0'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5'
    implementation 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'
    implementation 'io.rest-assured:rest-assured:4.4.0'
    implementation group: 'io.qameta.allure', name: 'allure-rest-assured', version: '2.14.0'
    implementation "io.qameta.allure:allure-testng:2.14.0"
    testImplementation group: 'org.testng', name: 'testng', version: '7.3.0'
}

test {
    useTestNG() {
        parallel = 'methods'
        threadCount = 2
    }
    if (project.hasProperty("api_key")) {
        systemProperties.put("api_key", "$api_key")
    }
}

With Junit 5:

plugins {
    id 'io.qameta.allure' version '2.5'
    id 'java'
}

allure {
    configuration = 'testImplementation'
    version = '2.7.0'

    useJUnit5 {
        version = '2.7.0'
    }

}

sourceCompatibility = JavaVersion.VERSION_1_8

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5'
    implementation 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'
    implementation 'io.rest-assured:rest-assured:4.4.0'
    implementation group: 'io.qameta.allure', name: 'allure-rest-assured', version: '2.14.0'
    implementation group: 'io.qameta.allure', name: 'allure-junit5', version: '2.14.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
}

test {
    useJUnitPlatform{
        systemProperty 'junit.jupiter.testinstance.lifecycle.default'         , 'per_class'
        systemProperty 'junit.jupiter.execution.parallel.enabled',              'true'
        systemProperty 'junit.jupiter.execution.parallel.mode.default',         'same_thread'
        systemProperty 'junit.jupiter.execution.parallel.mode.classes.default', 'concurrent'
    }
    if (project.hasProperty("api_key")) {
        systemProperties.put("api_key", "$api_key")
    }
}

What's wrong with TestNG ?


Solution

  • The problem is usage of @BeforeSuite. It is meant to be used only once per suite and ignored in following runs.

    For initializing the spec you can either do it directly inline in the field like protected RequestSpecification spec = new RequestSpecBuilder()... or use @BeforeClass.