Rails 2.3 and minitest - ruby-on-rails

I would like to try minitest with an existing Rails 2.3.14 application. I already tried several approaches but none of them seem to work.
It essentially boils down to this. When I add minitest to the Gemfile, all tests I run with bundle exec rake test are NOT executed with minitest.
The problem is that most of the test cases extend the ActiveSupport::Testcase or ActionController::Testcase (which extends ActiveSupport::TestCase).
By looking at the code of this class I saw that it already (somehow) suppports MiniTest:
class TestCase < ::Test::Unit::TestCase
if defined? MiniTest
Assertion = MiniTest::Assertion
alias_method :method_name, :name if method_defined? :name
alias_method :method_name, :__name__ if method_defined? :__name__
else
...
end
(see https://github.com/rails/rails/blob/2-3-stable/activesupport/lib/active_support/test_case.rb for complete code)
My question here is:
Is it somehow possible to use minitest instead of test::unit in Rails 2.3 without having to extend (MiniTest::Unit::TestCase)

Any testing framework is made of two things, a way to define and run tests (call this the test runner) and an assertion framework.
Looking at ActiveSupport it seems that if MiniTest is defined at all, running the rails Unit test runner will default to using MiniTest's assertions classes. This means you get to use Minitest's assertion syntax.
Getting MiniTest defined should just be a case of requiring 'minitest\unit'.
However if you want to use the runners, then you need to derive from the MniTest framework test fixture base classes.
There is a step by step walkthrough in railscasts for setting it up yourself.
It boils down to:
Remove test_unit from your config/applications.rb
Add the minitest gem to your gem file "Gemfile"
Setup the environment in a helper file you can include into your tests
Add a rake task to run the tests. (/lib/tasks/minitest.rake)
Railscasts has the details.
If you don't want to change your existing tests to do that.. then you have to monkey patch Test::Unit to redefine TestCase to either be the chosen MiniTest base class or something that derives from one. This is the approach that this gem takes and may give you some ideas on how best to go about that.
The other solution is to do a search/replace through your code to switch the base classes of the test cases.
I hope this helps.
I Updated my answer and remove the following as out of date:
minitest-rails has rightly been pointed out as it works for Rails 3.1 only.
This gem seems to be old (26th March 2009) but it may help. Check the source code if you need hints to do something similar.

Related

How do I use the normal controller test assertions in Minitest Spec DSL

I usually write my specs in RSpec but I use Minitest too.
Recently I learnt that there is a minitest dsl that could read like RSpec. They call it Minitest::Spec. I have checked it out and I think I like it. The gem 'minitest-rails' makes the setup configuration easy. There is however one limitation I have faced and that is in the integration specs. What is the equivalent for assertions like assert_response, assert_no_difference, and assert_template?
I have seen an answer. It turned out that I got them in the very gem that supplied the test expectations. I looked into the source code of the minitest/rails/controller.rb and I saw the simple way those expectations were implemented is by aliasing the real minitest assertions. Here is my find
class ActionController::TestCase # :nodoc:
alias :must_respond_with :assert_response
alias :must_redirect_to :assert_redirected_to
alias :must_render_template :assert_template
alias :must_select :assert_select
alias :must_select_email :assert_select_email
alias :must_select_encoded :assert_select_encoded
end

Unit testing in Rails 3.2 [duplicate]

I read somewhere that 'minitest' is the "new test::unit for ruby 1.9.2+".
But ruby 1.9.3 seems to include both test::unit and minitest, is that true?
In the default rails testing, as outlined in the Rails testing guide.... things like ActiveSupport::TestCase, ActionController::TestCase, are these using Test::Unit or Minitest?
In the rails guide, it shows examples with tests defined like this:
test "should show post" do
get :show, :id => #post.id
assert_response :success
end
That syntax, test string, as opposed to defining methods with names like test_something -- isn't mentioned in the docs for either Test::Unit or Minitest. Where's that coming from? Is Rails adding it, or is it actually a part of... whatever testing lib rails is using?
PS: Please don't tell me "just use rspec". I know about rspec. I am trying to explore the stdlib alternatives, in the context of rails.
There is a Test::Unit "compatibility" module that comes with Minitest, so that you can (presumably) use your existing Test::Unit tests as-is. This is probably the Test::Unit module you are seeing.
As of rails 3.2.3, generator-created tests include rails/test_help which includes test/unit.
The test "something" do syntax is a rails extension. It's defined in ActiveSupport::Testing::Declarative, which is require'd by rails/test_help.
This is perhaps a bit of a tangential response, but as to your rspec comment... You might want to take a look at minitest/spec which provides spec flavor syntax in stdlib in 1.9.x.
http://bfts.rubyforge.org/minitest/MiniTest/Spec.html

Domain object extraction with MiniTest

I have two questions. The first is a basic one. MiniTest is a drop-in replacement for UnitTest. So if you use generators in rails, you get a bunch of ActiveSupport::TestCase classes. If you use minitest (without minitest-spec-rails) then you can do
1.must_equal 1
# instead of
assert_equal 1, 1
Correct? So it's confusing to me why there's a MiniTest::Unit::TestCase class as described in railscast #327 (pro episode paywall sry). It's confusing when looking at a test suite which I'm actually using. If minitest is a drop-in replacement then I'm using minitest to execute testunit style rails tests. If I take it out, I'm using testunit to run testunit tests?
So let's say I am using MiniTest to run TestUnit style tests.
require 'test_helper'
class FooTest < ActiveSupport::TestCase
end
After watching destroyallsoftware's screencast on extracting domain objects, I was inspired. He makes some good points about avoiding loading test_helper.rb to speed up the test suite without resorting to spork trickery (which is exactly what I do). But how can I avoid loading test_helper.rb when that's what gives me ActiveSupport::TestCase from above?
Can you not extract domain objects and put them in lib/ or extras/ with MiniTest or TestUnit?
The answer to your first question is "no, not correct". Minitest is not a "drop-in replacement" for Test::Unit. Minitest provides a simpler implementation for most of Test::Unit, but not all of it. In Ruby 1.9 the Test::Unit library is built on top of Minitest's TestCase class, and fills the gaps between the two libraries.
Minitest provides two modes for writing tests: the classic TestCase approach, and a separate Spec DSL. Like Test::Unit, the Spec DSL is built on top of Minitest's TestCase. So while 1.9's Test::Unit and Minitest's Spec DSL are both are built on Minitest's TestCase, you can't use the Spec DSL in Test::Unit because its not part of its ancestry.
The answer to your second question is you cannot avoid test_helper.rb if you want to use ActiveSupport::TestCase. You will need to require minitest/autorun and have your test class inherit from MiniTest::Unit::TestCase.

minitest, test::unit, and rails

I read somewhere that 'minitest' is the "new test::unit for ruby 1.9.2+".
But ruby 1.9.3 seems to include both test::unit and minitest, is that true?
In the default rails testing, as outlined in the Rails testing guide.... things like ActiveSupport::TestCase, ActionController::TestCase, are these using Test::Unit or Minitest?
In the rails guide, it shows examples with tests defined like this:
test "should show post" do
get :show, :id => #post.id
assert_response :success
end
That syntax, test string, as opposed to defining methods with names like test_something -- isn't mentioned in the docs for either Test::Unit or Minitest. Where's that coming from? Is Rails adding it, or is it actually a part of... whatever testing lib rails is using?
PS: Please don't tell me "just use rspec". I know about rspec. I am trying to explore the stdlib alternatives, in the context of rails.
There is a Test::Unit "compatibility" module that comes with Minitest, so that you can (presumably) use your existing Test::Unit tests as-is. This is probably the Test::Unit module you are seeing.
As of rails 3.2.3, generator-created tests include rails/test_help which includes test/unit.
The test "something" do syntax is a rails extension. It's defined in ActiveSupport::Testing::Declarative, which is require'd by rails/test_help.
This is perhaps a bit of a tangential response, but as to your rspec comment... You might want to take a look at minitest/spec which provides spec flavor syntax in stdlib in 1.9.x.
http://bfts.rubyforge.org/minitest/MiniTest/Spec.html

Can I switch the testing framework of a Rails app?

When I started my Rails app, I chose RSpec as my testing framework, because of all the hype. Now, I'm trying to write more tests, and I find that I don't like to write tests this way. I'd like to switch back to the default testing framework.
How could I do this switch? I'm using Rails 3.0.5
Don't know if you are aware, but if you use assertions instead of rspec-expectations (obj.should matcher), which you can already do without any additional configuration, then the only difference is this:
# w/ Test::Unit
class FooControllerTest < ActionController::TestCase
test "something or other" do
...
end
end
# w/ RSpec
describe FooController do
it "does something or other" do
...
end
end
Everything else that you can write using Test::Unit in Rails, you can write using RSpec exactly the same way.
Then you get all the non-syntax-related benefits of RSpec like readable output, a robust command line tool with its own -help output, etc.
I realize that doesn't answer the question you're asking, but I hope it helps you in your decision process.
It's not an either/or situation. You can have RSpec and Test::Unit tests in the same Rails application, so just begin writing Test::Unit tests. No need to switch, just do new development with Test::Unit.
Depending on how you run your tests, your CI setup, and how you have modified your app this may be more or less changes, but in practice these are straightforward.
in config/application.rb
module AppName
class Application < Rails::Application
generate.test_framework :test_unit, :fixture => false # :rspec <- before
...
New models/controllers generate the basic test/* files

Resources