Set Test Variable from own library

966 views
Skip to first unread message

BS

unread,
Dec 4, 2008, 4:11:10 AM12/4/08
to robotframework-users
Hi!

I would like to register a variable to be visible in the whole test
case. So, there is a keyword Set Test Variable. I tried to do
something like:

class MyClass:
def my_keyword(self, x):
a = x
BuiltIn.BuiltIn().set_test_variable(a)

1. Should I create new instance of the BuiltIn class?
2. It evaluates the 'a' variable. Example
>>> a = 'abc'
>>> BuilIn.BuiltIn().set_test_variable(a)
<<< Invalid variable syntax 'abc'

Pekka Klärck

unread,
Dec 4, 2008, 5:08:55 PM12/4/08
to xter...@o2.pl, robotframework-users
2008/12/4 BS <xter...@o2.pl>:

First of all, in most cases it is better to use the BuiltIn keyword
'Set Test Variable' in the test data to accomplish this. Setting the
variable can be wrapped into a user keyword in a resource file and you
can then distribute that resource file with rest of the
library/framework/toolset.

There might, of course, be reasons why to use the
BuiltIn.set_test_variable directly in your library. I haven't tried
that myself, but I'm quite sure that you should be using either

BuiltIn().set_test_variable('${var}', 'value')

or

BuiltIn().set_test_variable('$var', 'value')

The latter syntax is what the keyword expects, but the former might
also work. As I said, I haven't tried this myself.

Cheers,
.peke

BS

unread,
Dec 4, 2008, 6:19:50 PM12/4/08
to robotframework-users
On 4 Gru, 23:08, "Pekka Klärck" <p...@iki.fi> wrote:

> First of all, in most cases it is better to use the BuiltIn keyword
> 'Set Test Variable' in the test data to accomplish this. Setting the
> variable can be wrapped into a user keyword in a resource file and you
> can then distribute that resource file with rest of the
> library/framework/toolset.

I understand this way, but I don't understant why it would be better.
Whatever, after I wasted a time on figure out how to set_test_variable
works (and I don't know why I didn't understand it after reading the
code and that I should pass more than 1 argument ;D), I've realized
what will be optimal for my case.
So, I would like to write a variable-library (and use it with
Variables keyword in Setting table, or in setup section if possible).
There will be some operation on XML files etc. So I will go in Python
to do this. And at least, it's pretty simple to get global variables
from this. And it works. The issue is, how to get an access to them
from my libraries ;) I can simple import that variable-library but
references to objectes don't match. I tried to debug robot in pdb, and
general I found place when robot handles with the variable-library,
but I had to go out from the office, and haven't figured out how to
access them from my own libraries. If you can give me simple tip,
would be nice, and I will not have to debug it again and waste more
time ;)

> There might, of course, be reasons why to use the
> BuiltIn.set_test_variable directly in your library. I haven't tried
> that myself, but I'm quite sure that you should be using either
>
>     BuiltIn().set_test_variable('${var}', 'value')
>
> or
>
>     BuiltIn().set_test_variable('$var', 'value')
>
> The latter syntax is what the keyword expects, but the former might
> also work. As I said, I haven't tried this myself.

Thx for that. If you will help me with the issue described above,
perhaps I will not need to use this. But I will test it and let you
know if it works, when I will back to NSN (next Tuesday).

cheers!

BS

unread,
Dec 9, 2008, 4:27:24 AM12/9/08
to robotframework-users
On 4 Gru, 23:08, "Pekka Klärck" <p...@iki.fi> wrote:

>     BuiltIn().set_test_variable('${var}', 'value')
>
> or
>
>     BuiltIn().set_test_variable('$var', 'value')
>
> The latter syntax is what the keyword expects, but the former might
> also work. As I said, I haven't tried this myself.

Already tested and both don't work.

I got: Non-existing variable '${foo}'

Pekka Klärck

unread,
Dec 9, 2008, 4:59:26 AM12/9/08
to robotframework-users
Accidentally only replied to the sender...


---------- Forwarded message ----------
From: Pekka Klärck <pe...@iki.fi>
Date: 2008/12/9
Subject: Re: Set Test Variable from own library
To: xter...@o2.pl


2008/12/9 BS <xter...@o2.pl>:

I created following simple test library and after executing 'Set Var'
keyword both ${spam} and ${eggs} variables were available.

from robot.libraries.BuiltIn import BuiltIn

def set_var():
BuiltIn().set_test_variable('${spam}', 'eggs')
BuiltIn().set_test_variable('$eggs', 'spam')


In your earlier mail you mentioned something about Variables in
Setting table. If that means that you try to use variable files then
the above does not work for you since it is a test library. Variable
files could really be suitable for your case, though, and they are
very simple. The simplest variable file that would create same
variables as the above keyword is:

spam = 'eggs'
eggs = 'spam'


For more information about variable files, see
http://robotframework.googlecode.com/svn/tags/robotframework-2.0.3/doc/userguide/RobotFrameworkUserGuide.html#variable-files

Cheers,
.peke

BS

unread,
Dec 9, 2008, 6:35:04 AM12/9/08
to robotframework-users
On 9 Gru, 10:59, "Pekka Klärck" <p...@iki.fi> wrote:

> I created following simple test library and after executing 'Set Var'
> keyword both ${spam} and ${eggs} variables were available.
>
>    from robot.libraries.BuiltIn import BuiltIn
>
>    def set_var():
>        BuiltIn().set_test_variable('${spam}', 'eggs')
>        BuiltIn().set_test_variable('$eggs', 'spam')

Ok, my fault. Marcin Michalak noticed me that I tested these vars in
another testcase, so I have to use set_suite_variable() instead of
set_test_variable().
No, it works fine!

> In your earlier mail you mentioned something about Variables in
> Setting table. If that means that you try to use variable files then
> the above does not work for you since it is a test library. Variable
> files could really be suitable for your case, though, and they are
> very simple. The simplest variable file that would create same
> variables as the above keyword is:
>
>    spam = 'eggs'
>    eggs = 'spam'
>
> For more information about variable files, seehttp://robotframework.googlecode.com/svn/tags/robotframework-2.0.3/do...

Perhaps, you didn't understand my question.
Let's say i have a variable file var.py with the following context:
spam = 'eggs'
eggs = 'spam'

and I have library file lib.py. and i wish to use those variables
inside the library (i can by `import var`). but modifying them don't
affect outside the library.


-----
var.py
-----
foo = 'bar'

-----
lib.py
-----
import var

class C(object):
ROBOT_LIBRARY_SCOPE = "TEST SUITE"
def f(self):
print var.foo
var.foo = "spam"


and following test suite:
[Setting Table]
Library | lib.py
Variables | var.py

[TestCase Table]
TC1 | f
| Log ${foo}

in output i have 2 times the same value "bar". i wish to get "bar" and
"spam"


Perhaps I access to the variable file in wrong way. How should I to do
it?

BS

unread,
Dec 9, 2008, 7:18:44 AM12/9/08
to robotframework-users
On 9 Gru, 12:35, BS <xterr...@o2.pl> wrote:


Marcin suggested to add the following line:
> class C(object):
>    ROBOT_LIBRARY_SCOPE = "TEST SUITE"
>    def f(self):
>        print var.foo
>        var.foo = "spam"
BuiltIn().set_(global|suite|test)_variable('$foo', var.foo)

And it works! Hope it's good solution :)

Pekka Klärck

unread,
Dec 9, 2008, 10:29:18 AM12/9/08
to xter...@o2.pl, robotframework-users
2008/12/9 BS <xter...@o2.pl>:

>
> Marcin suggested to add the following line:
>> class C(object):
>> ROBOT_LIBRARY_SCOPE = "TEST SUITE"
>> def f(self):
>> print var.foo
>> var.foo = "spam"
> BuiltIn().set_(global|suite|test)_variable('$foo', var.foo)
>
> And it works! Hope it's good solution :)

Setting var.foo to new value doesn't have any effect because Robot
Framework has already read it's value into variable ${foo}. You are
just rebinding the value of 'foo' attribute to a new value but Robot
can't notice that. If the value would originally be a mutable object
(like a list or your custom object) you should be able to alter its
state using something like "var.foo.do_something('x')".

Using BuiltIn.set_xxx_variable is probably a better idea than altering
the state of the variable as it's more explicit. You can also remove
'var.foo = "spam"' line (as well as importing var) altogether and set
the variable like

BuiltIn().set_(global|suite|test)_variable('$foo', 'spam')


Cheers,
.peke

BS

unread,
Dec 9, 2008, 11:17:31 AM12/9/08
to robotframework-users
On 9 Gru, 16:29, "Pekka Klärck" <p...@iki.fi> wrote:

> Setting var.foo to new value doesn't have any effect because Robot
> Framework has already read it's value into variable ${foo}. You are
> just rebinding the value of 'foo' attribute to a new value but Robot
> can't notice that.

Yeah, that i thought. So, how can I get an access to the list with
already loaded variables in Robot?

> If the value would originally be a mutable object
> (like a list or your custom object) you should be able to alter its
> state using something like "var.foo.do_something('x')".

Yeah, that how Python works.

> Using BuiltIn.set_xxx_variable is probably a better idea than altering
> the state of the variable as it's more explicit. You can also remove
> 'var.foo = "spam"' line (as well as importing var) altogether and set
> the variable like
>
>     BuiltIn().set_(global|suite|test)_variable('$foo', 'spam')

OK. That's ok for setting. How to get actual value (in library file of
course)? import var; var.foo is not the best option as you noticed
above.

Pekka Klärck

unread,
Dec 9, 2008, 1:01:10 PM12/9/08
to xter...@o2.pl, robotframework-users
Argh, replied only to sender again... This time this reply has some
new content, though.

2008/12/9 Pekka Klärck <pe...@iki.fi>:
> 2008/12/9 BS <xter...@o2.pl>:


>>
>> How to get actual value (in library file of
>> course)? import var; var.foo is not the best option as you noticed
>> above.
>

> I would simply use the variable in the test data and then get the
> actual value into the library. There is no stable public API for
> getting variables, but if you really want you can see how the BuiltIn
> library gets the access. You may also want to add a star or otherwise
> comment this issue:
> http://code.google.com/p/robotframework/issues/detail?id=167

I was wrong, BuiltIn keyword Replace Variables can actually be used to
replace variables with their values, and BuiltIn.replace_variables
method thus works in libraries. The original use case for this keyword
was replacing variables in template files read from the system, but it
works pretty well in this situation too. The only limitation is that
it always returns values as a string, but I already opened a separate
issue [1] about removing that limitation.

[1] http://code.google.com/p/robotframework/issues/detail?id=175

Cheers,
.pkee

Cheers,
.peke

BS

unread,
Jan 15, 2009, 3:33:47 AM1/15/09
to robotframework-users
On 9 Gru 2008, 19:01, "Pekka Klärck" <p...@iki.fi> wrote:

> I was wrong, BuiltIn keyword Replace Variables can actually be used to
> replace variables with their values, and BuiltIn.replace_variables
> method thus works in libraries. The original use case for this keyword
> was replacing variables in template files read from the system, but it
> works pretty well in this situation too. The only limitation is that
> it always returns values as a string, but I already opened a separate
> issue [1] about removing that limitation.
>
> [1]http://code.google.com/p/robotframework/issues/detail?id=175

It's fixed in 2.0.4 but I forgot to mention that using Replace
Variables to just return a variable doesn't look nice ;) IMHO there
should be new keyword Return Variable or Get Variable or something
like this.

Pekka Klärck

unread,
Jan 15, 2009, 4:13:58 AM1/15/09
to xter...@o2.pl, robotframework-users
2009/1/15 BS <xter...@o2.pl>:

I agree that replace_variables is not the best method name to use
inside a library for this purpose, but Return Variable and Get
Variable wouldn't make sense as keywords since you can just use
variable syntax in the test data. If you are really bothered by the
not-exactly-optimal method name, you can simply rename it in your
library like

from robot.libraries.BuiltIn import BuiltIn
BuiltIn.get_variable = BuiltIn.replace_variables

Alternatively you can have a helper method like

def get_variable(string):
return BuiltIn().replace_variables(string)

Cheers,
.peke

BS

unread,
Jan 16, 2009, 4:22:00 AM1/16/09
to robotframework-users
On 15 Sty, 10:13, "Pekka Klärck" <p...@iki.fi> wrote:

> I agree that replace_variables is not the best method name to use
> inside a library for this purpose, but Return Variable and Get
> Variable wouldn't make sense as keywords since you can just use
> variable syntax in the test data. If you are really bothered by the
> not-exactly-optimal method name, you can simply rename it in your
> library like
>
>     from robot.libraries.BuiltIn import BuiltIn
>     BuiltIn.get_variable = BuiltIn.replace_variables
>
> Alternatively you can have a helper method like
>
>     def get_variable(string):
>         return BuiltIn().replace_variables(string)

Ok, I understand your point. But what I wanted to notice is that we
use a behaviour of Replace to get extra functionality.
But this behaviour is not a main function of Replate Variables so,
nobody knows if some day this behaviour would change (without
changaing a target function). And then we have a problem ;)

Pekka Klärck

unread,
Jan 16, 2009, 6:49:06 AM1/16/09
to xter...@o2.pl, robotframework-users
2009/1/16 BS <xter...@o2.pl>:

We try not to modify keywords so that their functionality changes, and
if we would break some existing behavior we would most likely revert
back. It wouldn't help much if we had another method in the library
since we could accidentally break it too.

Cheers,
.peke

BS

unread,
Jan 16, 2009, 1:32:59 PM1/16/09
to robotframework-users
On 15 Sty, 10:13, "Pekka Klärck" <p...@iki.fi> wrote:


>     from robot.libraries.BuiltIn import BuiltIn
>     BuiltIn.get_variable = BuiltIn.replace_variables

Builtin().replace_variables() doesn't work for Setting neither
Variable tables. Can you fix it?

Pekka Klärck

unread,
Jan 16, 2009, 3:46:46 PM1/16/09
to xter...@o2.pl, robotframework-users
2009/1/16 BS <xter...@o2.pl>:

What do you mean with this? Are you trying to set new variables or
alter settings? Setting variables works with
set_test/suite/global_variable but changing settings is not supported.

Cheers,
.peke

Reply all
Reply to author
Forward
0 new messages