Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System env property as placeholder token in the test steps #248

Closed
authorjapps opened this issue Jun 2, 2019 · 22 comments
Closed

System env property as placeholder token in the test steps #248

authorjapps opened this issue Jun 2, 2019 · 22 comments
Assignees
Labels
feature-request New feature which can be introduced help wanted

Comments

@authorjapps
Copy link
Owner

authorjapps commented Jun 2, 2019

@ashishMal requested a feature via StackOverFlow n Gitter.

Background

I need to load the system properties in one class like host etc. and once they are loaded, It can be used in all the further test cases/scenarios like normal properties as ${propetyName}.
Check this stackoverflow link- https://stackoverflow.com/questions/56252109/zerocode-set-system-property-in-host-configuration-file

From SOF

Configuration:
zerocode-tdd.1.3.2

${host}
At runtime, system property set with -D java option. All is well.

Problem / What I Need:
At unit test time, system property not set, and host not resolved.
App uses Junit and Zerocode, would like to simply configure Zerocode to set the system property.

Example:

host.properties

web.application.endpoint.host:${host}
web.application.endpoint.port=
web.application.endpoint.context=

More Info:
Requirement is for configuration only. Can't introduce new Java code, or entries into IDE.

Any help out there? Any ideas are appreciated.


More Details

@siddhagalaxy wrote-
This sounds similar to your question, but defined in the config file instead of system-env.
Can you check this answer - https://stackoverflow.com/questions/54716763/reading-extra-properties-or-host-addresses-inside-the-json-test-case/55077950#55077950

Solution

User is looking for host to be supplied as system-env? so that he can execute the test for different hosts in runtime ?

e.g.

-Dhost=https://dev1.local.uk

or

-Dhost=https://sit1.local.uk

Workaround

He has worked it out correctly, which is great! 👍 (which unblocks you)

We will make it more straight forward soonish...

(Checking with other committers for the best approach... Probably you can pick this ticket and contribute. This shd be a minor code change only)


History

@ashishMal replied in SOF-
Found a solution, but not sure if this is the correct way to do so.

Step 1: Create a config file and load system properties.

Config.java

public class Config {

    public Map<String, Object> readProperties(String optionalString) {
        Map<String, Object> propertiesMap = new HashMap<>();
        final String host = System.getProperty("host");
        
        propertiesMap.put("host", host);

        return propertiesMap;
    }
}

Step 2: Add a step (before other steps) to use the loaded properties in the .json file.

test.json

{
    "scenarioName": "Test ...",
    "steps": [
         {
            "name": "config",
            "url": "com.test.Config",
            "operation": "readProperties",
            "request": "",
            "assertions": {}
        }
    ]
}

Step 3: Use loaded property in step config

test.json

 {
        "scenarioName": "Test ...",
        "steps": [
             {
                "name": "config",
                "url": "com.test.Config",
                "operation": "readProperties",
                "request": "",
                "assertions": {}
            },
            {
                "name": "test",
                "url": "${$.config.response.host}/test/xxx",
                "operation": "GET",
                "request": {},
                "assertions": {
                    "status": 200
                 }
            }
        ]
    }

That's it, although it is working but I am looking for better approach.

Some possible options I am trying are:

  • Common step for load/config (in one place)
  • Directly using properties as {host} in json files
  • Custom client

Again any help/ideas are appreciated.

@authorjapps authorjapps added feature-request New feature which can be introduced help wanted labels Jun 2, 2019
@jneate
Copy link
Collaborator

jneate commented Jun 15, 2019

@authorjapps I started working on this issue, got it working but want to run the solution by everyone to see what they think.

In github_host.properties I added the value as an environment variable:
image

Test class refers to the properties file:
image

Inside the property section, it replaces all properties that meet the regex (\${)+([a-zA-Z0-9_-]*)(})+ and calls System.getEnv for each property that matches the regular expression:
image

Haven't tested it loads but it does work, wanted to see others thoughts before progressing.

@authorjapps
Copy link
Owner Author

@jneate thanks mate 👍 .

For everyone's benefit(and to make it easy to understand) I am putting the below comments.

Reading properties from the host config file feature is already present.
README Link: https://github.com/authorjapps/zerocode/blob/master/README.md#using-any-properties-file-key-value-in-the-steps

What Jame's solution will do is-
It will replace the value against a property key with the values from the system envs by the matching key.

e.g. (one of its application could be)

config properties

db_port=${MONGO_DB_PORT}
db_host=${MONGO_DB_HOST}

Then the developer/tester can run the test(s) against different ports(27018, 27019 etc) or different hosts(dev, sit, uat/preprod etc) or typically in Jenkins pipeline by maven runtime args via -D.

mvn test -Dtest=AppleApiTest#getProducts -DMONGO_DB_PORT=27018

or

mvn test -Dtest=AppleApiTest#getProducts -DMONGO_DB_PORT=27019

or

mvn test -Dtest=AppleApiTest#getProducts -DMONGO_DB_HOST=dev.apple.local.uk

or

mvn test -Dtest=AppleApiTest#getProducts -DMONGO_DB_HOST=sit.apple.local.uk

Hello @ashishMal, can you review n comment here please ?

Folkd for your review please- @santhoshTpixler @BeTheCodeWithYou @officiallysameer

@ashishMal
Copy link

Thanks @jneate for the solution and @authorjapps for the explanation.
Seems like, it should work now.

Let me check and come back to this.

@jneate
Copy link
Collaborator

jneate commented Jun 17, 2019

@authorjapps @ashishMal - Just one slight clarification to my earlier comment, I'd originally coded it so that you could access environment variables by referencing them inside the properties file.

Example: web.application.endpoint.host=${HOST}
Then provided that the HOST environment variable was set on your machine then it would access the value and load it, ignoring anything passed via -D.

If you want to pass the variables via the -D flag then I just need to change the code from System.getenv() to System.getProperty() and it will work therefore matching the examples in @authorjapps comment above.

Hope this helps.

@santhoshTpixler
Copy link
Collaborator

Right now we can override the properties file with -Denv=production. This allows us to choose different propery files at run time.
Similar idea can be applied here. Let's say the -Denv=System.props should fetch the System properties instead to loading a property file. System.props is just an example.

It is possible to use either propery file or System properties which can be choosen at run-time.

@ashishMal Will this solution be useful for you?

@jneate
Copy link
Collaborator

jneate commented Jun 17, 2019

@santhoshTpixler I thought @ashishMal still wanted to use the property files but pass values to the property file via -D because I assume there will be property values in the config that remain consistent regardless of the target environment and the command could become quite lengthy dependent on the number of properties.

@santhoshTpixler
Copy link
Collaborator

@jneate Looks like the requirement is to use both the property file and System properties.
But it should be simple to either one option. Something like fetching from the property file which contains references to system properties looks a bit complicated.

command could become quite lengthy dependent on the number of properties

Property files are used to solve the quoted issue.

We use multiple properties file with environment name prefixed to keep it simple and maintainable.
for example: dev_host.properties, local_host.properties, production_host.properties which will be overriden in the command line to support the use case.

I haven't seen where the environment variables change quite often. Let's say there is a need to override couple of properties frequently, then a echo command can be used to append the property before running the java command

@ashishMal can you comment on this?

@jneate
Copy link
Collaborator

jneate commented Jun 18, 2019

Yeah I agree @santhoshTpixler that it looks a bit overkill, I thought at first it was to retrieve environment variables as opposed to properties.

Maybe we just need to update the documentation providing more examples but let's wait and see.

@authorjapps
Copy link
Owner Author

@ashishMal ,
Please check, If these two pages help you to solve your usecase! It addresses similar thing(almost similar usecase).

Picking/Configuring/Running Env specific properties - Maven/Gradle

@jneate
Copy link
Collaborator

jneate commented Jun 27, 2019

@ashishMal any update on this?

@ashishMal
Copy link

Hi @authorjapps/ @jneate

Although it is working but I was looking for some other approach like reading system properties directly in the test json files.

@authorjapps I cannot use the approach of environment specific files as I have some system properties which I want to read at the time of executing it.

But thanks calling a class before all the test cases and replacing the property value will do.

@authorjapps
Copy link
Owner Author

authorjapps commented Jun 28, 2019

@ashishMal, Thanks for further details!
just trying to understand your usecase. Seems like it is slightly different to what we thought(trying to solutionize here).

Let me reiterate it below-

1

Actually you are looking for

"url": "${host}/test/xxx",

and the

  1. ${host} should be resolved via maven cli -Dhost=http://xyz.local:8080
    1. i.e. here host is set via a System properties(not the System env)

Fair enough until this point. We will sort that out for you soon!


2

and you really don't need is -- to resolve this from a config .properties file via another key-value
e.g.

web.application.endpoint.host:${host}

In this case, host can be resolved via maven cli -D as well as a System env host. Also for this we already have a solution in place(@jneate 's very first solution)

Now the Q is -

  • Are you looking for only No.1 ?
  • Are you looking for No.1 and No.2 ?

We know you are already unblocked(that's fine), but we can have this as good to have feature to keep everyone's life easy for future automation! 👍

@santhoshTpixler
Copy link
Collaborator

santhoshTpixler commented Jun 28, 2019

@authorjapps Can we have a place holder like ${SYSTEM.PROP:host} which will be resolved to System.getProperty("host")

@ashishMal
Copy link

@authorjapps Can we have a place holder like ${SYSTEM.PROP:host} which will be resolved to System.getProperty("host")

Yes exactly, this is something I am looking for.

@jneate
Copy link
Collaborator

jneate commented Jun 28, 2019

@ashishMal - Thanks for the clarification, I'll update and come back

@ashishMal
Copy link

Hi @jneate /@authorjapps/ @santhoshTpixler

Any update/workaround to the problem above?

@authorjapps
Copy link
Owner Author

@ashishMal , sorry mate, we were a little busy with other issues/PRs.

@jneate , just checking, if you could pick this and amend the PR please(sometimes this week? )?

@jneate
Copy link
Collaborator

jneate commented Jul 16, 2019

@ashishMal @authorjapps - Hoping to pick this up tonight, sorry about the delay work has been really busy.

@jneate
Copy link
Collaborator

jneate commented Jul 16, 2019

@authorjapps @santhoshTpixler - PR raised to address

@authorjapps
Copy link
Owner Author

authorjapps commented Jul 20, 2019

@ashishMal mate, we are trying to fit this into the release version 1.3.9 which has got a bunch of other features packaged(i.e. after all PRs merged). We are hoping this to be available to you by tomorrow(Sunday) 👍 .

Thanks for your patience!

@authorjapps
Copy link
Owner Author

authorjapps commented Jul 21, 2019

Release done mate @ashishMal.
Can you please mark this as resolved in the SOF(when you get chance)?

stackoverflow link- https://stackoverflow.com/questions/56252109/zerocode-set-system-property-in-host-configuration-file

Maven dependency:

<dependency>
  <groupId>org.jsmart</groupId>
  <artifactId>zerocode-tdd</artifactId>
  <version>1.3.9</version>
</dependency>

@ashishMal
Copy link

Thanks @authorjapps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New feature which can be introduced help wanted
Projects
None yet
Development

No branches or pull requests

4 participants