开发者

What is happening during Rails Testing?

I'm new to Ruby On Rails. I love, it has Testing capabilities built in. But, I can't wrap around my head with testing. Here is my first basic Question about it.

What happens during testing really?

I understand development, we want some result, we use the data we have or get it from users to achieve the end result we want. But, the notion of testing seems sometimes confusing for me. I have been testing applications in browser for some time, are we replicating the same with code? Is it 开发者_如何学Cwhat testing is about? Replicating browser testing with automated code? Enlighten Me here.


Reading A Guide to Testing Rails Applications will be a good starting point.

Basically, you have three kinds of tests: unit, functional and integration.

Unit tests are testing your Models. In these tests you check whether a single method of your model works as expected, for example you set assign a login with spaces, and then you test whether the spaces were removed:

class UserTest < ActiveSupport::TestCase
  def test_login_cleaning
    u = User.new
    u.login = "  login_with_spaces  "
    assert_equal "login_with_spaces", u.login
  end
  # ... and other tests
end

Functional tests are testing your controllers (and views). In each test you simulate one request sent to one controller with given set of parameters, and then you ensure that the controller returned the proper response.

Note however, that in this test you cannot test the rendering of the page, so it's not strictly simulating a browser. To test whether your page looks nicely, you need to do it manually (I am almost sure some techniques exist, but I do not know of them).

An example of functional test:

class UserControllerTest < ActionController::TestCase
  def test_show_renders_admin
    get :show, :id => 1
    assert_response :success
    assert_select "div.user" do
      assert_select "span.name", "Joe Admin"
    end
  end
  def test_show_handles_unknown_id
    get :show, :id => 9999
    assert_response 404
    assert_select "p.warning", "No such user"
  end
end

Integration tests are testing a sequence of requests - something like a scenario, where an user logins, gets the 'create user' page, creates an user, and so on. These tests check whether the single requests (tested in functional tests) are able to work together.


I see that Simone already pointed the importance of automation in tests, so the link to the Guide is the only value in my answer ;-)

You may find it very helpful to apply some rules of Test Driven Development, especially when your project matures a little.

I know that it's not easy to start the project by writing test, because often you do not yet know how everything will work, but later, when you find a bug, I strongly suggest to start fixing every bug from writing a failing test case. It really, really helps both in the bug-fixing phase, and later - ensuring that the bug does not reappear.


Well, I noticed that I did not directly answer your question ;-)

When you start test procedure, Rails:

  • deletes the test database (so make sure you do not have any valuable data here),
  • recreates it using the structure of the development database (so, make sure you have run all your migrations),
  • loads all the fixtures (from test/fixtures/*)
  • loads all the test classes from test/units/* and other directories,
  • calls every method whose name starts with 'test_' or was created by the macro test "should something.." (alphabetically, but you may consider the order as being random)
  • before every call it executes a special setup procedure, and after every call it executes teardown procedure,
  • before every call it may (depending on the configuration) recreate your database data, loading the fixtures again.

You will find more information in the Guide.


What happens during testing is that you really run a set of specialized programs or routines (test code) that calls routines in your application (code under test) and verifies that they produce the expected results. The testing framework usually has some mechanism to make sure that each test routine is independent of the other tests. In other words the result from one test does not affect the result of the others.

In Rails specifically you run the tests using the rake test command line tool. This will load and execute each test routine in a random order, and tell you if each test was successful or not.


This answer doesn't necessary apply to Rails itself. When you talk about testing in Rails, you usually mean automatic testing.

The word automatic is the essence of the meaning. This is in fact the biggest difference between unit testing and "browser" testing.

With unit testing you essentially write a code, a routine, that stresses a specific portion of your code to make sure it works as expected. The main advantages of unit testing compared to "browser" testing are:

  1. It's automatic and can be run programmatically.
  2. Your test suite increases during the development lifecycle.
  3. You reduce the risk of regression bugs, because when you modify a piece of code and you run the test suite, you are actually running all the tests, not just a random check.

Here's a basic, very simple example. Take a model, let's say the User model. You have the following attributes: first_name, last_name. You want a method called name to return the first and last name, if they exist.

Here's the method

class User
  def name
    [first_name, last_name].reject(&:blank?).join(" ")
  end
end

and here's the corresponding unit test.

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def test_name
    assert_equal "John Doe", User.new(:first_name => "John", :last_name => "Doe").name
    assert_equal "John", User.new(:first_name => "John").name
    assert_equal "Doe", User.new(:last_name => "Doe").name
    assert_equal "", User.new().name
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜