When I run a spec file (rspec spec/models/user_spec.rb) it prints something like 12 examples, 2 failures, 3 pending.
What's the fastest way to get the 12 examples part of it? (without running the spec)
I have found a way to do this and involves the following snippet being add to spec/spec_helper.rb:
if ENV['COUNT']
class RSpec::Core::Example
def pending; true; end
end
end
This way when I do:
COUNT=true rspec spec/controller/posts_controller_spec.rb
it assumes all the spec examples are pending and returns:
80 examples, 80 pending
Of course there is a problem. It doesn't account for all the really pending spec examples but I think it is a good enough solution.
Similar to vrinek's answer, but for RSpec 3, you can use:
[In path/to/skip_rspec.rb]
class RSpec::Core::ExampleGroup
define_example_method :it, :skip => true
define_example_method :example, :skip => true
define_example_method :specify, :skip => true
end
Command line:
$ rspec --require path/to/skip_rspec.rb
NB. If you have config.filter_run_excluding :skip in your spec_helper.rb, you will have to take it out.
Related
Is there a way to run Rspec macros conditionally ?
For example ability to filter macros using
RSpec.configure do |c|
c.filter_run_excluding :broken => true
end
## This should get skipped
it_should_validate_with_macro :some_param, :broken => true
Note: This is to invoke group of tests dynamically. So pending kinda solution is not I'm looking for.
describe "an example" do
it "is implemented but waiting" do
pending("something else getting finished")
this_should_not_get_executed
end
end
from https://relishapp.com/rspec/rspec-core/v/2-0/docs/pending/pending-examples
You can run specs in the same process, and you can also do things like capture the output.
But a simple example that might work for you is simply to create a ruby script:
require 'rspec/core'
RSpec.configuration.add_setting(:some_setting)
RSpec.configuration.some_setting = false
RSpec::Core::Runner.run(['spec/models/bar.rb'])
RSpec.clear_examples
if RSpec.configuration.some_setting
RSpec::Core::Runner.run(['spec/models/foo.rb'])
end
Then, in your rspec script that will modify the setting:
RSpec.describe 'bar' do
it 'bar' do
RSpec.configuration.some_setting = true
end
end
This will conditionally run the spec in foo.rb.
I am in the process of learning Ruby and I recently set up a small project in which i am writing an API.
currently i have 2 classes, one called API which inherits from Grape
class API < Grape::API
(first quick question, within this class can i have normal methods, like def say_hello ? or is it just web methods?)
and one which i have called APIHelpers
i have set up 2 x spec files
api_spec.rb
APIHelpers_spec.rb
this is the contents of my Rakefile:
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new do |t|
t.rspec_opts = '--format documentation'
t.pattern = ['spec/libs/*.rb']
end
task :default => :spec
When i run the rake (i am using Rubymine 6.0 as my IDE) i am not getting any output from the Rspec except that the 2 tests i have added have passed.
2 examples, 0 failures, 2 passed
Finished in 0.05642 seconds
using the --format documentation i would have expected to see the whole structure from the describe and it statements.
Does anyone have any idea on how i can go about making these tests show correctly using RubyMine?
thanks
in case anyone else comes across this question, here is what i did to get around this issue,
instead of using Rake to run my tests i just used a Rspec configuration, added in an spec_helper
and added in this bit of code
RSpec.configure do |config|
config.color_enabled = true
config.tty = true
config.formatter = :documentation
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
this fixed my issues
I'm trying to speed up a large RSpec project's tests. In addition to using RSpec's --profile option I wanted to get the longest running test files [1] printed out.
In my spec_helper.rb I dump the classes being tested and total time to a file, however as we have spec/model and spec/request directories I'd really like to be able to print the current test's filename and not just the class name (described_class), so that the user can disambiguate between model/foo_spec.rb and request/foo_spec.rb when optimizing.
In a before block in the spec/spec_helper.rb, how can I get the current test file's filename?
My (heavily trimmed) spec_helper looks like this:
config.before :all do
#start_time = Time.now
end
config.after :all do |test|
timings.push({ :name => test.described_class,
:file => 'I do not know how to get this',
:duration_in_seconds => (Time.now - #start_time) })
end
config.after :suite do
timing_logfile_name = 'log/rspec_file_times.log'
timing_logfile = "#{File.dirname(__FILE__)}/../#{timing_logfile_name}"
file = File.open(timing_logfile, 'w')
timings.sort_by{ |timing| timing[:duration_in_seconds].to_f }.reverse!.each do |timing|
file.write( sprintf("%-25.25s % 9.3f seconds\n",
timing[:name], timing[:duration_in_seconds]) )
end
file.close
tell_if_verbose("Overall test times are logged in '#{timing_logfile_name}'")
end
This doesn't seem to be available in the curretn RSpec meta-data, but I'm hoping someone more familiar with the internals can think of a way to expose it. Thanks,
Dave
[1] Often a file with, say, 100 examples in it yields more speed up than a single example from --profile - when that large file's before :each / before :all blocks are targetted, obviously even a ms saved is multiplied up by the number of tests in the file. Using this technique in addition to --profile helped me a lot.
As long as you're just using this for profiling your tests to identify which files need to be improved, you should be able to toss this into your spec_helper.rb file (and remove it afterwards). I fully understand that this is not pretty/clean/elegant/acceptible in production environments and I disavow that I ever wrote it :)
config.before(:each) do |example|
path = example.metadata[:example_group][:file_path]
curr_path = config.instance_variable_get(:#curr_file_path)
if (curr_path.nil? || path != curr_path)
config.instance_variable_set(:#curr_file_path, path)
puts path
end
end
For easier organization, I'd like to namespace a couple folders under my /spec directory. So rather than /spec/requests, I'd like to use /spec/another_directory/requests.
However, when I run my specs under these new namespaced directories, I get
NoMethodError:
undefined method `whatever_path'
So, it looks as those my routes are no longer being properly loaded. If I move the file back up to spec/requests (without the namespace), all is well and the test is green.
Not really sure what the issue is. I'm requiriing 'spec_helper' in my files. I've also seen:
require File.dirname(__FILE__) + '/../../spec_helper'
and its variations, but I'm not really sure how that helps because it seems to load the spec_helper, just not the routes. And to further make things fun, I'm reloading the routes before each run in the Spork.pre_fork block
Spork.each_run do
load "#{Rails.root}/config/routes.rb"
end
but I still get the error whether Spork is running or not.
What am I doing wrong?
(rspec-rails 2.8.1)
I think, this is due request example before hook is not fired. If you look further, you can understand how rspec-rails decide which example type it runs.
I suggest you to use spec/requests/another_directory schema or you can try to reconfigure Rspec somewhat like:
RSpec::configure do |config|
config.include RSpec::Rails::RequestExampleGroup, :type => :request,
:example_group => {:file_path => 'path/to/your/requests')}
end
I ended up doing:
config.include RSpec::Rails::RequestExampleGroup, :type => :request,
:example_group => {
:file_path => config.escaped_path(%w[spec (my|folder|names) requests])}
But, then it's not getting the Capybara methods, so I include then again after the above config block
config.include Capybara::DSL, :type => :request
config.include Capybara::RSpecMatchers, :type => :request
I wanted to make the path more elastic so I don't have to have include each 'parent' folder. I tried using ** instead of having to include (each|folder), but it wasn't loading. I then tried setting the path directly using:
:file_path => "spec/../requests"
but then I lose the ability to run a single file.
Either way, the above code works, just have to pipe each of your folder's names.
This has been causing some frustration recently...
It seems that using Factories in my cucumber tests, in some situations causes AssociationTypeMismatch errors such as:
MyModel(#65776650) expected, got MyModel(#28190030) (ActiveRecord::AssociationTypeMismatch)
These seem to happen when there is an association reference - as if the Factory created object is different to the real one. See this question for more details: Cucumber duplicate class problem: AssociationTypeMismatch
I have been gradually changing Factory calls to real Model.create or mock_model calls. It would be nice to keep using Factory girl... I wonder if there is something I may have done wrong?
Thank you
I had this happening with me on Rails 3.1.0 rc5, and got it working.
To expand on Jonas' answer.
You should change your Gemfile to be like this:
gem 'factory_girl', '~> 2.0.0', :require => false
gem 'factory_girl_rails', '~> 1.1.0', :require => false
And then if you are using Spork, make your spec/spec_helper.rb file look like this:
Spork.each_run do
require 'factory_girl'
require 'factory_girl_rails'
end
It seems to happen if ActiveSupport unloads and reloads a constant that you have a reference to.
I've experienced the same with Rspec/Capybara, and what helped was a mixture of different things:
Make sure you have cached_classes set to false in your test environment (config/environments/test.rb)
In your gemspec, try replacing require 'factory_girl_rails' with 'factory_girl'
I'm using Spork (a test server), which seems to make this stuff increasingly difficult.
If you are using a test server, evaluate whether you should put ', :require => false' after factory_girl in your gemspec.
The topic is also covered in this google groups thread
Please let us know if any of this helped.
If you're using Spork, make sure to reload your factories after reloading your models.
E.g.
Spork.each_run
if Spork.using_spork?
print "Reloading models ... "
ActiveSupport::Dependencies.clear
puts "done"
print "Reloading factories ... "
FactoryGirl.reload
puts "done"
end
end
This happens because cache_classes is false, as is required by Spork. Capybara reloads Rails classes for every request (or, to be correct, Rails' reloader middleware does, which is not called for normal tests), and this freaks out the factories (exactly why, I'm not sure). You can either reload them, or simply run your Capybara specs outside of Spork.
So you need two things: to only run Capybara outside of Spork, and to set cache_classes to false only for Spork.
To only run Capybara outside of Spork, I have a Guardfile that runs specs in spec/requests outside of Spork and other specs inside of Spork here:
https://gist.github.com/1731900
Then, in config/environments/test.rb:
config.cache_classes = !ENV['DRB']
Your Capybara specs will be a bit slower, as they need to boot rails, but everything will Just Work.
I had some success with reloading the Factory definitions try something like this:
class Factory
def self.reload_definitions #:nodoc:
self.factories.clear
definition_file_paths.each do |path|
load("#{path}.rb") if File.exists?("#{path}.rb")
if File.directory? path
Dir[File.join(path, '*.rb')].each do |file|
load file
end
end
end
end
end
I ran into this issue when I passed the "class" option to my factory that was inherited by other factories:
factory :draft_resource, :class => Resource do
factory :resource, :parent => :draft_resource do
The only solution I could find was to simply not do this.
I ran into this same issue and spent probably ten hours trying every solution on this thread and everywhere else on the web. I started ripping out huge chunks of code trying to get it as close to another app of mine in which I couldn't reproduce the problem. Finally, I came across some helper functions in my spec_helper file:
def sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token if defined?(cookies)
end
A sign_in helper intended to work both in controller and request specs. And it does, sort of--just not with spork. When I removed the capybara helpers the issue was resolved:
def sign_in(user)
cookies[:remember_token] = user.remember_token
end