Suppose i have a cucumber scenario like:
Scenario Outline: do something
Given do something with "<data1>"
AND done some process on "<data2>"
When again done some experiment on "<data3>"
Then checking "<result>"
Examples:
| data1 | data2 | data3 |result |
| value1| value2| value3| result1|
This scenario is completely fine, but imagine a this scenario with 5 more step with new data. That looks very annoying. Is there any way i can spit this examples table into column. If column spit is not possible then any other suggestion.
Each row of examples should have a reason behind them. If two rows have the same reason behind them, then you are just wasting runtime repeating yourself.
Lets take a simple example
Scenario Outline
When I register as <account> with <passsword>
Then I should be <result>
Examples
| account | password | result |
| free | too_short | unregistered |
| taken | ok | unregistered |
...
You can easily replace this complex scenario with two much simpler ones
Scenario: register with too short a password
When I register with too short a password
Then I should be told I need a longer password
Scenario: register with existing account
When I register with an existing account
Then I should be told the account is taken
There are several reasons to prefer doing things in this way
Each scenario is simpler to read
Each scenario tells you WHAT the behaviour is and WHY its important (with the examples you have to infer that from the data)
Each step definition is much simpler to implement
By making concrete the specifics of the example, you invite writing more scenarios around a particular subject.
You can apply this pattern to every Scenario Outline, and doing so will
fix your problem with to many examples
help you write better scenarios and code. Finding out the reason behind each example helps you write better code.
You do not have any other solution. The purpose of the examples is especially to have several lines:
Examples:
| data1 | data2 | data3 |result |
| value1| value2| value3| result1|
| value11| value12| value13| result2|
| value21| value22| value23| result3|
if you do not have several lines, you can put the data directly in your scenario (not Scenario Outline):
Scenario : do something
Given do something with "value1"
AND done some process on "value2"
When again done some experiment on "value3"
Then checking "result1"
I am having trouble understanding what you want to do, or what you mean by 'column split', so not sure if this answers your question or not.
You can split your examples up into different groups where the examples have a common theme, you can even tag those groups
#golden_path
Examples: valid values
| data1 | data2 | data3 | result |
| value1 | value2 | value3 | result1 |
| bar | foo | fizz | buzz |
#low_boundary #negative_test
Examples: low boundaries
| data1 | data2 | data3 | result |
| 0 | smag | cruft | resultx |
| bar | 0 | fizz | resulty |
That allows you to better understand the purpose of given groups of example values, and even run subsets of scenario outlines based on using tags.
Key thing to remember is that the header row has to be there for each set of examples (I always try to just split them up and leave that out, resulting in an error)
Related
Given a PySpark Dataframe I'd like to know if for a column A exists a value (e.g. 5). The first approach would be to do something like
df.filter("A = 5")
but in this way the function would look for all the records that have that value, taking more time than expected. Instead if for example I know that I find the value in one of the first records I don't need to go ahead and continue iterating.
For example:
+---+
| A |
+---+
| 0 |
| 5 |
| 1 |
| 9 |
| 1 |
| 4 |
| 1 |
...
| 5 |
| 1 |
and suppose that it contains for thousands of records, I'd like to have a quick result as the 2nd record is 5, no need to check for the whole DF (of course there's no guarantee of performance because I might be unlucky and 5 is only the last record, but if I can save resources would be great!).
Any idea on how to achieve that?
An approach might be with
df.filter("A = 5").head()
With some tests I spotted a noticeable difference in execution time and the Spark engine seems to return in this way only the first occurrence that satisfies the condition.
So if it returns null the record doesn't exist (it will have to iterate through all the Datframe obviously), otherwise a Row object will be returned.
Given this example:
I have a list of books that I want to add to the system. Each book is mandatory to have book name and a variable number of authors. When writing a data table for my example I did the following:
| book name | author name a| author name b | author name c|
| book 1 | author 1 | | |
| book 2 | author 2.1 | author 2.2 | |
This worked fine here, but is there a better way to approach the same problem. Another scenario for an example where the input is a variable list of 3 to 5 elements. It doesn't feel right to do the following:
|element a | element b| element c | element d| element e|
Is there a support for a comma separated list inside a cell, something such as (given that this didn't work for me):
|book | authors |
| b1 | a1, a2, a3|
Thanks in advance
This is a really bad way to use Cucumber. If you want to add a book with multiple authors create a step for that
When I add a book with multiple authors
rather than put stuff in a table.
In general using tables in features is not the way to go. The bigger and more complex the table the further you are getting away from how cucumber was designed to be used.
considering I have core data objects stored like this:
|Name | ActionType | Content | Date |
|-----|------------|---------|-----------|
|Abe | Create | "Hello" | 2014-07-01|
|Cat | Create | "Well" | 2014-07-01|
|Abe | Create | "Hi" | 2014-07-02|
|Bob | Edit | "Yo" | 2014-07-03|
|Cat | Delete | "What" | 2014-07-04|
|Abe | Edit | "Haha" | 2014-07-05|
I would like to get the last action of each user, so the results would be
|Abe | Edit | "Haha" | 2014-07-05|
|Cat | Delete | "What" | 2014-07-04|
|Bob | Edit | "Yo" | 2014-07-03|
Does anyone knows how to do that with a NSFetchRequest? So far from what I've gathered, if you want to use "group by", you can only retrieve the values in the group by cause (it will return "Abe, Cat, Bob" without the rest of the data in the core data object). Similar with "returnsDistinctResults", it will not return the whole object.
I have a feeling that core data is not equipped for that, any helps & hints would be appreciated!
Core Data is an object graph, not a database. Core Data itself has no concept of uniqueness, it's up to you to implement that in your application. This is most typically done using the find or create pattern. This pattern helps you prevent duplicate objects from being stored.
That said, you CAN return distinct results from Core Data using the NSDictionaryResultType. This will not prevent duplicates from being stored, but can be used to return distinct results from a fetch. There is an example of this in the programming guide. You can give this request all properties for a given entity by working with the NSEntityDescription of the managed object you are fetching.
For getting the object with the "last" timestamp for each, you actually want to get the object with the maximum value for that key path. That can be done a number of ways - a subquery, key path operators, expressions, etc.
Is there any way to reuse data in SpecFlow feature files?
E.g. I have two scenarios, which both uses the same data table:
Scenario: Some scenario 1
Given I have a data table
| Field Name | Value |
| Name | "Tom" |
| Age | 16 |
When ...
Scenario: Some scenario 2
Given I have a data table
| Field Name | Value |
| Name | "Tom" |
| Age | 16 |
And I have another data table
| Field Name | Value |
| Brand | "Volvo" |
| City | "London" |
When ...
In these simple examples the tables are small and there not a big problem, however in my case, the tables have 20+ rows and will be used in at least 5 tests each.
I'd imagine something like this:
Having data table "Employee"
| Field Name | Value |
| Name | "Tom" |
| Age | 16 |
Scenario: Some scenario 1
Given I have a data table "Employee"
When ...
Scenario: Some scenario 2
Given I have a data table "Employee"
And I have another data table
| Field Name | Value |
| Brand | "Volvo" |
| City | "London" |
When ...
I couldn't find anything like this in SpecFlow documentation. The only suggestion for sharing data was to put it into *.cs files. However, I can't do that because the Feature Files will be used by non-technical people.
The Background is the place for common data like this until the data gets too large and your Background section ends up spanning several pages. It sounds like that might be the case for you.
You mention the tables having 20+ rows each and having several data tables like this. That would be a lot of Background for readers to wade through before the get to the Scenarios. Is there another way you could describe the data? When I had tables of data like this in the past I put the details into a fixtures class in the automation code and then described just the important aspects in the Feature file.
Assuming for the sake of an example that "Tom" is a potential car buyer and you're running some sort of car showroom then his data table might include:
| Field | Value |
| Name | Tom |
| Age | 16 |
| Address | .... |
| Phone Number | .... |
| Fav Colour | Red |
| Country | UK |
Your Scenario 2 might be "Under 18s shouldn't be able to buy a car" (in the UK at least). Given that scenario we don't care about Tom's address phone number, only his age. We could write that scenario as:
Scenario: Under 18s shouldnt be able to buy a car
Given there is a customer "Tom" who is under 16
When he tries to buy a car
Then I should politely refuse
Instead of keeping that table of Tom's details in the Feature file we just reference the significant parts. When the Given step runs the automation can lookup "Tom" from our fixtures. The step references his age so that a) it's clear to the reader of the Feature file who Tom is and b) to make sure the fixture data is still valid.
A reader of that scenario will immediately understand what's important about Tom (he's 16), and they don't have to continuously reference between the Scenario and Background. Other Scenarios can also use Tom and if they are interested in other aspects of his information (e.g. Address) then they can specify the relevant information Given there is a customer "Tom" who lives at 10 Downing Street.
Which approach is best depends how much of this data you've got. If it's a small number of fields across a couple of tables then put it in the Background, but once it gets to be 10+ fields or large numbers of tables (presumably we have many potential customers) then I'd suggest moving it outside the Feature file and just describing the relevant information in each Scenario.
Yes, you use a background, i.e. from https://github.com/cucumber/cucumber/wiki/Background
Background:
Given I have a data table "Employee"
| Field Name | Value |
| Name | "Tom" |
| Age | 16 |
Scenario: Some scenario 1
When ...
Scenario: Some scenario 2
Given I have another data table
| Field Name | Value |
| Brand | "Volvo" |
| City | "London" |
If ever you aren't sure I find http://www.specflow.org/documentation/Using-Gherkin-Language-in-SpecFlow/ a great resource
I have two scenarios in two different feature files but both scenarios tests search functions but on different parts of my page.
The scenarios I have looks something like this:
Scenario Outline: Search items from QuickSearch
Given that the following items
| id | title |
| 1 | Item1 |
| 2 | Item2 |
When I search for <criteria> in this search
Then I should get <result>
And I should not get <excluded>
Examples:
|criteria|result | excluded |
| 1 | 1 | 2 |
| 2 | 2 | 1 |
and:
Scenario Outline: Using a filter
Given that I have the following things:
|id |name |
|1 | thing1 |
|2 | thing2 |
When I use the <filter> filled with <criteria>
Then I should obtain these <results>
And I should not obtain these <exclusions>
Examples:
|filter |criteria |results |exclusions |
|name |thing |1,2 | |
|id |1 |1 |2 |
As you can tell in the second scenario I have changed the word get to obtain in order to write separate steps for the two scenarios.
The only reason I need two different steps is because the id in the 2 different scenarios map to different names (no I cant use the same for both and don't want to start on id 3 in the second)
So I'm thinking about common steps for both of the scenarios (at least when it comes to the then steps) and I want a hash mapping id and name together in order to do validation, but I want the hash to be different depending on which scenario called the step.
So, is there a way in cucumber + capybara that I can tell which scenario called a step?
I do not know of a way to directly access the scenario name from the Cucumber step. However, you can access the name in a before hook and store it in a variable so that it is available to your steps.
Add this before hook to your env.rb:
Before do |scenario|
case scenario
when Cucumber::Ast::OutlineTable::ExampleRow
#scenario_name = scenario.scenario_outline.name
when Cucumber::Ast::Scenario
#scenario_name = scenario.name
else
raise('Unhandled scenario class')
end
end
Edit: if you're using a more recent version of Cucumber, try instead:
Before do |scenario|
case scenario.source.last
when Cucumber::Core::Ast::ExamplesTable::Row
#scenario_name = scenario.scenario_outline.name
when Cucumber::Core::Ast::Scenario
#scenario_name = scenario.name
else
raise('Unhandled scenario class')
end
end
Your steps can then check the scenario name using #scenario_name. Example:
Then /I should get (.*)/ do |result|
if #scenario_name == 'Search items from QuickSearch'
# Do scenario specific stuff
elsif #scenario_name == 'Using a filter'
# Do scenario specific stuff
end
# Do any scenario stuff
end