[RUBY]Cucumber: Step Definitions multiple Optional Group - Capture in same step

101 views
Skip to first unread message

Frank

unread,
Sep 21, 2017, 11:42:40 AM9/21/17
to Cukes

I'm trying to write a step that will match the following steps that are similar and capture parameters:

Step1: And I delete the filter(s) using the "UI"

Step2: Then I delete the filter(s) using the "API" for "doc-browser" context

Step3: I delete the filter(s) using the "API" for "doc-browser" context with user "file_user2"

I don't want to create 3 separate steps, they all start with I delete the filter using the #{arg} and the last 2 just extend on that.

I thought this was going to accomplish it:

And(/^I delete the filter\(s\) using the "([^"]*)"(?: for "([^"]*)" context| with user "([^"]*)")?/) do |delete_method, context, user| case delete_method when 'API' if user.nil? SearchFilters.new.delete_global_local_filters(delete_method, api_context_val: context) else SearchFilters.new.delete_global_local_filters(delete_method, { api_context_val: context, username: user }) end when 'UI' SearchFilters.new.delete_global_local_filters(delete_method, filter_name: @filter_name) end end

However, I'm not capturing my username.

Is it possible to accomplish having one step definition that captures all 3 variations and still captures my arguments?

Andrew Premdas

unread,
Sep 21, 2017, 1:05:27 PM9/21/17
to cu...@googlegroups.com
I understand you don't want to use three different steps, but in this case you really should because

1. The implementation of each step is a clear one liner, so you are removing a case statement.
2. The regex for this step is horrible and you will be removing that
3. Each individual step provides the opportunity to simplify the parameters being passed, you have 2 API and one UI paramter which can just be removed entirely (if I understand the code correctly you can remove all the params and regexs)

This is a clear case where a little bit of repetition is a price well worth paying for a simpler implementation.

Reducing the number of step definitions by using regex's and params is often an anti-pattern.

All best

Andrew

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
------------------------
Andrew Premdas

Dana Scheider

unread,
Sep 21, 2017, 2:06:00 PM9/21/17
to cu...@googlegroups.com
I agree with Andrew. I generally consider a case statement to be a sign you need to either use more steps or extract a helper module, but in this case extracting a helper module wouldn't really help with your problem. I think your problem with the particular regex lies with your use of (?:) and parentheses, but the best solution would be to use a less complicated regex rather than fixing this one.
Dana

Frank

unread,
Sep 21, 2017, 3:31:54 PM9/21/17
to Cukes
Thank you to you both. 

I was too busy trying to be crafty and it seems like it would cause more headaches in the long run.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
------------------------
Andrew Premdas

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.

Chuck van der Linden

unread,
Sep 25, 2017, 2:07:23 PM9/25/17
to Cukes
The other advantage of distinct steps is that if you make a typo an IDE that knows cucumber (such as Rubymine) will color code the step as not matching an existing step definition.  This gives you some immediate feedback to inspect your step more closely to see why it is not being matched.  

If you have multiple captures, and Case statements, the IDE can't tell if something in the capture is not matched by a case statement that processes it, so you don't know there is an issue with a mismatch until you run the step and it gets caught in the default section of the case statement, and even then debugging time will be related to how helpful your case 'default' is at informing you the value you specified was not matched.
Message has been deleted

Andrew Premdas

unread,
Sep 26, 2017, 9:02:42 AM9/26/17
to cu...@googlegroups.com
This has already been answered on another thread

On 20 September 2017 at 21:17, <fbr...@i3logix.com> wrote:

I'm trying to write a step that will match the following steps that are similar and capture parameters:

Step1: 

And I delete the filter(s) using the "UI"

Step2: 

Then I delete the filter(s) using the "API" for "doc-browser" context

Step3: 

I delete the filter(s) using the "API" for "doc-browser" context with user "file_user2"

I don't want to create 3 separate steps, they all start with I delete the filter using the #{arg} and the last 2 just extend on that.

I thought this was going to accomplish it:

And(/^I delete the filter\(s\) using the "([^"]*)"(?: for "([^"]*)" context| with user "([^"]*)")?/) do |delete_method, context, user| case delete_method when 'API' if user.nil? SearchFilters.new.delete_global_local_filters(delete_method, api_context_val: context) else SearchFilters.new.delete_global_local_filters(delete_method, { api_context_val: context, username: user }) end when 'UI' SearchFilters.new.delete_global_local_filters(delete_method, filter_name: @filter_name) end end

However, I'm not capturing my username.

Is it possible to accomplish having one step definition that captures all 3 variations and still captures my arguments?

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Dave Pointon

unread,
Oct 3, 2017, 6:31:36 AM10/3/17
to Cukes
Whilst agreeing with the other contributors in principle (for me, the suggested repetition doesn't sit well with DRY), I feel that I oughtta point out that the regex is wrong - '|' captures either /for "doc-browser" context/ or /with user "file_user2"/ -  try something like...
And(/^I delete the filter\(s\) using the "([^"]*)"(?: for "([^"]*)" context(?: with user "([^"]*)")?)?/) do

Best rgds,
Dave P
Reply all
Reply to author
Forward
0 new messages