Mapping wrong number of parameter from Gherkin features file to step definition - cucumber

I had feature declaration like this:
Feature: find taxi and minicabs information
in order to get taxi and minicabs contact at given location
as application developer
I want to find tax and minicabs contact information at given location or query options
Scenario Outline: find taxi and minicabs contact information
Given Joe at location with <lat> and <lon>
When get all taxi and minicabs contacts information
Then should see list of taxi and minicabs
And all of them are at location with <lat> and <lon>
Examples:
| lat | lon |
| 51.490075 | -0.133226 |
And I had step definition like this:
#Given("^Joe at location with ([+-]?([0-9]+[.])?[0-9]+) and ([+-]?([0-9]+[.])?[0-9]+)$")
public void joeAtLocationWithLatAndLon(Number lat, Number lon) throws Throwable {
....
}
I expected I can received 2 parameters but Cucumber passed to me 4 parameters.
Error message as below:
with pattern [^Joe at location with ([+-]?([0-9]+[.])?[0-9]+) and ([+-]?([0-9]+[.])?[0-9]+)$] is declared with 2 parameters. However, the gherkin step has 4 arguments [51.490075, 51., -0.133226, 0.].
Do you have any idea about this? btw, I very appreciate if you can explain the way cucumber identify the number of parameters or share me any document about that.

The issue is the two inside brackets inside the regular expression. Using the current regex you will get 2 groups - one the whole "51.490075" and second "51." which matches the exp in the ([0-9]+[.]) part. Thus 4 arguments are created.
Remove the inside brackets and you will get just one argument for each, so two in total.
The next problem you are going to have is cucumber does not know how to transform String to Number class unless you tell it. For this you need to make use of the Transform annotation and create a specific class for this.
import cucumber.api.Transformer;
public class NumberTransformer extends Transformer<Number>{
#Override
public Number transform(String value) {
return Double.parseDouble(value);
}
}
#Given("^Joe at location with ([+-]?[0-9]+[.]?[0-9]+) and ([+-]?[0-9]+[.]?[0-9]+)$")
public void joeAtLocationWithAnd(#Transform(NumberTransformer.class)Number arg1, #Transform(NumberTransformer.class)Number arg2) throws Exception {
System.out.println(arg1);
System.out.println(arg2);
}
For the transforming issue you can also look up xstreams. If you are using cucumber 2, these kind of transformation is easier by using Xstreamconvertor annotation - https://github.com/cucumber/cucumber-jvm/pull/1010

Related

UML class diagram dependency or association

I'm not really sure about how to distinguish whether I should define a relationship as dependency or association for certain cases.
For example,
class AttendanceSheet {
Map<String> students;
boolean[] attend;
public void addStudent(Student s)
{
students.add(s.getName(),s.getStudentNumber());
}
public void checkAttendance(String name) { //... }
}
class Student {
private String name;
private int staffNumber;
//more information such as address, age, etc..
Student(String n, int sn)
{
name = n;
studentNumber = sn;
}
public String getName()
{
return name.clone();
}
public String getStudentNumber()
{
return studentNumber;
}
}
For this case, would Student and Association have association or dependency?
This is because I'm not sure whether the association must have the actual reference of the object or it suffice to just have certain information that can reach the object (since student id and number is far more enough to know find out which student object it is directing to).
In your case the <<uses>> is sufficient, because you don't have actual properties of type Student in AttendanceSheet.
As a side note: not using object references and instead just having the studentNumber is - to say the least - an odd design. But I don't know the context.
On the business level those objects are related, but there is no single preferred method of diagramming this relationship.
Please see Section 9.5.4 of UML specification for more details on the topic, especially Figure 9.12
To be specific those two notations are semantically equivalent (I'm ignoring irrelevant details):
In the first one to keep a traceability you can use an explicit Dependency pretty much the way you did.
One can also consider students as a Shared Aggregation, however it might be also considered an overkill. Not necessary, just showing a possibility for an answer completeness.
You may also consider Qulified associations to indicate a reference to the Student is based on their specific properties. This is pretty much closest to your need. Sorry, I don't know how to achieve such notation in my tool, but you can find more details in Figure 11.37 in Section 11.5 of the aforementioned specification.

Conditional Inputs?

I'm trying to write a cucumber test for part of our application (I'm completely new to cucumber, and writing acceptance tests really), and I have a step in the test, which I want to do one of 2 different things. I want it to either check for a specific value, or check for a system default value.
This is what I came up with
Scenario Outline: English News
Given with the locale is set to '<language>'
When a user views the page
Then they see the <image> image
Examples:
| language | image |
| en-gb | default |
| fr | "french.png" |
This then hits one of 2 different step definitions,
#And("^they see the default image$")
public void defaultImage() throws Throwable {
// check for system default
}
#And("^they see the \"(.*)\" image$")
public void customImage(String image) throws Throwable {
// check for specific value from the input
}
Is this the correct way to do this? My TL has suggested that I should actually only have the one step def, and pass "default" as the input, and then do a conditional check inside the step def, like this:
#And("^they see the \"(.*)\" image$")
public void checkImage(String image) throws Throwable {
if ("default".equals(image)){
// check for system default
} else {
// check for specific value from the input
}
}
Which is the correct way to do this? Any help is greatly appreciated.
your default image must have a real name, right ? so why not validating its real name ? because "default" could be anything so not everyone may understand the same thing.
If you do this, indeed you need only one step def. I wouldn't put an if check, I would assert the real name. You can maybe add a comment in your example table saying that the first value is the default, so that it's clear for everyone in your team.

Un-nesting nested tuples to single terms

I have written an udf (extends EvalFunc<Tuple>) which has as output tuples with inner tuples (nested).
For example the dump looks like:
(((photo,photos,photo)))
(((wedg,wedge),(audusd,audusd)))
(((quantum,quantum),(mind,mind)))
(((cassi,cassie),(cancion,canciones)))
(((calda,caldas),(nova,novas),(rodada,rodada)))
(((fingerprint,fingerprint),(craft,craft),(easter,easter)))
Now I want to process each of this terms, distinct it and give it an id (RANK). To do this, i need to get rid of the brackets. A simple FLATTENdoes not help in this case.
The final output should be like:
1 photo
2 photos
3 wedg
4 wedge
5 audusd
6 quantum
7 mind
....
My code (not the udf part and not the raw parsing):
tags = FOREACH raw GENERATE FLATTEN(tags) AS tag;
tags_distinct = DISTINCT tags;
tags_sorted = RANK tags_distinct BY tag;
DUMP tags_sorted;
I think your UDF is return is not optimal for your workflow. Instead of returning a tuple with variable number of fields (which are tuples), it would be a lot more convenient to return a bag of tuples.
Instead of
(((wedg,wedge),(audusd,audusd)))
you will have
({(wedg,wedge),(audusd,audusd)})
and you will be able to FLATTEN that bag to:
1. make the DISTINCT
2. RANK the tags
To do so, update your UDF like this :
class MyUDF extends EvalFunc <DataBag> {
#Override
public DataBag exec(Tuple input) throws IOException {
// create DataBag
}
}

How can I get the Scenario Outline Examples' table?

In AfterScenario method, I want to get the rows from table "Examples" in Scenario Outline, to get the values in it, and search that specific values in the database
I know that this can be achieved by using Context.Scenario.Current...
Context.Scenario.Current[key]=value;
...but for some reason I'd like to be able to get it in a simpler way
like this:
ScenarioContext.Current.Examples();
----------- SCENARIO --------------------------------
Scenario Outline: Create a Matter
Given I create matter "< matterName >"
Examples:
| matterName |
| TAXABLE |
----------AFTER SCENARIO -----------------------------------
[AfterScenario()]
public void After()
{
string table = ScenarioContext.Current.Examples();
}
So if you look at the code for ScenarioContext you can see it inherits from SpecflowContext which is itself a Dictionary<string, object>. This means that you can simply use Values to get the collection of values, but I have no idea if they are Examples or not.
The best solution I came up with was to infer the examples by keeping my own static singleton object, then counting how many times the same scenario ran.
MyContext.Current.Counts[ScenarioContext.Current.ScenarioInfo.Title]++;
Of course, this doesn't work very well if you don't run all the tests at the same time or run them in random order. Having a table with the examples themselves would be more ideal, but if you combine my technique along with using ScenarioStepContext you could extract the parameters of the Examples table out of the rendered step definition text itself.
Feature
Scenario Outline: The system shall do something!
Given some input <input>
When something happens
Then something should have happened
Examples:
| input |
| 1 |
| 2 |
| 3 |
SpecFlow Hook
[BeforeStep]
public void BeforeStep()
{
var text = ScenarioStepContext.Current.StepInfo.Text;
var stepType = ScenarioStepContext.Current.StepInfo.StepDefinitionType;
if (text.StartsWith("some input ") && stepType == StepDefinitionType.Given)
{
var input = text.Split(' ').Last();
}
}

Java Cucumber Step Definition for vertical DataTable

I'm using cucumber-jvm. I have the following in a .feature file:
Background:
Given the following account file line:
| First Name | Lance |
| Last Name | Fisher |
| Corporate Name | |
This is a vertically-oriented table. The following generated step definition uses First Name and Lance as the headers, where First Name, Last Name, and Corporate Name should be the headers.
#Given("^the following account file line:$")
public void the_following_account_file_line(DataTable arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
// For automatic conversion, change DataTable to List<YourType>
throw new PendingException();
}
How would I implement a step definition to handle a vertical table rather than a horizontal table?
Just receive the value on parameter as Map<String, String> instead of DataTable. Cucumber will convert the first columns as map keys and the second column as map values.
It's simple enough, as the Datatable can return an array of arrays of strings, and you can step through this in whatever manner you wish.
However, I'd agree with Prakash Murthy that the horizontal table is more usual and useable.

Resources