I'm trying to get a little more familiarity with Rails / ActiveRecord. In trying to do so I am attempting to use Cucumber to help with some "discovery" tests.
I have the following
Feature: Describing a task
In order to work with tasks
As a user
I want to be able to know what makes up a task and to improve my understanding of ActiveRecord
Scenario: A task has certain core fields
Given the following tasks exist
| id | name |
| 1 | some task |
And the following estimates exist
| task_id | hours | explanation |
| 1 | 8 | initial estimate |
| 1 | 6 | better undertsanding of task |
| 1 | 16 | no control over inputs to create task |
| 2 | 22 | for other task |
Then a task: "task" should exist with name: "some task" #this works
Then the estimate "estimate" should exist with explanation: "initial estimate" #this works
Then the estimate "estimate" should be one of task: "task"'s estimates #this works
Then the task "task" should have 3 estimates #this one fails
EDIT
I have no custom steps - trying to use use what comes out of the box with cucumber and pickle (just to limit my confusion).
The models are
class Estimate < ActiveRecord::Base
belongs_to :Task, :class_name => "Task", :foreign_key => "Task_id"
end
and
class Task < ActiveRecord::Base
has_many :estimates
end
Can anyone point me in the right direction (or if I need to post more code)?
Thanks,
Joe
Your estimate class can look like this:
class Estimate ...
belongs_to :task
end
It will infer the table name and the fk and assuming you've been following the rails database idioms it should all just work.
As for your cuke steps, I've never used pickle, so I'm not sure what's going on with that, but if the step that's failing is:
Then the task "task" should have 3 estimates #this one fails
It might be to related to the change I've outlined above (maybe it's doing something weird with the table name??).
Related
I would like to run below scenario outline of gradle-cucumber project from cmd prompt.
Scenario Outline: Validate details for Testcase Id "<Id>"
Then User validates testcase detail of project for "<Id>"
Examples:
| Id |
| GB |
| QW |
Tried this cmd :-
gradlew.bat clean test -Dcucumber.options="--name 'Validate details for Testcase Id "<Id>"'"
Error:- The system cannot find the file specified.
We are using SpecFlow for functional tests that suppose to replace manual testing when a human reads generated email and validates that all sections match specification. The problem is that Scenario Outlines become to grow to have too many parameters
Scenario Outline: generate and send confirmation email
Given I have stored itinerary in '<EmbeddedItinerary>'
When Generate confirmation email
Then section1 should have parameters '<Param1_1>', '<Param1_2>', '<Param1_3>',...
Then section2 should have parameters '<Param2_1>', '<Param2_2>', '<Param2_3>',..
Then section3 should have parameters '<Param3_1>', '<Param3_2>', '<Param3_3>',...
....
Examples:
| EmbeddedItinerary | Param1_1| Param1_2| Param1_3| Param2_1| Param2_2| Param2_3| Param3_1| Param3_2| Param3_3|...
| Itinerary_1 | Value1_1 | Value1_2 | Value1_3 | Value2_1 | Value2_2 | Value2_3 |Value3_1 | Value3_2 | Value3_3 |...
| Itinerary_1 | Value1_1 | Value1_2 | Value1_3 | Value2_1 | Value2_2 | Value2_3 |Value3_1 | Value3_2 | Value3_3 |...
But the number of columns in Examples would become unmanageable. I wish to have multi-line examples ( but with different reason then in Multiple Multi-Line Examples in SpecFlow Feature File).
The option that I see is to store all ExpectedResults in embedded xml or json resource file, and have SpecFlow features quite small e.g.
Scenario Outline: generate and send confirmation email with correct email address for flight section
Given I have stored embedded resource '<EmbeddedItinerary>'
When Generate confirmation email
Then sections should be as specified in '<ExpectedResultsFile>'
Examples:
| EmbeddedItinerary | ExpectedResultsFile
| Itinerary_1 | ExpectedResults1 |
| Itinerary_2 | ExpectedResults2 |
...
Is it a good idea?
Can anyone suggest better way ( more SpecFlow style)?
My concern is that moving expected data to separate files I am loosing visibility, that is one of advantages of SpecFlow features.
Update: while writing this question I found commercial product ($AUD 255 per user) Specflow+Excel http://www.specflow.org/plus/excel/getting-started/ , which may satisfy my requirement to maintain many columns.
Is it a mature/reliable product? Should I use it instead of own parsing expected results files in proprietary format?
If I have a lot of parameters in a Scenario Outline, I try to work as much as possible with default parameters or split the Scenario Outline in multiple ones.
I think in your case, it should be possible to split the one 'generate and send confirmation email' Scenario Outline in multiple ones that you have a scenario outline for every section.
This would reduce the amount of needed parameters per scenario and you get faster feedback if an error occurs. You immediately see in which section you have an error.
e.g.:
Scenario Outline: generate and send confirmation email - section 1
Given I have stored itinerary in '<EmbeddedItinerary>'
When Generate confirmation email
Then section1 should have parameters '<Param1_1>', '<Param1_2>', '<Param1_3>',...
Examples:
| EmbeddedItinerary | Param1_1 | Param1_2 | Param1_3 |
| Itinerary_1 | Value1_1 | Value1_2 | Value1_3 |
Scenario Outline: generate and send confirmation email - section 2
Given I have stored itinerary in '<EmbeddedItinerary>'
When Generate confirmation email
Then section2 should have parameters '<Param2_1>', '<Param2_2>', '<Param2_3>',..
Examples:
| EmbeddedItinerary | Param2_1 | Param2_2 | Param2_3 |
| Itinerary_1 | Value2_1 | Value2_2 | Value2_3 |
Scenario Outline: generate and send confirmation email - section 3
Given I have stored itinerary in '<EmbeddedItinerary>'
When Generate confirmation email
Then section3 should have parameters '<Param3_1>', '<Param3_2>', '<Param3_3>',...
Examples:
| EmbeddedItirerary | Param3_1 | Param3_2 | Param3_3 |
| Itinerary_1 | Value3_1 | Value3_2 | Value3_3 |
About SpecFlow+Excel: That is also an option. Maintaining examples in Excel is most of the time easier than in the feature- file. It will at least solve your problem in short term, but you have to be also careful to write scenarios that are still understandable and readable.
You can get a trial license for it from here: http://www.specflow.org/request-your-specflow-trial-license/
Full Disclosure: I am one of the developers of SpecFlow+ (Runner & Excel).
Is it possible to use different tables based on previous steps?
So suppose I have something like
When I choose from a <list> of things
And I run a <test> from that thing chosen with special <parameter>
Examples:
|list|
| a |
| b |
| a |
| test | parameter |
| mytest1 | myparameter1 |
| mytest2 | myparameter2 |
| b |
| test | parameter|
| mytest1 | myparameter3 |
| mytest2 | myparameter4 |
Is this possible and what would be the correct structure?
No its not, and it is a very bad idea. Generally when you want to do programming in your scenarios, you should do it by
Giving it a name
Pushing the programming down into the step definitions
In this particular case you seem to want to be doing some sort of exhaustive testing, where you try a single operation under a number of different conditions. Cucumber is not appropriate for this sort of testing. Instead find a way to do these sort of tests at a lower level of abstraction e.g. a unit test.
The main reason for not doing exhaustive testing in Cucumber is the runtime cost. As a rough rule of thumb each integration test (Cucumber) has a run time cost of hundreds of unit tests (maybe thousands of good unit tests).
I seem to be having some issues with Rake and my Cucumber features file.
Here is the command in Jenkins. It specifys the Rake file that I have put directly in the ./features directory so the testjson.feature is right there.
/usr/local/bin/rake --rakefile /home/robm/code/BDD/practise-tests/testtq/features/Rakefile
Rakefile looks like this:
require 'cucumber/rake/task'
Cucumber::Rake::Task.new :features do |t|
t.cucumber_opts = '*.feature'
end
It's pretty straightforward but in the console output from Jenkins I get:
Feature: Validate DUT JSON
JSON should be evaluated for all routes in API
All API routes should return valid JSON
If JSON is invalid for one or more route in API it has DUT failed
Scenario Outline: Validate JSON # testJson.feature:6
Given there is a DUT with "<input>" and "<un>" and "<pw>" # testJson.feature:7
When the JsonTest code is run # testJson.feature:8
Then the output should be "<output>" # testJson.feature:9
Examples:
| input | un | pw | output |
| 172.168.101.139 | username | password | CHECK |
| 172.168.101.214 | username | password | CHECK |
2 scenarios (2 undefined)
6 steps (6 undefined)
0m0.007s
which tells me it's not finding the feature file, right?
When I go to the directory above the feature file and run Cucumber the test works!
So, obviously I have an error with my Rake file. Any ideas?
I put this in as my Rake working directory
/home/robm/code/BDD/practise-tests/testtq
then specified the feature file
"./features/testJson.feature"
that got it to work not sure why the other didn't work.
I try several ways like stubbing STDOUT, using highline-test and aruba gems, but it still stops my cucumber tests and asking for user input. Are there best practices for testing such applications with Cucumber?
Aruba gives me solution.
First of all, my mistake was creating new instance of app's root class without checking if __FILE__ == $0.
And finally it looks like this:
dashboard.feature:
Feature: Manage app with dashboard
As an app user
In order to control application
I want to have a dashboard
Scenario: View dashboard
When I run `../../lib/reporter.rb` interactively
Then I should see following choices
| 1 | Choice 1 |
| 2 | Choice 2 |
| 3 | Choice 3 |
steps.rb:
Then(/^I should see following choices$/) do |table|
menu = ''
table.rows_hash.each do |key, value|
menu << "#{key}. #{value}\n"
end
Timeout::timeout(exit_timeout) do
loop do
break if assert_partial_output_interactive(menu)
sleep 0.1
end
end
end