5

I have an automation testing framework in Java. I need this code run on multiple environment such as SIT, UAT and Prod but all of these environment have different URL.

sit-config.properties

hompepage = XXX

uat-config.properties

homepage = YYY

Maven Profile

<profiles>
    <profile>
        <id>sit</id>
        <activation>
            <property>
                <name>environment</name>
                <value>sit</value>
            </property>
        </activation>
    </profile>
    <!-- mvn -Denvironment=sit clean test -->

    <profile>
        <id>uat</id>
        <activation>
            <property>
                <name>environment</name>
                <value>uat</value>
            </property>
        </activation>
    </profile>

  </profiles>

Questions (EDIT):

  1. How to load specific properties file based on environment test?
  2. I got an example for Java Owner library but for testng not Maven.

http://www.testautomationguru.com/selenium-webdriver-how-to-execute-tests-in-multiple-environments/

Please help. Thanks.

nicholas
  • 2,581
  • 14
  • 66
  • 104
  • What you want is one property file for each environment ("dev.properties", "sit.properties", etc). Each would have the same set of properties, such as homepage.url=XXX . Not sure if it's a duplicate, but see https://stackoverflow.com/questions/22757318/different-property-variable-for-local-and-prod-environment-spring – racraman Jul 12 '19 at 02:11
  • Do not have separate branches, but rather your test code should be tagged and released together with the code under test (ideally in the same SCM system). This is because tests run against Dev today could well fail when run against Production, since Production is at where Dev was some time ago. So when running the test, get the version of the test suite from SCM appropriate for the environment, and specify the environment (ie, which properties file to use) at run time. – racraman Jul 12 '19 at 02:23
  • How to specify which properties file to use at run time? – nicholas Jul 12 '19 at 02:35
  • 1
    Up to you - but typically either on the command line (like "-Denv=prod"), or by an environment variable set on each machine. Then use that to construct the filename of the properties file to load, as in the question I linked to. – racraman Jul 12 '19 at 02:42
  • Since you're using maven, see also https://stackoverflow.com/questions/1149352/using-maven-for-multiple-deployment-environment-production-development and https://maven.apache.org/guides/mini/guide-building-for-different-environments.html – racraman Jul 12 '19 at 02:47
  • Please answers my latest questions. Thanks. – nicholas Jul 12 '19 at 03:30
  • Certainly use Spring's features if you're using spring - see https://dzone.com/articles/spring-boot-profiles-1 and https://stackoverflow.com/questions/38520638/how-to-set-spring-profile-from-system-variable. Note that their assignment `spring.profiles.active=dev` can equally be on the command line in place of the "env" on my previous comment - ie. use `-Dspring.profiles.active=dev` – racraman Jul 12 '19 at 03:48
  • I not planning to use Spring. I plan to use Java owner library + Maven profile. – nicholas Jul 12 '19 at 04:00
  • "but for testng not Maven." What it means? Testng and Maven are completely different things. – Roberto Pegoraro Jul 15 '19 at 12:59
  • The article uses Java owner library and testng to pass the config at runtime. Not using maven to pass config. – nicholas Jul 16 '19 at 01:51

4 Answers4

4

First you have to create properties file with your different URLs

Then Add config File reader

public String applicationUrl_QA() {
        String applicationUrl = properties.getProperty("applicationUrl_QA");
        if(applicationUrl != null) return applicationUrl;
        else throw new RuntimeException("url not specified in the Configuration.properties file.");
    }

Then you can config all the environments like below

if(Env.equalsIgnoreCase("QA")){
            if(URL.equalsIgnoreCase("_QA")){
                driver.get(configFileReader.applicationUrl_QA());
}

then you have create seperate XMLs like below

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="false" thread-count="5" verbose="1">

    <!--Values Chrome Firefox HLChrome HLFirefox HTMLUnit phantomJS-->
    <parameter name="browser" value="Firefox"/>

    <!--Values AdminURL StatementURL PatientURL-->
    <parameter name="URL" value="Value"/>

    <!--Values QA Dev Uat Prod -->
    <parameter name="Env" value="QA"/>
    <test name="AdminTests">
        <classes>
            <class name="tests.Test1"/>
        </classes>
         <classes>
            <class name="tests.test2"/>
        </classes>
    </test>
</suite>

Finally you have to call all the xmls using one xml file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="false" thread-count="5" verbose="2">
<suite-files>
    <suite-file path="File1_QA.xml"/>
</suite-files>
    <suite-files>
        <suite-file path="File2_UAT.xml"/>
    </suite-files>
</suite>
Devdun
  • 747
  • 5
  • 14
  • As i said, i don;t want use properties file and testng xml file. I want use Java owner library + Maven profile. – nicholas Jul 17 '19 at 01:48
3

I had to solve a similar problem. And here is how I approached.

Step-1: Add surefire plugin in your POM.xml under build > plugin section.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <systemPropertyVariables>
                    <TestEnvironment>local</TestEnvironment>
                </systemPropertyVariables>
                <!-- <suiteXmlFiles>
                    <suiteXmlFile>here goes your testng xml</suiteXmlFile>
                </suiteXmlFiles> -->
            </configuration>
        </plugin>

Here, TestEnvironment is the custom system property you are setting up, this can be retrieved later in your code.

Note: If you want to run a specific testng xml, un-comment <suiteXmlFiles> tag and provide the path of your testng xml file.

Step-2: Add code to get the system property and read from the respective properties file.

        // Assuming your properties files are in the root directory of your project.
        String configFileName = "./%s-config.properties";
        String EnvironmentName = System.getProperty("TestEnvironment");
        System.out.println("TestEnvironment: " + EnvironmentName);

        configFileName = String.format(configFileName, EnvironmentName);
        properties = new Properties();
        properties.load(new FileInputStream(new File(configFileName)));

Step-3: Pass TestEnvironment to mvn command

mvn clean test -DTestEnvironment=sit

This command will read from your sit-config.properties file and execute the tests. To read from different properties files pass a different value in the command line.

Please let me know if this answered your questions.

Appu Mistri
  • 768
  • 8
  • 26
  • I don't want to use Properties code. I want to use Java Owner library + Maven profile. – nicholas Jul 12 '19 at 09:21
  • 1
    @nicholas you can use the above idea to decide where to load the properties from when using [this approach](http://owner.aeonbits.org/docs/importing-properties/) (or even [this approach](http://owner.aeonbits.org/docs/configuring/), where `${myPath}` would come from the Maven profile). You just need to add the plugin configuration under each of the `profile > build > plugins` sections. You can keep the basic configuration out of the `profiles` section and just push `systemPropertyVariables` down to `profiles`, Maven should be able to merge them – crizzis Jul 17 '19 at 16:08
0

I suggest you to use Spring Boot for using different files of configurations(profiles). But, if you only need pass the URL parameter during execution, try as this:

In your code:

public class Url {

    public static String host;

    static {
        Url.host = System.getProperty("mysystem.property.host");
    }
}

And then, when you execute the tests, pass the property as this:

mvn clean test -Dmysystem.property.host=yourUrl

Roberto Pegoraro
  • 1,313
  • 2
  • 16
  • 31
0

According to the example that you gave, there is an instruction below, what you have to do for executing the test from Maven:

1) Maintain a separate property file for each environment in src/test/resourcces

2) Add 'owner' dependency in your Maven project.

3) Create Interface 'Environment' as shown in the example with:

    @Sources({
    "classpath:${env}.properties"
    })

4) Throughout your test and page objects, you would be using the testEnvironment object:

public class EnvironmentTest {

    Environment testEnvironment;

    @Test
    public void functionalTest() {
        System.out.println(testEnvironment.url());
        System.out.println(testEnvironment.getDBHostname());
        System.out.println(testEnvironment.getDBPassword());
    }

    @BeforeTest
    public void beforeTest() {
        String environemnt = System.getProperty("environment"); //here you read your environment name
        ConfigFactory.setProperty("env", environemnt); //here you use your environment name for reading proper file
        testEnvironment = ConfigFactory.create(Environment.class); //here we create an instance of the Environment interface & access the property file
    }
}

5) Run your program using Maven where you enter environment name for your test:

clean test -Dtest=EnvironmentTest -Denvironment=qa
cheparsky
  • 514
  • 6
  • 20