With a little bit of cleverness it's possible now. For example, your
keyword "Given the following lorries" could do nothing but create an
empty suite variable. Then, create a keyword named ":" that creates a
list from its arguments and appends that to the suite variable. Call
that keyword several times and you end up with a list of lists,
effectively a two-dimensional array. Any other keywords that follow
then just need to use the suite variable created by those two
keywords.
Your test would look something like this:
Given the following lorries:
: | name | colour |
: | name 1 | green |
: | name 2 | yellow |
Do something with the variable
I have some tests that test functions that process robot tests (robot
testing robot!) and I use this technique to embed a test case inside a
test case. I end up with a list of lists, with each element in the
list itself a list representing one row from a test case. In effect, a
2D array.
BTW, there's nothing special about ":" other that it is unobtrusive.
You could just as easily call it "_" or "table row" or something.
--
Bryan Oakley
Orbitz Worldwide
Welcome aboard and great to hear that you like Robot's BDD features.
Hopefully we can figure out a way to make it even better!
> RF does not easily support the multi-line
> table arguments that Cucumber/Gherkin does (see
> https://github.com/aslakhellesoy/cucumber-rails-test/blob/master/features/manage_lorries.feature).
> I've managed a work-around by using the ellipsis feature, but it's less than
> elegant.
>
> For example, the Gherkin statement:
>
> Given the following lorries:
> | name | colour |
> | name 1 | green |
> | name 2 | yellow |
I didn't know Cucumber had this kind of a feature but it looks pretty
handy. According to the docs [1] the step definition doesn't actually
get a list of list but a custom Cucumber::Ast::Table object that has
several convenience methods for accessing the data.
[1] https://github.com/aslakhellesoy/cucumber/wiki/multiline-step-arguments
> can be written in RF as
>
> Given the following lorries:
> ... | name | colour |
> ... | name 1 | green |
> ... | name 2 | yellow |
>
> but my Python function receives a list of strings rather than a
> two-dimensional list. I then have to split and strip the strings in order to
> get just the values.
An easy to to avoid the need of splitting and stripping is formatting
the data either like this:
Given the following lorries:
| ... | name | colour |
| ... | name 1 | green |
| ... | name 2 | yellow |
or
Given the following lorries:
... name colour
... name 1 green
... name 2 yellow
Notice that the first example uses the pipe-and-space-separated plain
text format in combination with the more common space-separated format
[2]. In both cases the `Given the following lorries:` keyword gets
altogether six arguments and you just needed to construct a list of
list yourself. In Python (if you omit the colon) you can use, for
example, this code:
def given_the_following_lorries(*lorries):
lorries_as_list_of_tuples = zip(lorries[:-1:2], lorries[1::2])
# your code continues here ...
We could also add a new keyword into Collections library [3] for
converting a list into a list of list.
[3] http://code.google.com/p/robotframework/wiki/CollectionsLibrary
> In order for my ideal situation to work, I think RF would have to support
> two-dimensional lists. Is this even feasible? Does anyone have a better
> solution? Thanks.
Bryan already explained a very cool hack that adds custom syntax for
this purpose with a special `:` keyword. If there is a larger need for
list of lists as arguments, adding build-in syntax for them is
possible too. We first needed to agree on the syntax and how the
argument is passed to the keyword.
Cheers,
.peke
--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org
Very nice. I hadn't come across that page so I didn't realize how it
was implemented.
> Given the following lorries:
> ... name colour
> ... name 1 green
> ... name 2 yellow
I had tried this, but didn't like how I got everything in a single list.
> In both cases the `Given the following lorries:` keyword gets
> altogether six arguments and you just needed to construct a list of
> list yourself. In Python (if you omit the colon) you can use, for
> example, this code:
>
> def given_the_following_lorries(*lorries):
> lorries_as_list_of_tuples = zip(lorries[:-1:2], lorries[1::2])
> # your code continues here ...
An interesting approach I hadn't considered. Unfortunately it's still
a bit more munging than would be nice.
> We could also add a new keyword into Collections library [3] for
> converting a list into a list of list.
>
> [3] http://code.google.com/p/robotframework/wiki/CollectionsLibrary
A keyword that would accept an argument for the position to split the
list at? That sounds like a fairly easy way to get something a little
cleaner.
> Bryan already explained a very cool hack that adds custom syntax for
> this purpose with a special `:` keyword. If there is a larger need for
> list of lists as arguments, adding build-in syntax for them is
> possible too. We first needed to agree on the syntax and how the
> argument is passed to the keyword.
For some reason, Google Groups didn't email me of Bryan's post so I
didn't see it until your response. I'll give that a try. I think
supporting "table" arguments would be a great default feature for
Robot. I like the idea of using the colon keyword as it complements
the ellipses keyword, being they are both argument modifiers.
Thank you Bryan and Pekka for your advice!
--
Steve Fox
and sorry for not getting back to this earlier.
2011/5/4 Steve Fox <li...@thefoxhome.net>:
> On Mon, May 2, 2011 at 5:20 PM, Pekka Klärck <pe...@iki.fi> wrote:
>>
>> We could also add a new keyword into Collections library [3] for
>> converting a list into a list of list.
>>
>> [3] http://code.google.com/p/robotframework/wiki/CollectionsLibrary
>
> A keyword that would accept an argument for the position to split the
> list at? That sounds like a fairly easy way to get something a little
> cleaner.
This keyword would probably be pretty trivial to implement. Or
actually keywords as there probably should be a keyword also for
flattening such a list of list. Please submit an enhancement request
to the issue tracker if you think it is useful.
>> Bryan already explained a very cool hack that adds custom syntax for
>> this purpose with a special `:` keyword. If there is a larger need for
>> list of lists as arguments, adding build-in syntax for them is
>> possible too. We first needed to agree on the syntax and how the
>> argument is passed to the keyword.
>
> For some reason, Google Groups didn't email me of Bryan's post so I
> didn't see it until your response. I'll give that a try. I think
> supporting "table" arguments would be a great default feature for
> Robot. I like the idea of using the colon keyword as it complements
> the ellipses keyword, being they are both argument modifiers.
Did you try it? How well did it work?
Thomas,
I had found your post when I was first looking for a solution to this,
and it was great to see an example of how to combine the BDD and
Data-Driven formats. Unfortunately it's not quite what I'm trying to
achieve, which is tabular arguments. Rather than a table of multiple
arguments, I would like one argument to hold a single two-dimensional
list of data. Thank you for your help!
--
Steve Fox
Unfortunately I'm under a deadline right now and haven't had any time
to devote to this. I will be getting to it as soon as I have a moment
to spare. Sorry for not being responsive.
--
Steve Fox
No worries. If we end up adding new syntax to the framework the
decision should not be made in hurry.