0

To run my Selenium/Cucumber java project, I need to pass some VM arguments, variables, properties path etc... now easiest way is to pass it in Eclipse run configuration under "VM arguments" tab. I need to give path of Log4j2.xml, sqlJdbc driver, any UserID etc.

Now, if i put all this in a properties file and then run the "TestRunner', then how can i make sure properties are loaded before the Features run. I get NullPointerException.

Can i put this in a static block? THis way will it get initialized before any TestNG feature runs?

enter image description here

@CucumberOptions(glue = { "stepDefinitions" }, features = {
        "src/test/resources/features/CreateUserProfile.feature" }, plugin = { "pretty",
                "json:test-output/JsonReport.json", "html:test-output/HTMLReport.html",
                "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", })

public class TestRunner {
    public TestNGCucumberRunner testNGCucumberRunner;

    @BeforeClass(alwaysRun = true)
    public void setUpClass() {
        if (testNGCucumberRunner == null) {
            testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
        }
    }

    @Test(groups = "cucumber scenarios", description = "Runs Cucumber Scenarios", dataProvider = "scenarios")
    public void scenario(PickleWrapper pickleEvent, FeatureWrapper cucumberFeature) throws Throwable {
        testNGCucumberRunner.runScenario(pickleEvent.getPickle());
    }

    @DataProvider
    public Object[][] scenarios() {
        if (testNGCucumberRunner == null) {
            testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
        }
        return testNGCucumberRunner.provideScenarios();
    }

    @AfterClass(alwaysRun = true)
    public void tearDownClass() {
        testNGCucumberRunner.finish();

    }

    static {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        System.setProperty("current.date", dateFormat.format(new Date()));
        String propertyFilePath = "C:\\EclipseWorkspace\\Automation\\src\\main\\resources\\config.properties";
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(propertyFilePath));
            Properties properties = new Properties();
            try {
                properties.load(reader);
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("Config.properties not found at " + propertyFilePath);
        }

    }

}

UPDATE:

I get this error ...i have loaded the properties file in the TestRunner.java file, also loaded in the BaseTest.java class where driver is initialized. Still i get this error. Please help. I don't want to use eclipse VM arguments and want my properties to be loaded from the script only.

java.lang.NullPointerException: Cannot invoke "String.equalsIgnoreCase(String)" because the return value of "java.lang.System.getProperty(String)" is null
1
  • What results are you getting from the code you posted? Jan 30, 2023 at 10:31

2 Answers 2

0

Solution :

  • Snippet to load config.properties
Properties prop=new Properties();

FileInputStream ips = new FileInputStream(“home/username/ProjectName/src/config.properties”);

prop.load(ips);
  • Ensure .properties are getting loaded before features run:
    • Basically you can have multiple implementations to achieve this
    • On successful driver object creation, you can create and load the prop object
    • Good solution to use try..catch blocks for all the initialisation
0

Here's an example solution in Java:

1 First, create a properties file, e.g. config.properties, with your configuration data.

url=https://www.example.com
username=testuser
password=testpassword

2 Next, create a class that will load the properties file and store the values in variables:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ConfigProperties {
    private static String url;
    private static String username;
    private static String password;
    
    static {
        Properties prop = new Properties();
        try (InputStream input = new FileInputStream("config.properties")) {
            prop.load(input);
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    public static String getUrl() {
        return url;
    }
    
    public static String getUsername() {
        return username;
    }
    
    public static String getPassword() {
        return password;
    }
}

3 Finally, in your Cucumber test runner class, you can access the properties as follows:

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/features", glue = { "steps" }, tags = { "@smoke" })
public class CucumberTestRunner {
    public static String URL = ConfigProperties.getUrl();
    public static String USERNAME = ConfigProperties.getUsername();
    public static String PASSWORD = ConfigProperties.getPassword();
}

This way, you can easily access the properties from your Cucumber test cases without having to hard-code the values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.