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
Related
I have a rake task test that I setup following the only examples I could find online.
It looks like this:
require 'test_helper'
require 'minitest/mock'
require 'rake'
class TestScrapeWelcome < ActiveSupport::TestCase
def setup
Rake.application.init
Rake.application.load_rakefile
#task = Rake::Task['scrape:scrape']
#task.reenable
end
def teardown
Rake::Task.clear
end
test "scraping text and sending to elasticsearch" do
mocked_client = Minitest::Mock.new
get_fixtures.each_with_index do |arg,i|
mocked_client.expect :index, :return_value, [index: "test", type: 'welcome', id: i, body: arg]
end
Elasticsearch::Model.stub :client, mocked_client do
#task.invoke
end
assert mocked_client.verify
end
private
def get_fixtures
(0..11).map { |i|
File.read("test/fixtures/scrape/index_#{i}.json")
}
end
end
But after the task runs once it starts running again without me doing anything (puts prints before and after #task.invoke show that the task is only run the once).
Turns out that rake is already required and initialized when the test runs so all of the following lines need to be removed or the task gets defined twice and runs twice even if you only invoke it once.
require 'minitest/mock'
require 'rake'
...
Rake.application.init
Rake.application.load_rakefile
Updated answer for rails 5.1 (using minitest):
I found I needed the following to load tasks once and only once:
MyAppName::Application.load_tasks if Rake::Task.tasks.empty?
Alternatively add MyAppName::Application.load_tasks to your test_helper, if you don't mind tasks being loaded even when running individual tests that don't need them.
(Replace MyAppName with your application name)
I've tried #iheggie answer but it worked in a way that indeed tests were run once but any other task was breaking with Don't know how to build task '<task_name_like_db_migrate>'.
I'm on Rails 3.2 still. It turned out that there were couple tasks loaded beforehand so the Rake::Task.tasks.empty? was never true and all other useful tasks were not loaded. I've fiddled with it and this version of it works for me right now:
Rake::Task.clear if Rails.env.test?
MyAppName::Application.load_tasks
Hope this helps anyone.
A solution that works for testing the tasks of a Gem that has been made a Railtie so it can add tasks to the Rails app:
Don't define the Railtie in test mode when you're also defining a Rails::Application class in spec_helper.rb (which allows your tests to call Rails.application.load_tasks). Otherwise the Rake file will be loaded once as a Railtie and once as an Engine:
class Railtie < Rails::Railtie
rake_tasks do
load 'tasks/mygem.rake'
end
end unless Rails.env.test? # Without this condition tasks under test are run twice
Another solution would be to put a condition in the Rake file to skip the task definitions if the file has already been loaded.
I have a TDD solution written in Ruby 1.9.3 (latest stable Windows RubyInstaller).
The application is in the app directory and in the sibling test directory I have 4 files containing tests.
I have a Rakefile executing a MiniTest test suite that merely includes the test case files.
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = FileList['test/ts_*.rb']
t.verbose = true
end
ts_test_suite.rb:
gem 'minitest'
require_relative 'tc_requirement_tests.rb'
require_relative 'tc_command_tests.rb'
require_relative 'tc_movement_tests.rb'
require_relative 'tc_placement_tests.rb'
When I execute rake test from the commandline 2 of the 4 files execute successfully and (for some strange reason) the other two are not being executed. tc_requirement_tests.rb is one of those two files:
require 'test_base.rb'
require './app/turn_to.rb'
require './app/direction.rb'
class RequirementTests < TestBase
def requirement_test_1
#bad_robot.place(0, 0, Direction::NORTH)
#bad_robot.move
assert_equal "Output: 0,1,NORTH", #bad_robot.report_posture
end
def requirement_test_2
#bad_robot.place(0, 0, Direction::NORTH)
#bad_robot.turn(TurnTo::LEFT)
assert_equal "Output: 0,0,WEST", #bad_robot.report_posture
end
def requirement_test_3
#bad_robot.place(1, 2, Direction::EAST)
#bad_robot.move
#bad_robot.move
#bad_robot.turn(TurnTo::LEFT)
#bad_robot.move
assert_equal "Output: 3,3,NORTH", #bad_robot.report_posture
end
end
If I deliberately put a syntax error in one of the two test case files that are not executing, Rake complains with the expected error message, so I know that it is "seeing" the file.
Any ideas why 2 of the 4 test case files are not being executed?
It sounds like your test framework needs the test function names to begin test_. Try renaming your test functions so that they're in the format test_requirement_1, test_requirement_2, etc.
Where can I write code to be executed only once after loading of all global fixtures, and before running any tests/specs
I tried before(:suite) with rspec 1.3.1 on Rails 2.3.11 and that seems to get executed before fixtures.
How about a rake task(/lib/tasks) ? For instance, i have one(reset_db.rake) that loads fixtures, resets db and more :
namespace :db do
desc "Drop, create, migrate, seed the database and prepare the test database for rspec"
task :reset_db => :environment do
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
Rake::Task['db:fixtures:load'].invoke
Rake::Task['db:test:prepare'].invoke
end
end
I run into the same issue, but still haven't found any way to hook up some code after loading fixtures ... so i used the SpyrosP solution. However the problem with this way of doing is that you can't benefit anymore of the fixtures accessors helpers, since you don't load your fixtures from the rspec config but from a rake task.
So basically you neeed to recreate theese helpers like that (code is a bit dirty but seems to work for me :
#spec_helper.rb
module CustomAccessors
# Remplacement de fixtures :all
%w{yml csv}.each do |format|
paths = Dir.
glob(::Rails.root.join("spec/fixtures/*.#{format}")).
map! { |path| path.match(/\/([^\.\/]*)\./)[1] }
paths.each do |path|
define_method path do |*args|
path.singularize.camelcase.constantize.find(ActiveRecord::Fixtures.identify(args[0]))
end
end
end
end
RSpec.configure do |config|
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.include(CustomAccessors)
end
I am in the process of upgrading my application to Rails 3. I started using Rspec 2 with Rails 3. I need to turn off transactional fixtures for some of my rspec tests. Prior I used the following code in my model specs
before(:all) do
ActiveSupport::TestCase.use_transactional_fixtures = false
end
after(:all) do
ActiveSupport::TestCase.use_transactional_fixtures = true
clean_engine_database
end
That now gives me the error:
Failure/Error: ActiveSupport::TestCase.use_transactional_fixtures = false
undefined method `use_transactional_fixtures=' for ActiveSupport::TestCase:Class
Is there a way to do this per test block in Rails 3 with Rspec 2?
I'm looking for the answer to this question, came across this blog entry
It suggests to declare inside the describe block
describe "xxx" do
self.use_transactional_fixtures = false
...
I tried it with Rails 3.0.7 with RSpec 2.6.3, and looks like working.
RSpec.configure do |config|
config.use_transactional_fixtures = true
end
You can disable transactional fixtures globally by putting config.use_transactional_fixtures = false on the spec_helper.rb. If you want to control them by test (e.g. use transactional just on some of them), you can set this behavior with DatabaseCleaner.
I've had a related problem when testing pages with javascript on the browser (a scenario that does not work with transactional fixtures). Here's how I managed to work around it: http://github.com/lailsonbm/contact_manager_app
I wrote a little monkeypatch to the Rails MySQLAdapter and want to package it up to use it in my other projects. I am trying to write some tests for it but I am still new to testing and I am not sure how to test this. Can someone help get me started?
Here is the code I want to test:
unless RAILS_ENV == 'production'
module ActiveRecord
module ConnectionAdapters
class MysqlAdapter < AbstractAdapter
def select_with_explain(sql, name = nil)
explanation = execute_with_disable_logging('EXPLAIN ' + sql)
e = explanation.all_hashes.first
exp = e.collect{|k,v| " | #{k}: #{v} "}.join
log(exp, 'Explain')
select_without_explain(sql, name)
end
def execute_with_disable_logging(sql, name = nil) #:nodoc:
#Run a query without logging
#connection.query(sql)
rescue ActiveRecord::StatementInvalid => exception
if exception.message.split(":").first =~ /Packets out of order/
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
else
raise
end
end
alias_method_chain :select, :explain
end
end
end
end
Thanks.
General testing
You could start reading about testing.
After you are understanding the basics of testing, you should think what you have changed. Then make some tests which test for
the original situation, resulting in errors since you updated it. So reverse the test after it indeed is working for the original situation.
the new situation to see whether you have implemented your idea correctly
The hardest part is to be sure that you covered all situations. Finally, if both parts pass then you could say that your code it working as expected.
Testing gems
In order to test gems you can run
rake test:plugins
to test all plugins of your rails application (see more in chapter 6 of the testing guide), this only works when the gem is in the vendor directory of an application.
Another possibility is to modify the Rakefile of the gem by including a testing task. For example this
desc 'Test my custom made gem.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
would run all available tests in the test directory ending with _test.rb. To execute this test you can type rake test (from the gem directory!).
In order to run the tests for the gem by default (when typing just rake) you can add/modify this line:
task :default => :test
I used the second method in my ruby-bbcode gem, so you could take a look at it to see the complete example.