After upgrading my rails app to 4.2, I started writing automated tests.
I started by doing something super simple:
class SimpleTest < ActionDispatch::IntegrationTest
test 'Browse a page' do
assert true
get '/'
assert_response :success
end
end
But when I:
▶ rake test
▶ bin/rake test
Nothing happens. No error, no blocking, process finishes, just nothing.
Did I miss something?
I was missing the require 'test_helper' at the beginning of my test, containing:
# /test/test_helper.rb
ENV["RAILS_ENV"] ||= "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending!
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
# Add more helper methods to be used by all tests here...
end
Related
I'm fairly new to Ruby/Ruby on Rails and having trouble stubbing out a method via mocha in an existing codebase.
I've simplified the code down to a MWE where this breaks.
Here is test_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
class Minitest::Test
def before_setup
end
end
And here is the test:
require 'test_helper'
require 'mocha/minitest'
class MyTest < ActionMailer::TestCase
describe "some test" do
it "should stub" do
My::Class.stubs(:bar).returns("foo")
puts My::Class.bar
end
end
end
This results in the following error when I run the test:
Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test
However, when I redefine my test_helper.rb as follows:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
# class Minitest::Test
# def before_setup
#
# end
# end
The test passes (and "foo" is printed as expected).
Why does the class Minitest::Test...end in test_helper.rb cause the first error? I can't remove that code from the actual codebase, so how can I modify it to work with mocha?
Ruby version: 2.4.1
Rails version: 4.2.8
Mocha version: 1.5.0
Adding a call to super in the patched method before_setup in test_helper.rb works:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
class Minitest::Test
def before_setup
# do something
super
end
end
This call to super allows the before_setup of Mocha::Integration::MiniTest to be called, which is necessary for proper initialization.
I learned how to test image file uploading from this excellent article:
https://jeffkreeftmeijer.com/2010/2014/using-test-fixtures-with-carrierwave/
Adapting those ideas for my app, I've got this test that works:
test "uploads an image" do
pic = Picture.create(:image => fixture_file_upload('/files/DJ.jpg','image/jpg'), :user => User.first)
assert(File.exists?(pic.reload.image.file.path))
end
I would like to test the same thing for the user interface, so I would think that this test would also pass:
test "create new picture" do
capybara_login(#teacher_1)
click_on("Upload Pictures")
fill_in "picture_name", with: "Apple"
attach_file('picture[image]', Rails.root + 'app/assets/images/apple.png')
check("check_#{#user_l.id}")
check("check_#{#admin_l.id}")
click_on ("Create Picture")
#new_pic = Picture.last
assert_equal "Apple", #new_pic.name
assert #new_pic.labels.include?(#user_l)
assert #new_pic.labels.include?(#admin_l)
assert #teacher_1, #new_pic.user
assert File.exists?(#new_pic.reload.image.file.path)
end
But it fails on the last line, asserting the existence of the file.
Below are the parts of my test_helper that I thought would be relevant. I can show the whole test_helper if someone thinks it necessary.
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
require 'capybara/rails'
Minitest::Reporters.use!
CarrierWave.root = 'test/fixtures/files'
class CarrierWave::Mount::Mounter
def store!
# Not storing uploads in the tests
end
end
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
include ApplicationHelper
include ActionDispatch::TestProcess
CarrierWave.root = Rails.root.join('test/fixtures/files')
def after_teardown
super
CarrierWave.clean_cached_files!(0)
end
end
Everything appears to be working as expected in development and production.
Thank you in advance for any insight.
I've made an application with the omniauth-facebook gem. All of my rails test were passing, but after adding in code to check for an authenticated user for access to certain actions - some of my tests fail. How can I go about adding code to my tests to log in a "test" user so that I can simulate an authenticated user? Most of the google results showed examples for Rspec or Devise examples, but I've been using the default testing suite for Rails 5, so it's been difficult for me to find some examples of how to properly do this. Please let me know if you'd like me to provide any specific samples of my current tests. Nothing relevant came to mind to include since I'm not sure where to start with this.
So after reading through documentation here, and trying various things here's what I came up with...
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
OmniAuth.config.test_mode = true
OmniAuth.config.add_mock(:facebook, {:uid => '123456', info: { email: 'email_address_of_user_in_fixtures#gmail.com' }})
def sign_in_admin
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:facebook]
get auth_facebook_callback_path
end
end
test/controllers/restaurants_controller_test.rb
require 'test_helper'
class RestaurantsControllerTest < ActionDispatch::IntegrationTest
setup do
# I sign in an admin user, and proceed
sign_in_admin
#restaurant = restaurants(:mcdonalds)
end
# other test methods for actions ...
end
config/routes.rb
Rails.application.routes.draw do
#...
get 'auth/facebook/callback', to: 'sessions#create'
#...
end
Alright, a little embarrassed I asked a very similar question yesterday, but we're stuck again.
We've fixed all of our controller tests, and started writing integration tests. We're encountering errors on all of our integration tests, even the famous assert = true:
site_layout_test.rb
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "the truth" do
assert true
end
#commenting out our real tests for debugging
=begin
test "top navigation bar links" do
get 'beta/index'
assert_template 'beta/index'
assert_select "a[href=?]", home_path
assert_select "a[href=?]", how_it_works_path
to do add map, community, sign up, login paths
to do: add paths to links on dropdown if user is logged in
end
=end
end
Terminal Test Results
12:31:32 - INFO - Running: test/integration/site_layout_test.rb
Started with run options --seed 27747
ERROR["test_the_truth", SiteLayoutTest, 2015-10-25 11:36:28 +0800]
test_the_truth#SiteLayoutTest (1445744188.33s)
NoMethodError: NoMethodError: undefined method `env' for nil:NilClass
1/1: [===================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.05380s
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
include Devise::TestHelpers
# Add more helper methods to be used by all tests here...
#
def setup_variables
#base_title = "TripHappy"
end
end
Unfortunately, that error message gives us very little clue as to where the error is occurring. I tried reading up on Minitests, but without an idea of where to look I'm fairly lost.
Thank you in advanced!
For reference, we're following M. Harti's Rails Tutorial, which means we're using Guard and Minitest Reporters. We also have a login system via Devise, if that affects anything.
Solution:
It was an issue with the Devise. I included include Devise::TestHelpers in class ActiveSupport::TestCase instead of class ActionController::TestCase.
It was an issue with the Devise. I included include Devise::TestHelpers in class ActiveSupport::TestCase instead of class ActionController::TestCase
I use mini-test for testing framework. I use omniauth gem for authentication. I use simplecov for code coverage. I run my tests using "bundle exec rake" or "rake minitest:controllers". I give an example for controllers. When I run rake minitest:controllers, controllers code coverage becomes 100%. But, when I run bundle exec rake, controllers code coverage become 60%.
SessionsController.rb code:
class SessionsController < ApplicationController
def create
auth = request.env["omniauth.auth"]
person=Person.find_by_provider_and_uid(auth.provider,auth.uid) || Person.create_with_omniauth(auth)
redirect_to root_path
end
end
SessionsController_test.rb
require "minitest_helper"
describe SessionsController do
before do
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:identity]
#person = Fabricate.build(:person)
end
it "should create authentication" do
assert_difference('Person.count') do
post :create, :provider => "identity"
end
assert_redirected_to root_path #person
end
end
I wonder that if I miss one point on writing test. I wait your ideas. Thanks in advance.
EDIT
minitest_helper.rb
require 'simplecov'
Simplecov.start
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require "minitest/autorun"
require "minitest/rails"
require "minitest/pride"
require 'database_cleaner'
require "minitest/rails/capybara"
require "minitest-mongoid"
DatabaseCleaner[:mongoid].strategy = :truncation
#OmniAuth.config.test_mode = true
OmniAuth.config.add_mock(:identity, {
:uid => '12345'
})
class MiniTest::Spec
before :each do
DatabaseCleaner.start
end
after :each do
DatabaseCleaner.clean
end
end
According to Simplecov's documentation, you just have to add theses lines in top of your test/test_helper.rb:
# test/test_helper.rb
require 'simplecov'
SimpleCov.start
# ...
Also do not forget to install simplecov gem in test group:
# Gemfile
# ...
group :test do
gem 'simplecov'
end
And that's it.
Rails 6: I encountered some issues with Rails 6 and tests paralelization so you may deactivate it in test/test_helper.rb:
# test/test_helper.rb
# ...
class ActiveSupport::TestCase
# ...
# parallelize(workers: 2)
end
It's hard to tell with no more information.
First of all try rake minitest:all and update your question with the result.
Please try following in case the former test did not conclude positively:
namespace :test do
task :coverage do
require 'simplecov'
SimpleCov.start 'rails' # feel free to pass block
Rake::Task["test"].execute
end
end
Let us know and we can edit or update the answer.
Minitest is known to have had some issues with it. I believe it was still work in progress, not sure where they stand now. It is not you, it's minitest. That workaround helped in some cases, maybe it helps you too.