Story Runner: Readability of output with multiple params

Fistly, many, many thanks for RSpec and Story Runner.

Minor request to improve readability of output

Given a scenario item with multiple params…
Eg. And “the user belongs to”, “Joe”, “Acme” do |user_name,
company_name|

The readability of the following output is less than ideal…
“And the user belongs to company,Joe Public, No Videos”

It would be great if something like the following were possible.
And “the user $1 belongs to $2”, “Joe”, “Acme” do |user_name,
company_name|

  • Andy

I would of posted a feature request, but rubyforge still doesn’t play
nice
with big brother’s transparent web proxy here in Singapore.

View this message in context:
http://www.nabble.com/Story-Runner%3A-Readability-of-output-with-multiple-params-tf4617148.html#a13186335
Sent from the rspec-users mailing list archive at Nabble.com.

On 10/12/07, Tasty [email protected] wrote:

It would be great if something like the following were possible.
And “the user $1 belongs to $2”, “Joe”, “Acme” do |user_name,
company_name|

You’d have no way of knowing this, because it’s something that Dan,
Aslak and I have discussed off line, but this is actually already in
the plan.

Also in the plan is a move to lighthouse, which should improve
everyone’s ability to submit requests, and ours to manage them.

Cheers,
David

On 10/13/07, David C. [email protected] wrote:

“And the user belongs to company,Joe Public, No Videos”
Also in the plan is a move to lighthouse, which should improve
everyone’s ability to submit requests, and ours to manage them.

Cheers,
David

ps:

And “the user $user belongs to $company”, “Joe”, “Acme”

Or even:

And “the user”, “Joe”, “works for”, “Acme”, “as a”, “janitor”

so the params are inline.

On 10/13/07, Dan N. [email protected] wrote:

Or even:

And “the user”, “Joe”, “works for”, “Acme”, “as a”, “janitor”

so the params are inline.

Dan - I know we discussed that possibility, but don’t recall where we
left the conversation. I think we were supposed to discuss this more
at length in Berlin. C’est la vie.

Since we have both approaches on the table, I’m curious to hear
thoughts from users - which would you prefer and why?

And “the user”, “Joe”, “works for”, “Acme”, “as a”, “janitor”

And “the user $user works for $company as a $jobtitle”, “Joe”, “Acme”,
“janitor”

Thanks,
David

Zach D.-2 wrote:

I like to keep them closer to customer readable/writable myself.

Customer readable/writable stories are important for me too.

To that end, I would prefer inline, Option 1.

  1. And “the user”, “Joe”, “works for”, “Acme”, “as a”, “janitor”
  2. And “the user $user works for $company as a $jobtitle”, “Joe”,
    “Acme”,
    “janitor”

Thanks
Andy

View this message in context:
http://www.nabble.com/Story-Runner%3A-Readability-of-output-with-multiple-params-tf4617148.html#a13196084
Sent from the rspec-users mailing list archive at Nabble.com.

When I first used story runner I thought the same option would be
needed.
Then I thought about it then came to the conclusion that it would be
more
clear to write something such as:

Given a user named, Joe
And a company named, Acme
And user works for, Acme
And user is a, Janitor

On 10/13/07, David C. [email protected] wrote:

And “the user”, “Joe”, “works for”, “Acme”, “as a”, “janitor”

I vote no on this.

And “the user $user works for $company as a $jobtitle”, “Joe”, “Acme”, “janitor”

If these are the two choices then this one is better, but this doesn’t
feel quite right.

It seems like StoryRunner should maintain consistent and clean
readability. The argument passing nature of declaring values used in
tests at the story part (Given, When, etc.) description reduces
readability.

For another discussion it may be valuable to discuss whether or not
the story parts (Given, When, etc…) should even support do/end
blocks. I realize this kills the ability to mark things as pending in
StoryRunner, but that seems like a side effect that could be overcome.

Do/end blocks seem to add unnecessary code ugliness for the Story’s
themselves. I like reading:

Given “a user for the company acme”
When “they login”
Then “they see their user profile”

And not:

Given "a user for the company", "Acme" do |company|
      # code here...
end
When "they login", "Joe" do |login|
    # the login code.
end
Then "they see their user profile" do
     #...
end

it seems like a good idea to keep acceptance test declaration separate
from the implementation this Story’s are supposed to be at a higher
level then spec examples. I like to keep them closer to customer
readable/writable myself.

Zach

Does it add any value to even add things like “Joe” and “Acme” into a
story part? It seems like that is an implementation detail of your
story.

Who cares about “Joe” or “Acme”, don’t you just care that you have a
user who works for a company. And if that company has a particular
trait wouldn’t it be cleaner to identify the company by that trait
rather then a name in the description?

IE: Given " a user who works for a company that sells cartoons"

And then in your helper you can use “Joe” and Acme"

def a_user_who_works_for_a_company_that_sells_cartoons
@user = Generate.user( “joe”)
@company = Generate.company(“Acme”)
@company.employees = @user
end

?

On 10/14/07, Pat M. [email protected] wrote:

IE: Given " a user who works for a company that sells cartoons"
?
How do you create two users?

Given “a user joe who works for a company that sells cartoons”
And “a user jim who works for a company that sells cartoons”

Leave it in the description and have a well named helper method
responsible for making these users.

def a_user_joe_who_works_for_a_company_that_sells_cartoons
create_a_user_who_works_for_a_company_that_sells_cartoons(“joe”)
end

Otherwise you will still most likely end up with a helper method and
you haven’t added any value except for making your story more cody by
passing arguments and creating unneeded do/end blocks.

Given “a user who works for a company that sells cartoons”, “Joe” do
|name|
create_a_user_who_works_for_a_company_that_sells_cartoons(“joe”)
end

Another option would be to not use a helper method at all and do the
real work inside of the do/end block, but no you’ve made your code not
reusable. How likely is it that you have one acceptance test where you
have a user who works for a company?

Given “a user who works for a company that sells cartoons”, “Joe” do
|name|
@company = Generate.company(“Acme”)
@user = Generate.user(“Joe”)
@company.employees << @user
end

I prefer hiding the implementation in well named helper methods as to
not take away from the a higher level of readability that the
acceptance test can accomplish. Granted, I’m shooting for the ideal,
which is a customer readable/writable acceptance test.

I don’t think argument passing in story parts is wrong, I think that
how they are being used in this thread is wrong. For example for a
game you may have an acceptance test that looks like:

Given “a user playing the game”
When “they make a guess of”, 200_000

etc…

This makes more sense to me then passing in something which adds no
value to the test, like the user’s name “Joe”


Zach D.
http://www.continuousthinking.com

On 10/14/07, Zach D. [email protected] wrote:


Zach D.
http://www.continuousthinking.com


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

How do you create two users?

Pat

On 10/14/07, Zach D. [email protected] wrote:

create_a_user_who_works_for_a_company_that_sells_cartoons(“joe”)
Another option would be to not use a helper method at all and do the
I prefer hiding the implementation in well named helper methods as to

etc…

This makes more sense to me then passing in something which adds no
value to the test, like the user’s name “Joe”

That’s a fair argument against this example, however I think that the
point of the example is that there will be cases with more than one
variable. For example:

Given “a ? account with ? dollars”

We could limit ourselves to one argument per method:

Given “a savings account”
And “500 dollars in the account”

But that strikes me as less user friendly as:

Given “a savings account with 500 dollars”

The syntax Dan introduced earlier in this thread comes from a
conversation he and I had a while back about FitLibrary’s DoFixture,
which uses Smalltalk-style keyword messages where every other cell is
part of a method name:

Given “a user of type”, “Admin”, “making a request for”, “user list”

This would result in a call to
a_user_of_type_making_a_request_for(“Admin”, “user list”). One way we
might be able to tie that Zach’s ideal (a normal sentence w/ lots of
helper methods) and make it a bit smarter would be something like
this:

def a__account_with__dollars(account_type, amount)
account = account_types[account_type].new(amount)
end

When the runner sees anything sent to Given, When or Then (or And)
that matches /^a\b(.+?)\baccount with\b(.+?)\bdollars$/, it would pass
$1.strip() and $2.strip() to this method.

The only problem with this is that I can easily imagine such patterns
starting to overlap in a larger story set, potentially producing
unwanted results. But perhaps that’s not as big a problem as I think?
Thoughts?

Dan - I’m curious as to your thoughts re: this supporting the perfect
vision of customer-readable/writable Acceptance Tests that Zach is
looking for.

Thoughts?

Cheers,
David

On 10/14/07, David C. [email protected] wrote:

rather then a name in the description?

def a_user_joe_who_works_for_a_company_that_sells_cartoons

When “they make a guess of”, 200_000

conversation he and I had a while back about FitLibrary’s DoFixture,

unwanted results. But perhaps that’s not as big a problem as I think?
Thoughts?

Dan - I’m curious as to your thoughts re: this supporting the perfect
vision of customer-readable/writable Acceptance Tests that Zach is
looking for.

Thoughts?

Nevermind. Pat M. just suggested a better idea in another thread
on this list:

http://rubyforge.org/pipermail/rspec-users/2007-October/003704.html

Cheers,
David

Of the options on the table, I prefer “using $placeholder values”
because
then it tells me the role the value plays in the sentence. Even Pat’s
version works by defining the $placeholders outside of the step.

In a “library” somewhere (we still need to define what a story/step
library
is or looks like):

define :given, "a user called $name working for $company as a $role" 

do
|name, company, role|

end

In the story definition:

Given "a user called Joe working for ACME as a janitor"

Same parser. $blah just maps to (.*?) - ie. a non-greedy match of
anything -
in terms of regexp.

I’m not a big fan of the alternating parameters thing - I just threw it
in
for completeness based on the Smalltalky conversation we had.