How to use negative expression in Cucumber Java - cucumber

In Cucumber you can write Then expressions and their step definitions to verify the results. The problem is I don't want to write 2 different step definitions for checking the outcome. One example would be like this:
Then the transaction is successful
and
Then the transaction is not successful
How can I get around this?
I've found out that in Ruby you could consolidate step definitions by using capturing optional groups as described [here]. That is:
Then /^I should( not)? see the following columns: "([^"]*)"$/ do |negate, columns|
within('table thead tr') do
columns.split(', ').each do |column|
negate ? page.should_not(have_content(column)) : page.should(have_content(column))
end
end
end
But I don't know whether this is possible in Java or not. And even if it is what type of variable should I be capturing?

Why not write two step definitions. Each one is simpler, on topic, doesn't require a regex. If you delegate the work the step definitions do to a helper method you can remove almost all of the code duplication as well
Then I should see the following columns |cols|
should_see_cols(cols)
end
Then I should not see the following columns |cols|
should_not_see_cols(cols)
end
Now you have super simple crystal clear step definitions and you can write your method/ methods however you want.
Step definition duplication is irrelevant if all your step definitions just make a single call to a helper method. You can be as DRY as you like with your helper methods and still keep your scenarios super simple and remove the need to use regex's and complex logic in your step defs.

In Java, I would create one method with capture groups (is|is not), and derive a boolean from that which I would compare to the value. On the other hand, this adds logic to your test implementation so there is something to be said for #diabolist's solution of having 2 distinct step definitions.

Related

Python SCons Action?

I've been searching the documentation for a long time and still can't figure this out.
In the SCons documentation, there is discussion about adding a PreAction or PostAction. In the examples, they call an example method:
foo = Program('foo.c')
AddPreAction(foo, 'pre_action')
This calls 'pre_action' before 'foo.c' is compiled and linked. However, there is no explanation about what format 'pre_action' must take.
I have discovered that there are several pre-built actions, such as 'Copy'. However, I cannot find the source of 'Copy' to reverse-engineer it and write my own.
Can anyone point me to a guide as to how to create my own Actions? I either need an interface for calling my own method such as 'pre_action' above, or a guide for writing an Action class.
Really, even just some example code that is actually complete enough to use would be helpful...
The manpage section Action Objects lists the types of things that can be passed to the Action factory function to create an action; that is also what you pass to AddPostAction and AddPreAction as the second argument - that is, either an Action already made by a previous call to Action, or something that can be converted into one like a command string, or a list of such, or a function with appropriate signature. Pre/Post will simply call the Action function with that argument. So in that section, where there's an example with a call to Action, you could just plug that argument into AddPreAction, or you could save the result of calling Action and give that as the argument to AddPreAction.
The amount of flexibility here makes it a little tricky to document concisely.
(btw the source to Copy is a function called copy_func but you probably don't want to use that form because it's a couple of extra levels of abstraction you won't need)

Is there an equivalent OR logic based from a Variable value in Origen?

I am working on Verigy 93K test program and I have a logic that I would like to know if there's an equivalent code in Origen.
I am working on Verigy 93K test program and I have this logic (IF condition) that I need to insert in my flow.
Basically, I have a variable called 'INSERTION' and this will have different values like 'GCORR', 'VCORR' and others.
I would like to know if there's an equivalent code like this in Origen.
I attached a snapshot, hope that it can help clarify my question more.
In this logic, I would like to check the INSERTION value and if the value is not equal to GCORR or VCORR, the logic should pass, else, fail.
Here is the screenshot:
This pull-request adds an official API for this.
This example would be implemented as:
whenever_any ne(:INSERTION, 'GCORR'), ne(:INSERTION, 'VCORR') do
# Your tests in here
end
That would produce something logically equivalent and which can be re-targeted to other platforms.
If you don't care about that and want to produce exactly as you have it in the above example, then this should work too (where the OR is hard-coded for V93K syntax):
whenever ne(:INSERTION, 'GCORR|VCORR') do
# Your tests in here
end
Here is the preliminary documentation of this feature from the above PR - https://github.com/Origen-SDK/origen_testers/blob/66345c9422d9fa6b2577af20110259e45c2bdd26/templates/origen_guides/program/flowapi.md.erb#L71
I couldn't find api support on flow control or variable values beyond "if/unless_enable" support which can help check for 1 or zero. One way is to use render.
render 'if #INSERTION != "GCORR|VCORR" then'
render '{'
# your code for non-GCORR_VCORR flow
render "} \n else \n { \n } "

Is it possible to split array in Gherkin to the next line

I have step where I am have String Array, something like this:
Then Drop-dow patient_breed contains ['Breed1', 'Breed2',.... Breed20']
I need to split this text on two lines. I know that in Gherkin there is expression """. I try something like this:
Then Drop-dow patient_breed contains ['Breed1',
"""
'Breed2',.... Breed20']
"""
It didn't help. Is there any solution?
What do you gain by putting this string in your scenario. IMO all you are doing is making the scenario harder to read!
What do you lose by putting this string in your scenario?
Well first of all you now have to have at least two things the determine the exact contents of the string, the thing in the application that creates it and the hardcoded string in your scenario. So you are repeating yourself.
In addition you've increased the cost of change. Lets say we want our strings to change from 'Breedx' to 'Breed: x'. Now you have to change every scenario that looks at the drop down. This will take much much longer than changing the code.
So what can you do instead?
Change your scenario step so that it becomes Then I should see the patient breeds and delegate the HOW of the presentation of the breeds and even the sort of control that the breeds are presented in to something that is outside of Cucumber e.g. a helper method called by a step definition, or perhaps even something in your codebase.
Try with a datatable approach. You will have to add a DataTable argument in the stepdefinition.
Then Drop-dow patient_breed contains
'Breed1'
'Breed2'
...
...
...
'Breed20']
For a multiline approach try the below. In this you will have to add a String argument to the stepdefinition.
Then Drop-dow patient_breed contains
"""
['Breed1','Breed2',.... Breed20']
"""
I would read the entire string and then split it using Java after it has been passed into the step. In order to keep my step as a one or two liner, I would use a helper method that I implemented myself.

prolog recursive searching with contraints

I have a house with rooms that are defined with connections for when you can go from one room to another eg.
connection(garage,sidehall).
connection(sidehall,kitchen).
connection(kitchen,diningroom).
canget(X,Y):-connection(X,Y).
canget(X,Y):-connection(X,_),
write('player goes from '),write(X),write(' to '),write(Y),nl,
canget(_,Y).
Im trying to figure out how make it so the player can only get from one room to another when they have a specific item, such as you can only be in the kitchen when items = gloves.
canget(X,Y,Item):-connection(X,Y,Item),canbein(Y,Item).
canget(X,Y,Item):-connection(X,Somewhere,Item),canbein(Somewhere,Item),canget(Somewhere,Y,Item).
tried defining canbein with:
canbein(kitchen):- item(sword).
canbein(sidehall):- item(hat).
but that doesnt work!
Have defined my items as such, not sure if this is right either:
item(gloves,sword,helm,cheese).
Basically, have i declared my item values correctly?
How can i use the specific item value to make canget x to y false?
Thank you!
Well, I see a few problems with your code. Firstly, you call canbein with two arguments (from canget predicate). However, canbein is defined as single-argument predicate. Therefore, the call always fails as no canbein/2 predicate exists.
I suggest the following modification:
canbein(kitchen, sword).
canbein(sidehall, hat).
Than, the item definition is not required. Let's think about what happens during the unification of
canget(X,Y,Item) :- connection(X,Y,Item), canbein(Y,Item).
Let's assume the following setting X=sidehall, Y=kitchen, Item==sword. This predicate should be OK. Assuming the conection predicate is OK, prolog tries to find canbein(Y, Item) i.e. canbein(kitchen, sword) and it succeeds.
On the contrary, if the Item is different the unification fails, hence it works as expected.
The second problem is the item predicate. By your definition, it expects 4 arguments. That's nonsense, of course. You should declare it like
item(gloves).
item(sword).
item(helm).
item(cheese).
However, I don't think this predicate is necessary at all. Just to be clear, try to call item(X) and obtain all results (the four declared). Try it with the prior definition - what should you even ask for?
I hope it helps :)

automapper - simplest option to only write to destination property if the source property is different?

NOTE: The scenario is using 2 entity framework models to sync data between 2 databases, but I'd imagine this is applicable to other scenarios. One could try tackling this on the EF side as well (like in this SO question) but I wanted to see if AutoMapper could handle it out-of-the-box
I'm trying to figure out if AutoMapper can (easily :) compare the source and dest values (when using it to sync to an existing object) and do the copy only if the values are different (based on Equals by default, potentially passing in a Func, like if I decided to do String.Equals with StringComparison.OrdinalIgnoreCase for some particular pair of values). At least for my scenario, I'm fine if it's restricted to just the TSource == TDest case (I'll be syncing over int's, string's, etc, so I don't think I'll need any type converters involved)
Looking through the samples and tests, the closest thing seems to be conditional mapping (src\UnitTests\ConditionalMapping.cs), and I would use the Condition overload that takes the Func (since the other overload isn't sufficient, as we need the dest information too). That certainly looks on the surface like it would work fine (I haven't actually used it yet), but I would end up with specifying this for every member (although I'm guessing I could define a small number of actions/methods and at least reuse them instead of having N different lambdas).
Is this the simplest available route (outside of changing AutoMapper) for getting a 'only copy if source and dest values are different' or is there another way I'm not seeing? If it is the simplest route, has this already been done before elsewhere? It certainly feels like I'm likely reinventing a wheel here. :)
Chuck Norris (formerly known as Omu? :) already answered this, but via comments, so just answering and accepting to repeat what he said.
#James Manning you would have to inherit ConventionInjection, override
the Match method and write there return c.SourceProp.Name =
c.TargetProp.Name && c.SourceProp.Value != c.TargetProp.Value and
after use it target.InjectFrom(source);
In my particular case, since I had a couple of other needs for it anyway, I just customized the EF4 code generation to include the check for whether the new value is the same as the current value (for scalars) which takes care of the issue with doing a 'conditional' copy - now I can use Automapper or ValueInject or whatever as-is. :)
For anyone interested in the change, when you get the default *.tt file, the simplest way to make this change (at least that I could tell) was to find the 2 lines like:
if (ef.IsKey(primitiveProperty))
and change both to be something like:
if (ef.IsKey(primitiveProperty) || true) // we always want the setter to include checking for the target value already being set

Resources