I'd like to know how much took to run the 10 most time consuming tests.. like I can do with rspec, any suggestion?
Short answer:
gem install minitest # Install MiniTest
gem install minitest_tu_shim # Install Test::Unit shim
use_minitest yes # Use MiniTest Test::Unit shim instead of stdlib Test::Unit
ruby your_test.rb -v # Run your test in verbose mode
Ruby 1.9 use MiniTest as its default testing framework instead of Test::Unit. MiniTest is smaller, faster, has more useful features, and is largely backward compatible with Test::Unit. One of those newer features is measuring the time each test takes with the -v flag. When you run the e sure you place this flag after the script
If, as in rails, you use Rake::TestTask to run your tests, you'll can either specify it at runtime by running
rake test TESTOPTS='-v'
or specify it in the task by adding -v to the options attribute, like so
Rake::TestTask.new do |t|
t.options = '-v'
end
Finally, if you're using rails and MiniTest just isn't good enough for you, you might appreciate the test_benchmark plugin. Usage is easy. Add the following line to your config/environments/test.rb
config.gem "timocratic-test_benchmark",
:lib => 'test_benchmark',
:source => 'http://gems.github.com'
Install it with
RAILS_ENV='test' rake gems:install
From then on, you'll get a nice sorted list when you run your tests
rake test:units
[...]
Test Benchmark Times: Suite Totals:
7.124 test_destroy(FeedTest)
7.219 test_create(FeedTest)
7.646 test_subscribe_to_auto_discovery(FeedTest)
9.339 test_auto_discover_updates_url(FeedTest)
9.543 test_find_or_create_by_auto_discover_url(FeedTest)
15.780 test_import_from_opml(FeedTest)
I'm sorry to say that MiniTest and the test_benchmark plugin are incompatible with each other, but I strongly encourage you to try MiniTest, since it'll make your tests faster, and will continue to be supported in Ruby 1.9.
Maybe run your unit tests under the ruby profiler by executing the code with ruby -rprofile instead of just ruby?
Minitest::Profile is a new gem that lists the top offenders after a standard test run.
https://github.com/nmeans/minitest-profile
Related
I have some classes with unit tests and I have a rake task to run these unit tests. However, I'm running into a problem where when the tests are run via rake an old version of minitest is being used. How can I get rake to use the newer version?
If I use the Minitest::Test subclass it runs fine when the tests are directly run through the ruby
command-line. However, if I use the following rake task:
require 'rake/testtask'
Rake::TestTask.new do |t|
t.pattern = 'tests/**/*_test.rb'
end
When I check the minitest version using puts MiniTest::Unit::VERSION it prints 5.5.0 when run with ruby, but prints 4.3.2 when run with rake. (When using gem list minitest -d version 4.3.2 is listed as the default.)
The reason I want to use the newer version of minitest is that when I directly run the unit tests using Ruby 2.0 I get the following warning:
MiniTest::Unit::TestCase is now Minitest::Test.
However, if I change MiniTest::Unit::TestCase to Minitest::Test I get the following error when I run the tests using rake.
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/ext/module.rb:36:in `const_missing': uninitialized constant MiniTest::Test (NameError)
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/minitest/unit.rb:28:in `const_missing'
I want to avoid requiring any changes to the system configuration, because I want these tests to run on the default OS X ruby installation.
Using gem 'minitest', '=5.5.0' does not change the version of minitest that gets used.
Possibility #1: Run Rake with bundle exec to force it to use the version of Minitest managed by Bundler:
bundle exec rake test
Possibility #2: Create a binstub for Rake for your project that will load your bundle automatically:
bundle binstub rake
After that, you should be able to run Rake without bundle exec to get the same result.
Caveat: This has worked for the Ruby environment managers I've used recently, but you might need to Google around for a solution if it doesn't work for you.
Ruby is having a hard time loading minitest from the gem instead of the standard library, so we need to give it a little help. Add the following to your helper or rake task:
gem "minitest"
That will tell ruby to use the gem version. Just be sure to add that before minitest is required.
Is there a way to write an Rspec test to prove that some code fails if we are using a specific version of a gem and passes if we use another version of the same gem?
What I do currently is have one version in my Gemfile and then run rspec spec and see a test pass. Then I modify my Gemfile with the different gem version and bundle update and then run rspec spec again and see the same test fail.
I would like to have two tests, one that loads one version of the gem and tests for normal execution and succeeds and another test that loads a different version of the gem and tests for an exception and succeeds on the raised exception and both tests are run on the same rspec spec run. Is this even possible. If not, any suggestions on anything that does not involve me having to modify my Gemfile manually?
Also, in case it helps
I currently use bundler to install gems.
ruby 1.9.3p545
rspec 2.14.1
Also, I am not using Rails
I think you can specify the gem and version you want to use in the code:
it "does something" do
gem "gemname", "4.0"
require "gemname"
expect(subject).to do_something
end
But I don't know if what you're trying to do is a good idea because you should be testing with the same gems you would be using in production.
You could define a different environment to include the alternative version of your gem and use this while testing. For example, in your Gemfile
group :custom_test do
gem 'gemname', 'x.y.z'
end
And then run your tests as in
RAILS_ENV=custom_test rspec
I strongly suggest however that you look into solutions that let you test against different environments, gemfiles, rails and ruby versions (e.g. Jenkins or Travis etc.)
I am in the middle of writing a Ruby Gem, but was wondering if there is an easier way to "test" your gem without having to build it, install it and require it to test it out in an IRB console?
Git clone it in an arbitrary folder, add its lib path to $: in the rakefile if needed (you actually don't in this case, as RakeTest should add it for you), and run rake test directly.
From irb, proceed similarly: add the lib path to $: to bypass the packaged gem. But note that you'll need to reload it when you change it, so it's less convenient than rake.
For completeness, in case you or a future visitor is unfamiliar with Rake:
Running Ruby unit tests with Rake
I have forked a ruby gem and made some updates. I need to run the gem tests and add my new tests and ensure all tests are succeeding.
The forked ruby gem is using rspec tests. How can I run these test?
Usually rake is sufficient to run all the tests, regardless of whether they're RSpec, Cucumber, etc. If you want to invoke RSpec directly try running rspec spec instead, or if the gem is using an unconventionally named test directory, just use rspec <directory_name>.
Note: Most new gems these days use Bundler to manage dependencies, so if you don't have the appropriate dependencies and there's a Gemfile in the root, then run "bundle install" first to get them. Then run with bundle exec ... (e.g., bundle exec rspec spec).
I am building up an integration test suite and there is one bit of logic that I need to have a clean database for. How can I run the db:test:purge task inside of one of my tests?
I am using: ruby 1.9.2, rails 3.0.9, rspec 2.6
You can invoke Rake tasks as following:
require 'rake'
Rake::Task[name].invoke
In this case this would result in the following code:
require 'rake'
Rake::Task['db:test:purge'].invoke
Approved answer didn't work for me, when I needed to execute my own rake task
Here's my solution
Put in the top of the spec file
require 'rake'
Place these lines where you need to execute your custom rake task, e.g. rake update_data from the file example.rake
load File.expand_path("../../../lib/tasks/example.rake", __FILE__)
# make sure you set correct relative path
Rake::Task.define_task(:environment)
Rake::Task["update_data"].invoke
My environment:
rails (4.0.0)
ruby (2.0.0p195)
rspec-core (2.14.7)
rspec-expectations (2.14.3)
rspec-mocks (2.14.4)
rspec (2.14.1)
rspec-rails (2.14.0)
If we require to use multiple rake tasks we can add
require "rake"
Rails.application.load_tasks
Then simply call any task.
Rake::Task['sync:process_companies'].invoke
Though I cant confirm if its slower because it loads all the tasks
for me (rails-6)
Rails.application.load_tasks
Rake::Task['app:sync'].invoke
=> require not necnessary in my case
We need to require the task also
require 'rake'
Rake.application.rake_require 'tasks/new_adapter'
After this, just call the task
Rake::Task['new:adapter'].invoke
Many of the above answers worked for me for running a single spec. However, I had to take an extra step when running multiple specs for a single rake task.
After each spec, I had to run Rake::Task.clear, as (for some reason) the task would not be run again if it was registered as being already_invoked (i.e. if Rake::Task['my_task'].already_invoked returned true.
I added the following line to my rake task spec:
after { Rake::Task.clear }
and everything worked as expected when running multiple tests for the same rake task.