Does anyone know if cucumber/Java supports the functionality of multiple steps to access the same stepDefinition?
What I am trying to achieve is to use as a Given a step that at the moment is used as a When (in another more complex test where the current When becomes just a precondition)
In my previous experience (Specflow/.Net) I could use something like
[Given(#"the user added a (.*) to the cart")]
[When(#"the user adds a (.*) to the cart")]
public void WhenTheUserAddsATotheCart(string product){
////code that adds to the cart
}
If I use the same methodology as in Specflow, a DuplicateStepDefinitionException is thrown.
Because Cucumber doesn't take the key words (Given, When etc.) into consideration when matching the Steps with the step definitions. Cucumber only looks for a regEx in the step definitions so I would need to have only one step definition (Given OR When). Meaning
[When(#"the user adds a (.*) to the cart")]
will also match
[Given(#"the user adds a (.*) to the cart")]
My problem is that we use the Given at past tense and the When at present tense.
So the question is: how can I use the same implementation for two step definitions?
The only solution I see is to extract the contains of the method that implements the Given into another method and call it under both Given step definition and under When.Something like:
[Given(#"the user added a (.*) to the cart")]
public void GivenTheUserAddedATotheCart(string product){
addToTheCart(product);
}
[When(#"the user adds a (.*) to the cart")]
public void WhenTheUserAddsATotheCart(string product){
addToTheCart(product);
}
public void addToTheCart(String product){
////code that adds to the cart
}
... but I don't really find this a nice solution
I have found multiple discussions around this topic in the cucumber repo but most of them are specific to the cucumber-jvm implementation:
https://github.com/cucumber/cucumber-jvm/issues/957
https://github.com/cucumber/cucumber-jvm/issues/1341
https://github.com/cucumber/cucumber-jvm/issues/895
This is a controversial topic and as I far as I understood no official support for this feature has been implemented but there are some references on how this could be achieved. On the example shown, since the steps are similar I would just extended the regular expression on the step definition to match both steps:
[Given(#"the user add(s|ed) a (.*) to the cart")]
public void WhenTheUserAddsATotheCart(string tense, string product){
////code that adds to the cart
}
Of course, this solution produces an additional parameter on the method which is useless unless you are planning to follow a different path when the step is executed in the past (Given) or in the present (When).
Related
I have just discovered contextSuperClass and have been experimenting with using it to provide scope annotations when building a symbol table in a first pass (I have a forward reference DSL).
I set the option in the grammar:
options {
tokenVocab=MyLexer;
language = CSharp;
contextSuperClass = interpreter.MyParserRuleContext;
}
and I have a class that derives from ParserRuleContext:
public class MyParserRuleContext : ParserRuleContext
{
public MyParserRuleContext()
{ }
public MyParserRuleContext(ParserRuleContext parent, int invokingStateNumber) : base(parent, invokingStateNumber)
{
}
public IScope ContextScope { get; set; }
}
So far so good. I use ParseTreeWalker with a listener (Enter/Exit methods) to walk the tree for the 1st pass and build the symbol table adding local scopes, etc into my ContextScope custom property.
The first issue is of course after the symbol table pass I am at the end of the token stream - the tree is walked.
The 2nd parse uses a visitor to evaluate the final result.
I have two questions:
How do I "reset" the parser so that it is at the root again without loosing scopes I have added into my custom property?
The second question is broader, but similar. Is this even a reasonable way to add scope annotations to the parse tree?
I have previously tried to use ParseTreeProperty<IScope> to add scope annotations, but the problem is similar. During the 2nd phase, the context objects provided in the visitor are not the same objects added to ParseTreeProperty<IScope> concurrent dictionary from the 1st pass - so they are not found. Between the 1st & 2nd passes I have only found parser.reset() as a way to start the parser over, and (of course) it appears to fully reset everything and I loose the any state I created in the 1st pass.
I am likely missing completely missing something here - so any help to put me in the right direction will be greatly appreciated.
Consider this feature snippet:
Given the date is '2022-01-01'
...
When the date is '2022-01-31'
...
One identical step but used with two different keywords. I haven't find much discussion about the naming convention in this case. I'd love for people to give their input.
The three main approaches I suppose are:
Name method with first keyword you use. If you need to use it again, just do it and ignore the fact that the method contains "Given" in its name
[Given(#"the date is '.*'")]
[Then(#"the date is '.*'")]
public void GivenTheDateIs(string date)
{
...
}
Use appropriate keyword in method name and create new method if needed more than once
[Given(#"the date is '.*'")]
public void GivenTheDateIs(string date)
{
//same code
}
[Then(#"the date is '.*'")]
public void ThenTheDateIs(string date)
{
//same code
}
Don't use keyword in method name
[Given(#"the date is '.*'")]
[Then(#"the date is '.*'")]
public void TheDateIs(string date)
{
...
}
Which one do you use and why?
Given is for setting up state
When is for doing something
Then is for evaluating results
In English at least tense differentiates
Given - past tense
When - present tense
Then - future tense
Generally When's are going to be done inefficiently.
With a UI a When will involve a browser interaction. Often a Given that does the same thing can be done more efficiently without that browser interaction. With an API the When will be done by a request/response cycle. Again a Given can do the same thing without the request/response.
For example consider adding the behaviour registration. First you would do
When 'I register' do
fill_in name, with: "Fred"
...
submit_form
end
But for you given you might do
Given 'I am registered' do
User.create(
name: "Fred"
...
end
end
which is much much faster.
You will use When I register only a few times in your application
You will use Given I am registered (in some form or other) for almost every user interaction you write a scenario for.
For the above example the Then is
Then 'I should be registered' do
# check UI for proof or registration
end
So Given's, When's and Then's are not only different in their context and tense, but also they are different in their implementations and their frequency of use.
The idea that a Given could be identical to a When or Then just reflects a lack of understanding and precision in your use of language for your scenarios and code for the implementation of your step definitions.
Of course you are allowed to write Cukes without this precision and control, but you don't need to, and you will gain alot if can write precisely enough that you never have to worry about the difference between a Given, When or Then
Caveats: Answer is opinionated, but question is an excellent one in my opinion. All code and examples are Ruby. All the examples are crude and simplistic. Putting lots of code in step def and calling the database directly in test code is poor practice.
I would like to write a number in cucumber page. Please let me know How can I write this.
Scenario Outline: Enter an invalid URL
Given the context "Invalid URL" is open on "Market"
When user is on the error 404 page
Then page not found message is displayed
But I have observed that 404 is taken as a parameter.
Sure, you just have to handle it as a regular expression (regex) in your step definitions. Your step definition could read as following:
#When("^When user is on the error \"(\\d+)\" page$")
public void When_user_is_on_the_error_page(int errorNum) throws Throwable {
...
}
That'll handle 1 or more digits. The \d represents a digit and the + sign represents "1 or more".
I personally like wrapping my parameters in double quotes ("") because then the IDE understands it's a parameter and can help you out with autocomplete, etc.
If you want to restrict it to more specific numbers (say only three digits) you can refine your regex to something like [\d]{3}. Oracle have lessons on Java regex here.
With
When user is on the error 404 page
You could use in the steps:
#When("^When user is on the error (.*) page$")
public void When_user_is_on_the_error_page(int errorNum) {
...
}
the (.*) will take whatever is in that slot and use as a variable that will be defined by the type between the (). In this case, the '400' will be converted to a int, thanks to:
(**int** errorNum){ ...}
If you have no practice with regex, it can be really useful since it will make your steps easier to read, since the (.*) doesn't have a pre defined type.
Currently diving into DDD and i've read most of the big blue book of Eric Evans. Quite interesting so far :)
I've been modeling some aggregates where they hold a collection of entities which expire. I've come up with a generic approach of expressing that:
public class Expirable<T>
{
public T Value { get; protected set; }
public DateTime ValidTill { get; protected set; }
public Expirable(T value, DateTime validTill)
{
Value = value;
ValidTill = validTill;
}
}
I am curious what the best way is to invalidate an Expirable (nullify or omit it when working in a set). So far I've been thinking to do that in the Repository constructor since that's the place where you access the aggregates from and acts as a 'collection'.
I am curious if someone has come up with a solution to tackle this and I would be glad to hear it :) Other approaches are also very welcome.
UPDATE 10-1-2013:
This is not DDD with the CQRS/ES approach from Greg Young. But the approach Evans had, since I just started with the book and the first app. Like Greg Young said, if you have to make good tables, you have to make a few first ;)
There are probably multiple ways to approach this, but I, personally, would solve this using the Specification pattern. Assuming object expiration is a business rule that belongs in the domain, I would have a specification in addition to the class you have written. Here is an example:
public class NotExpiredSpecification
{
public bool IsSatisfiedBy(Expirable<T> expirableValue)
{
//Return true if not expired; otherwise, false.
}
}
Then, when your repositories are returning a list of aggregates or when performing any business actions on a set, this can be utilized to restrict the set to un-expired values which will make your code expressive and keep the business logic within the domain.
To learn more about the Specification pattern, see this paper.
I've added a method to my abstract repository InvalidateExpirable. An example would be the UserRepository where I remove in active user sessions like this: InvalidateExpirable(x => x.Sessions, (user, expiredSession) => user.RemoveSession(expiredSession));.
The signature of InvalidateExpirable looks like this: protected void InvalidateExpirable<TExpirableValue>(Expression<Func<T, IEnumerable<Expirable<TExpirableValue>>>> selector, Action<T, Expirable<TExpirableValue>> remover). The method itself uses reflection to extract the selected property from the selector parameter. That property name is glued in a generic HQL query which will traverse over the set calling the remove lambda. user.RemoveSession will remove the session from the aggregate. This way the I keep the aggregate responsible for it's own data. Also in RemoveSession an domain event is raised for future cases.
See: https://gist.github.com/4484261 for an example
Works quite well sofar, I have to see how it works further down in the application though.
Have been reading up on DDD with CQRS/ES (Greg Young approach) and found a great example on the MSDN site about CQRS/ES: http://msdn.microsoft.com/en-us/library/jj554200.aspx
In this example they use the command message queue to queue a Expire message in the future, which will call the Aggregate at the specified time removing/deactivate the expirable construct from the aggregate.
I have two classes (class A and B) both marked with [Binding]. Currently I'm using a class per feature. Classes A and B both have a step that looks like this:
[Given(#"an employee (.*) (.*) is a (.*) at (.*)")]
public void GivenAnEmployeeIsAAt(string firstName, string lastName, string role, string businessUnitName)
When I run the scenario for the features defined in class A, and the test runner executes the step indicated above, the matching step in class B gets executed instead.
Are "Steps" global as well? I thought only the "hook" methods are global, i.e. BeforeScenario, AfterScenario. I do not want this behavior for "Given", "Then", and "When". Is there any way to fix this? I tried putting the two classes in different namespaces and this didn't work either.
Also, am I potentially misusing SpecFlow by wanting each "Given" to be independent if I put them in separate classes?
Yes Steps are (per default) global. So you will run into trouble if you define two attributes that have RegExps that matches the same Step. Even if they are in separate classes.
Being in separate classes, or other placement (other assembly even) doesn't have anything to do with how SpecFlow groups it - it's just a big list of Given's, When's and Then's that it try to match the Step against.
But there's a feature called Scoped Steps that solves this problem for you. Check it out here: https://github.com/techtalk/SpecFlow/blob/master/Tests/FeatureTests/ScopedSteps/ScopedSteps.feature
The idea is that you put another attribute (StepScope) on your Step Defintion method and then it will honor that scoping. Like this for example:
[Given(#"I have a step definition that is scoped to tag (?:.*)")]
[StepScope(Tag = "mytag")]
public void GivenIHaveAStepDefinitionThatIsScopedWithMyTag()
{
stepTracker.StepExecuted("Given I have a step definition that is scoped to tag 'mytag'");
}
... or to scope an entire step definition class to a single feature:
[Binding]
[StepScope(Feature = "turning on the light should make it bright")]
public class TurningOnTheLightSteps
{
// ...
}
This step definition is using a StepScope for a tag. You can scope your steps by:
Tag
Scenario title
Feature title
Great question! I hadn't fully understood what that was for until now ;)