How to pass Global Variables in data driven?

Let’s assume that I have some roles to put under the tests and I have created some glovals, for example:
GlobalVariable.adminRole,
GlobalVariable.customerRole,
GlobalVariable.reviewerRole etc.
Then I have the logIn(String role) method which send keys to text inputs.
Also pinned the internal data file with role column and passed the roles like:
role
${GlobalVariable.adminRole}
${GlobalVariable.customerRole} etc.

But send keys method on my web page sends String like ${GlobalVariable.adminRole} not the value.

When I did the same with TestObjects, api calls for example it works like a charm.
Is there any option to pass that into the test data like that and gets the real value of the global variable?

Thanks in advance,

Remi

Hello, i think it would be nice if you would copy and paste the snippet of you code which you need hlep on, because its hard to understand what you exact Problem is…

Maybe reffer to
https://forum.katalon.com/t/tip-how-to-help-us-help-you/12919/29

1 Like

I see, but I simply can’t share the code.
Long story short, how to pass the Global Variables into the internal data file to get it’s values in the data driven test?
What is hard to understand on that topic?

hi,

you are missing quates " "

println(GlobalVariable.URL_Application)
println("${GlobalVariable.URL_Application}")
def v = “${GlobalVariable.URL_Application}”
println(v)

http://demoaut.katalon.com/
http://demoaut.katalon.com/
http://demoaut.katalon.com/

1 Like

Right, data read from data files are read as simple Strings, so this makes sense. (What you are trying to do here is often called “Expression Language,” or EL for short). I don’t know of any built-in EL interpreter for Test Data, but we use a custom implementation:

    public static String getELValue(final String value) {
		int occurrence = value.indexOf("\${");
		if(occurrence >= 0) {
			String expression = value.substring(occurrence, value.indexOf("}") + 1);
			String function = expression.substring(2, expression.indexOf("("));
			String[] arguments = expression.substring(expression.indexOf("(") + 1, expression.indexOf(")")).split(",");
			String replacement = "INVALID_FUNCTION";
			switch(function) {
				case "randomAlphanumeric":
					replacement = Functions.randomAlphanumeric(Integer.parseInt(arguments[0]));
					break;
				case "randomString":
					replacement = Functions.randomString(Integer.parseInt(arguments[0]));
					break;
				case "randomNumber":
					replacement = Functions.randomNumber(Integer.parseInt(arguments[0]));
					break;
				case "randomCharSequence":
					replacement = Functions.randomCharSequence(Integer.parseInt(arguments[0]), arguments[1]);
					break;
				case "todaysDate":
					replacement = Functions.todaysDate(Integer.parseInt(arguments[0]));
					break;
				case "timestamp":
					replacement = Functions.timestamp();
					break;
			}
			return getELValue(value.replace(expression, replacement));
		}
		return value;
	}

What this allows you to do is pass in any String, and if the String contains any number of variable handles of the format ${someFunction()}, they will be replaced with the appropriate value (in my case, it’s meant for calling functions, but you could do this with static values or possibly even GlobalVariables). So, for instance, I could have a value in my data file like this:

“The current date is ${todaysDate()}, and the current timestamp is ${timestamp()}”

And if i passed this value to that method, the returned string would be something like:

“The current date is 05/20/2020, and the current timestamp is 134897012341234”

I know this doesn’t directly answer your question, but just food for though that this kind of thing is doable, but it’s not really possible with the built-in Katalon functionality.

tl;dr you cannot put variable handles in data files and expect them to be replaced, they are read simply as String values

1 Like

Long story short: if you need to use a certain GlobalVariable in your test case, map it directly at the testcase level, don’t put it in data file

Well, fine and many thanks, thats what I though, but I also a little bit confused by the things happen in the API request test objects. Because this is able to read the global variables from data files as values like that ${GlobalVariable.whatever} :slight_smile: Magic!
Of course I can go with the switch statement and add some abstraction layers, but it’s ridiculous :wink:

Whatever, many thanks for your response.

Regards,
Remi

Hi Bionel, that’s exactly what I want to avoid :smiley:

Right, there are many places (I would say most places) where you can do variable replacement like that. Data Files are just not one of them, unfortunately :expressionless:

1 Like

Ah, bro you didn’t really understand, sorry, but I just like to explain that to you because of nice talk with you :slight_smile:
If i have the data file with passed global variable like that ${GlobalVariable.dupa} and use it in the api call api call understands that and takes the value then make the api call correctly.
But if I want to pass that into the test class as a String value it can’t be understood as value and returns the ${blabla thing}.

Let’s imagine that I create the api test object url like ${serviceUrl}/whatever?param=${dupa}
And combine that with data file, everything works perfectly.

for example something like in the data file:
service | param
${GlobalVariable.serviceUrl1} | ${GlobalVariable.something}
${GlobalVariable.serviceUrl2} | ${GlobalVariable.something2}
${GlobalVariable.serviceUrl3} | ${GlobalVariable.something3}

then
WS.sendRequest(findTestObject(“myDupaRequest”) [(‘serviceUrl’) : service, (‘dupa’) : param])

the api calls would be for example:
https://uat.whatever?param=ilikebeer
https://qa.whatever?param=idontlikebeer
https://prod.whatever?param=katalonisapieceofs**t

This means that this will take the real values from profile. Why the heck ui test can’t do that :slight_smile:
Believe me or try by yourself, you will see :slight_smile:

Regards,
Remi

well … you can use the solution proposed by @Brandon_Hein or you can implement a different solution using TemplateEngine … see if this helps:
https://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html

1 Like