How do you mark a Cucumber Scenario as Pending - ruby

How do I mark a cucumber scenario as pending so it doesn't get counted as a passed?
Scenario: Guest should not see edit link
# pending implementation
Shouldn't I be able to mark is as pending?

The problem with the #wip tag, I've found, is that it doesn't make your test suite yellow. It completely ignores the wip features, and you tend to forget they exist. This has bitten my team in the rear when scenarios are tagged as #wip and then forgotten. I wish there was a better solution. The best I have is adding this custom step:
Given /^PENDING/ do
pending
end
Rather than mark a real feature as pending, I can put this into the lineup with a message, like so:
Given PENDING: we need client input
Then it shows up like this:
(::) pending steps (::)
features/example.feature:15:in `Given PENDING: we need client input'
Pending halts the chain of tests, but it does NOT prevent cucumber from nagging about any undefined steps that follow in that same scenario. Also, ideally failing and pending features would tell you the name of the scenario that failed, but they don't.

Okay figured this one out.
The Scenarios steps are marked as pending if it's not found in any of the steps files.
Scenario: New product form should have some special field
Given joe is logged in as an user
When on the new exercise page
Then the select field should have some special field
It's even nice enough to stub out the pending step.
When /^on the new exercise page$/ do
pending # express the regexp above with the code you wish you had
end

Another possibility is the #wip tag (work in progress). Scenarios tagged #wip will not be run by default, but just when you explicitly request them.
#wip
Scenario: New product form should have some special field
Given I still work on this feature
This way you can exclude some scenarios from the automated build, so that it doesn't break while you are working on the feature.

In addition to averell's answer, you can exclude scenario tags when running cucumber.
If #todo and #wip are tags you want to use for scenarios that are work in process or just mark pending scenarios, run your features like:
cucumber --tags ~#todo --tags ~#wip
If you're using Guard do something like this:
guard 'cucumber', :notification => true, :all_on_start => true,
:cmd => "bundle exec cucumber",
:cli => "--tags ~#todo --tags ~#wip" do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) do |m|
Dir[File.join("**/#{m[1]}.feature")][0] || 'features'
end
end

Related

Don't run a cucumber feature if a element on the page is not available but exit without failing

I want to check a page for an element before I start running the feature file for it (It's an element that periodically appears with an event so I only want to run the feature if its present).
The approach I wanted to use was a tagged before hook to see if the element was present and if it wasn't just don't run the feature but exit without 'failing' the step just exit with a message. I tried variants on the below but
1. If I don't have a rescue clause it obviously fails the scenario when the element isn't present
2. If I do have the rescue clause it handles it and passes moving onto the features which will then fail as the event isn't available.
Is there a way to halt running the feature file if the rescue clause is invoked without the 'fail'?
Before('#event') do
begin
find('.event').visible?
rescue Capybara::ElementNotFound
puts 'THE EVENT IS NOT ON'
end
end
You shouldn't be using find if you want to make a decision based on existence. Instead you should be using the predicate methods provided by Capybara (has_selector?, has_css?, has_xpath?, etc) so you don't have to rescue exceptions.
The other thing to know is the Cucumber skip_this_sceanrio method, which means you should end up with something like
Before('#event') do
# visit '/some_page' # May not be needed if you have another `Before` already visiting the needed page
skip_this_scenario('Skipping due to missing event') unless page.has_css?('.event')
end

How mocking works mocha gem?

I am new to mocha gem before that I am using minitest to test my product. Then I came across a situation where my application is publishing jobs to facebook. It selects some jobs and then publish them on facebook.
So somebody told me to use mocking and i found mocha gem.
I see a sample test.
def test_mocking_an_instance_method_on_a_real_object
job = Job.new
job.expects(:save).returns(true)
assert job.save
end
But I did not get the idea. In my jobs controller, I have validations
and the empty job cannot be saved successfully. But here with mocking the
above test assert that job can be saved without mandatory fields.So what exactly we test in above test case?
It is a good practice generally for several reasons:
From an isolation point of view: The responsibility of the controller is to handle the incoming request and trigger actions accordingly. In our given case the actions are: create a new Job, and issue a new post to Facebook if everything fits. (Please notice our controller doesn't need to know about how to post to FB)
So imagine the following controller action:
def create
job = Job.new job_params
if job.save
FacebookService.post_job job
...
else
...
end
end
I would test it like:
class JobsControllerTest < ActionController::TestCase
test "should create a job and issue new FB post" do
job_params = { title: "Job title" }
# We expect the post_job method will be called on the FacebookService class or module, and we replace the original implementation with an 'empty/mock' method that does nothing
FacebookService.expects :post_job
post :create, job_params
assert_equal(Job.count, 1) # or similar
assert_response :created
end
end
The other advantage is: FacebookService.post_job might take significant time, and might require internet access etc, we don't want our tests to pending on those, especially if we have CI.
And finally I would test the real FB posting in the FacebookService test, and maybe stub out some other method, to prevent posting on FB every single time when the test runs (it needs time, internet, FB account...).

Get Status from Scenario with Cucumber 2.0.0

It looks like its no longer possible use
scenario.status
in Cucumber 2.0.0 to determine the status of a scenario (passed, failed, undefined, skipped). It looks like it is possible to see if a scenario either passes or fails, but I'm also looking to see when steps are undefined or skipped.
Previously, in my code I would write the results to a DB in the After hook of the scenario, like so:
After do |scenario|
#controller.post_results(scenario)
end
Inside of post results, I would call scenario.status to get the status.
Is this no longer possible to do with Cucumber 2.0.0? If it is, what is the new method?
You need to use Hooks.rb to get the status of scenario.
You can use
if scenario.failed?
todo...
end
or
scenario.status
inside the hooks.rb.
Find more details here: https://github.com/cucumber/cucumber/wiki/Hooks

can I use multiple exclusion filters in rspec?

In a _spec.rb file I'm setting up an exclusion filter something like:
RSpec.configure do |config|
# we need determine this once at the very front
# and the result be available in the instance
server_success = server1_available?
config.exclusion_filter = {
:svr1 => lambda {|what|
case what
when :available
!server_success
end
}
}
end
and then later in the file I do
describe :get_items_by_client, :svr1 => :available do
to prevent test execution if the server isn't available.
This all works fine if I run the spec file alone. However, I have similar code in another file controlling tests that access a different server, and when I run them all only I see that each of the server checks is done (I have a puts in the "serverX_available?" code), but only one set of tests is being excluded (even though neither server is available).
I'm starting to think that you can have only a single exclusion filter, but I can find any docs anywhere that speak to that. Is this doable on a per-file basis? I could have a single complex filter all in a support file, but then how would I get it incorporated when I'm doing just a run of a single spec-file?
Ideally, I'd like to find a form that works per-file but let's me do the availability check once since it is a somewhat expensive check and I have several examples in the test that are controlled by that.
config.filter_run_excluding :cost => true
config.filter_run_excluding :slow => true
Try this out and this works.

Reuse Cucumber steps

I want to reuse some Cucumber steps but can't seem to find the right way.
I want to write a step like:
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
But then have another step like:
Given /^I login successfully$
# call "Given I login with valid credentials"
end
So in testing user authentication I can use the former, but most other places, I can use the latter, and not actually have to repro code.
Is there a way to call that other step, or do I just put the logic in a helper method, and call said method from each task (basically a method extraction refactoring, which, after reading my question makes me believe that's actually the best way anyway)?
Note that the method for calling steps within steps has changed in recent versions of cucumber, which you'll see if you get an error like "WARNING: Using 'Given/When/Then' in step definitions is deprecated, use 'step' to call other steps instead:/path/to/step_definitions/foo_steps.rb:631:in `block in '
". See the cucumber wiki for details.
The gist of the change is that you should now use the step or steps methods.
When /^I make all my stuff shiny$/
step "I polish my first thing"
end
When /^I make all my stuff shiny$/
steps %Q{
When I polish my first thing
When I shine my second thing
}
end
UPDATE: The method described below has been deprecated. The recommended way to call a step from within another step now looks like this:
Given /^I login successfully$/
step "I login with valid credentials"
end
Old, deprecated method (for reference):
You can call steps from other steps like this:
Given /^I login successfully$/
Given "I login with valid credentials"
Then "I should be logged in"
end
If all of the scenarios within a feature require this (or other steps), you can also add a Background to each features, with the common steps, like so:
Background:
Given I log in with valid credentials
Scenario: Change my password
Given I am on the account page
Calling steps from step definitions is a bad practice and has some disadvantages:
If scenario will fail and there are nested step invocations, you will get only the last invoked step definition in the stack trace. It may be hard to find from which place that last stepdef was called
Call to stepdef is sometimes harder to find and read than ruby method
Ruby methods give you more power than calling steps from step defs
Aslak Hellesøy recommends to extract popular actions to World instead of reusing steps. It isolates those actions in one place, makes this code easier to find. You can extract code to usual Ruby classes or modules as well.
#/support/world_extensions.rb
module KnowsUser
def login
visit('/login')
fill_in('User name', with: user.name)
fill_in('Password', with: user.password)
click_button('Log in')
end
def user
#user ||= User.create!(:name => 'Aslak', :password => 'xyz')
end
end
World(KnowsUser)
#/step_definitions/authentication_steps.rb
When /^I login$/ do
login
end
Given /^a logged in user$/ do
login
end
Here is a useful discussion on the subject in Cucumber mailing list - link
Best wrap your steps in %{} rather than quotes. Then, you don't need to escape double quotes which you'll need to use frequently.:
Given /^I login successfully$
step %{I login with valid credentials}
end
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
Reuse keywords in feature file which will provide code reusability.
It is highly NOT recommended to call step defs within step defs.
I would write my feature file this way,
Scenario Outline: To check login functionality
Given I login with "<username>" and "<password>"
Then I "<may or may not>" login successfully
Examples:
|username|password|may or may not|
|paul |123$ |may |
|dave |1111 |may not |
In my step definition, (This is Java)
#Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
public void I_login_with_and(String username, String password){
//login with username and password
}
#Then(I \"([^\"]*)\" login successfully$)
public void I_login_successully_if(String validity){
if(validity.equals("may")){
//assert for valid login
}
else
if(validity.equals("may not")){
//assert for invalid login
}
}
In this way, there is a lot of code reusability.
Your same Given and Then handles both valid and invalid scenarios.
At the same time, your feature file makes sense to the readers.

Resources