1
  1. I have developed a jBehave story to test some work flow implemented in our system. Let’s say this story is called customer_registration.story

  2. That story is a starting point of some other more complex work flows that our system supports. Those more complex work flows are also covered by different stories. Let’s say we have one of our more complex work flows covered by a customer_login.story

So the customer_login.story will look somehow like below:

Story: Customer Login

Narrative:

In order to access ABC application
As a registered customer
I want to login into the application

Scenario: Successfully login into the application

GivenStories: customer_registration.story

Given I am at the login page
When I type a valid password
Then I am able to see the application main menu

All works perfectly and I am happy with that.

3.The story at point 1 above (customer registration) is something I need to run on different sets of data. Let’s say our system supports i18n and we need to check that customer registration story runs OK for all supported languages, say we want to test our customer registration works OK with both en-gb and zh-tw

So I need to implement a multi_language_customer_registration.story that will look something like that:

Story: Multi language customer registration

Narrative:

In order to access ABC application
As a potential customer
I want to register for using the application

Scenario: Successfully customer registration using different supported languages

GivenStories: customer_registration.story

Then some clean up step so the customer registration story can run again

Examples:
|language|
|en-gb   |
|zh-tw   |

Any idea about how I could achieve this? Note that something like below is not an option as I do need to run the clean up step between runs.

GivenStories:  customer_registration.story#{0},customer_registration.story#{1}

Moving the clean up step inside the customer registration story is not an option too as then the login story will stop working.

Thanks in advance.

P.S. As you could guess in reality the stories we created are more complex and it is not an easy task to refactor them, but I am happy to do this for a real gain.

Julian
  • 3,678
  • 7
  • 40
  • 72

3 Answers3

2

First off, BDD is not the same as testing. I wouldn't use it for every single i18n scenario. Instead, isolate the bit which deals with i18n and unit test that, manually test for a couple and call it done. If you really need more thorough then use it with a couple of languages, but don't do it with all of them - just enough examples to give you some safety.

Now for the bit with the customers. First of all, is logging in and registration really that interesting? Are you likely to change them once you've got them working? Is there anything special about logging in or registration that's particular to your business? If not, try to keep that stuff out of the scenarios - it'll be more of a pain to maintain than it's worth, and if it's never going to change you can just test it once, manually.

Scenarios which show what the user is logging in for are usually more enticing and interesting to the business (you are having conversations with the business, right?).

Otherwise, here are the three ways in which you can set up a context (Given):

  • By hacking the data (so accessing the database directly)
  • Through the UI (or controller if you're automating from that level)
  • By using existing data.

You can also look to see if data exists, and if it doesn't, set it up. So for instance, if your customer is registered and you don't want him to be registered, you can delete his registration as part of setting up the context (running the Given step); or if you need him to be registered and he isn't, you can go through the UI to register him.

Lastly, JBehave has an @AfterScenario annotation which you can use to denote a clean-up step for that scenario. Steps are reusable - you can call the steps of the scenario from within another step in code, rather than using JBehave's mechanism (this is more maintainable anyway IMO) and this will allow you to avoid clearing registration when you log in.

Hope one of these options works for you!

Community
  • 1
  • 1
Lunivore
  • 17,277
  • 4
  • 47
  • 92
2

From a tactical standpoint, I would do this:

In your .story file

Given I set my language to {language}
When I type a valid password {pass}
Then I am able to see the application main menu

Examples:
|language|pass|
|en-gb   |password1|
|zh-tw   |kpassword2|

Then in your Java file,

@Given ("I set my language to $lang")
@Alias ("I set my language to {language}")

// method goes here

@When ("I type a valid password $pwrd")
@Alias ("I type a valid password {pass}")

// method goes here

@Then ("I am able to see the application main menu")
MDJ
  • 21
  • 2
0

most unit testing frameworks support this.

Look how mstest you can specify DataSource, nunit is similar https://github.com/leblancmeneses/RobustHaven.IntegrationTests

unfortunately some of the bdd frameworks i've seen try to replace existng unit test frameworks when it should instead work together to reuse the infrastructure.

https://github.com/leblancmeneses/BddIsTddDoneRight is fluent bdd syntax that can be used with mstest/nunit and works with existing test runners.

Leblanc Meneses
  • 3,001
  • 1
  • 23
  • 26
  • Thanks for your post but I am looking for a jBehave solution. We are on the java side (not that it really matters) and in JUnit you can also do lot of stuff. However, the problem I posted here is part of a end to end testing suite. JBehave fires REST and WS request or pushes buttons on various web pages doing exactly what a user and/or a client application do in the real world. When I said I was happy to do some refactor work I did not mean rewriting more than one year of good work do develop all these scenarios :-) – Julian May 26 '12 at 05:25
  • take a look at https://github.com/leblancmeneses/RobustHaven.IntegrationTests while not in java - you have full source that could be converted to java. We use selenium and watin and can build some large composite workflows: .Sequence(helper.DoPastDueFlow(xx, xx, xx, xx, xx)) .Sequence(...) .Sequence(...) about 6 classes to convert. Your existing recorded scenarios would go inside a visitor that would visit each node in the composite to execute the workflow. – Leblanc Meneses May 26 '12 at 19:41