New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rails test command to run the test suite
#9080
Conversation
|
/cc @dhh |
|
Seems good. I think we should update the guides in the scope of this pull request. Unless you think it will need a lot of work. |
|
Yeah, I'm working on the guide right now. Going to submit that as a separate commit, just in case if someone want to merge this in first. |
|
Documentation updated. Also, add some more stuff to my todo list. |
| You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of commands to help in testing. The table below lists all commands that come along in the default Rakefile when you initiate a Rails project. | ||
|
|
||
| | Tasks | Description | | ||
| | ------------------------------- | ----------- | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different table indent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch. fixed!
|
Cool stuff @sikachu |
|
@sikachu Awesome! |
|
Code updated based on @carlosantoniodasilva's review. Thanks! |
|
good job |
|
Is this going to be smart enough to run tests/specs for the appropriate test framework for those of us who don't use MiniTest? |
|
@calebthompson no, not for now. We might provide a hook later, but it's not currently in our radar. Actually, we were thinking about making |
|
I feel like this is just going to be cumbersome unless/until rspec and cucumber specifically pick it up. You'll end up with two ways of running tests, and frankly the gems that people prefer to test with are going to win out over Rails conventions here I think. |
|
With |
|
Right. I understand what you mean, and I like that. However, the goal of this ticket was to fix the slow |
|
I feel like we do need some way to hook into this. On many projects, I use different frameworks for unit tests, acceptance tests, and JavaScript tests (e.g., rspec/cucumber/jasmine or minitest/cucumber/jasmine). |
|
Please Do Investigate. On Jan 26, 2013, at 19:31, Andy Lindeman notifications@github.com wrote:
|
|
I really don't see the motivation for having Also, given that |
|
For last, why would you bind your test framework runner to Rails when there isn't a need in the first place? If you guys are having extra free-time, we still have ~400 issues open that would love some attention. |
What work was done to make the Since this is a replacement for existing working (if slow) code I would like to see evidence of why it is pointless to try to make Could it be something I can improve in rake? |
|
@drbrain the original problem was that running test via |
|
@myronmarston seems to think it's a '(mis?)-use' of Rake that's causing the problems: https://twitter.com/myronmarston/status/295296519203065856 https://twitter.com/myronmarston/status/295296827350200320 Myron, how should we be improving this? |
Let me preface my suggestions with two quick comments:
With that said, I think there's an optimal way to use rake that's quite different from how rails uses it. Specifically, it leverages the fact that rake, like most ruby programs, has two run-time phases:
My preferred way to use rake is to make phase 1 as lightweight and minimal as possible. My rule of thumb is to only require files that define rake tasks during this phase, and to defer all other requires to phase 2. Each task becomes responsible (either through the code directly in the task, or via a prerequisite task) for loading the files and libraries it needs to run. This goes hand-in-hand with the way I use bundler, and fits right in with my preferred approach of explicitly loading dependencies at runtime...but I know that DHH prefers the convenience of not having to manually manage dependencies at runtime. (As usual, this is about trade offs. The particular things I value most differ from the things DHH values most and that's fine). Rails has, for as long as I know, chosen to load the entire rails environment at task definition time, which essentially causes the environment to be double-booted when running a task that spawns a new process that boots the environment. Changing to my preferred approach would be a large change, but if there's desire to move in that direction, a major release (like rails 4) is the right time to do it. As a point of comparison, here's the kind of speed I get out of rake. This is on a large app that I (and an entire team at @seomoz) have been working on full time for 9+ months: That's 255 ms wall clock time, which is barely noticeable. As for the idea of having a more full-featured test runner...I heartily support such a thing (one of my favorite parts of rspec is the super flexible test runner, complete with the binary that supports a plethora of options), but I wonder if it's better suited as an external gem that can be used by any T::U/minitest project? Is there anything about this that needs to be coupled to rails? |
Yes, that's why I wanted to make sure you came here, and why I made sure to copy the tweet and the (mis?) part of it. The |
Thanks...it's nice to know my tweet was interpreted in the spirit it was intended :). |
|
Prem, before we apply this, please get -n and fixture loading implemented. I don't think it's a full replacement before that happens. |
|
@dhh |
|
Rails loads fixtures by default when you run the rake suite tasks. So "rake test" and "rake test:units" will load fixtures. This should do the same. But don't load fixtures when running one specific file or test within that file. In that case, we should have an option like --load-fixtures/-f that does it. On Feb 1, 2013, at 23:37, Prem Sichanugrist notifications@github.com wrote:
|
|
Code update with not loading fixture by default. @dhh can you give it another look? |
|
Looks good to me. I think this is good enough to merge and start using. I say we deprecate the "rake test" tasks. No reason to have two ways to do this. Also, we should pull in the test:prepare stuff so it doesn't go through Rake. |
|
@rubys see comment above from @dhh. We decided not to load all the fixtures by default if you run single test. I think the intention is that you will want to load only fixtures you want explicitly in the test file. However, if you run the whole suite, Regarding the support for only one file name: is that really the case? I think I have a test case to cover running multiple files. Can you re-confirming me on that one? |
|
My bad. When I specified two files, I neglected to notice that the second file had zero tests in it.
|
Add `rails test` command to run the test suite
@dhh why? This change
Providing Being able to run one test with just plain old ruby is an extremely important use case for me. I would like to know the essence of this feature so that I can add support for my usecase again. |
|
Just a couple more thoughts on this. When you do something like this: Rails generates a controller test that depends on fixtures, but that file cannot stand on it's own. It depends on fixtures, but does not load them. Someone writing their own controller test can choose whether or not to load fixtures, but as long as we're generating a controller test that depends on fixtures, shouldn't that file be able to run on it's own? |
|
Aaron, today fixtures are not loaded when you do "ruby -Itest test/unit/some_test.rb". "rails test test/unit/some_test.rb" would mimic that. The reason is that running a single test requires a quick feedback loop and loading all fixtures is slow, so reloading all the fixtures every time you run an isolated test where the fixtures are unlikely to change would be a poor trade-off. We'd still allow you to specify that fixtures should be reloaded, like "rails test test/unit/some_test.rb --reload-fixtures". "rails test models" would work just like "rake test:models" do today, which includes reloading the fixtures. The reason here is that the trade-off is different. Running an entire battery of tests take a fair while in most cases, so it's not an undue tax to reload fixtures before doing so. In other words, "rails test" operates just like rake + one-off ruby running does today. It mimics those behaviors to fit the trade-offs that are inherent in either operation. I don't see how any of these changes break existing code. Could you explain further? On Mar 20, 2013, at 6:20 PM, Aaron Patterson notifications@github.com wrote:
|
Actually, they do with Rails 3.2.x and Rails 4.0.0.beta1. And did up to this change, apparently in response to your request: 1a0c58b#L2L9 |
|
That's just loading the fixtures. What's I'm talking about is setting them up in the database, that's what's taking time. rake db:fixtures:load. On Mar 21, 2013, at 9:01 AM, Sam Ruby notifications@github.com wrote:
|
|
Wait. Let me double-check. I might interpret what @dhh wanted wrong in 1a0c58b#L2L9 We don't want to create records in the database when you start your test, but we definitely want you to be able to use |
Ok. Now I'm thoroughly confused :-) In any case, the problem that Aaron is seeing, and would like reversed, is as follows: |
|
That's a bug then. Prem must have misunderstood. The way it should work is:
If any of these points are not currently true, it's a bug. On Mar 21, 2013, at 9:29 AM, Sam Ruby notifications@github.com wrote:
|
|
@rubys I think I was the one who got it wrong. Load fixture != put them in the database. So it seems like we didn't even create records in the database when we ran Thanks @dhh @rubys and @tenderlove, and I'm sorry that I got it wrong. |
|
No worries, Prem. It is a little confusing that loading fixtures and providing access to them are two separate tasks. Glad we got it cleared up. Can you ping this thread again when it's all fixed up and Aaron/Sam can retest? Thanks! On Mar 21, 2013, at 9:35 AM, Prem Sichanugrist notifications@github.com wrote:
|
|
I've created #9854 to track the progress and put it on 4.0.0 milestone! |
|
@dhh the rake tasks call The actual problem behind the slow tests is that we load the environment twice. @wangjohn (and team MIT) are working to remove the requirement that we have one app per process. Once this requirement is gone, we will have the ability to switch environments in the same process. That means we can fix the rake tasks to have the same speed as I would like to revert the changes to the rake tasks. There is no reason to deprecate them, so we should not. TL;DR we can eventually make the rake tasks as fast as |
|
I guess I don't see why we need two ways to run the same thing. I'm fine that we have a transition period, but at some point we should pick that "rails test" is the way to run tests in Rails, and deprecate/extract the rake tasks that do the same time. |
Why |
|
I actually don't care much whether it's one or the other. What I care about is:
I find the argument form for rake test a little awkward, so from a CLI perspective, "rails test" seems nicer. But that's not the major point. |
|
@dhh these seem like fine requirements. We can eventually make
Quick proof that Here's the definition of task :aarontest do
require 'minitest/autorun'
$: << '.'
$: << 'test'
Dir['test/**/*_test.rb'].each { |x| require x }
end |
|
I buy all that. So the next question is timing. How quickly can we speed up rake test? In time for 4.0? If not, is it worth shipping "rails test" in the mean time? I would really like to have fast tests for 4.0. On Mar 25, 2013, at 10:44 AM, Aaron Patterson notifications@github.com wrote:
|
|
Alright. I don't feel comfortable shipping the singleton removal in 4.0. I think our deadline is too close. Instead, it is possible to detect that we are inside a rake test task before the application gets loaded. I've added a diff here which reverts the rake tasks but makes them as fast as If we're OK with that hack, I can modify all the test tasks to no longer shell out. People can have fast tests without using Here's output from a test app (using @rubys data): |
|
I'd be OK with a hack if we have a clean path to a solid solution. Then we don't have to divert to "rails test" on the API side. So I say let's roll with your speed up for "rake test" and thank prem for his working that provoked this, even if we don't end up keeping it. The goal all along was fast tests, so that's the big deal! |
|
Yeah, as long as we have a fast test runner, I don't mind if at the end we decide to not including |
|
@tenderlove, et al, is there a way that rspec-rails's I think most rspec-rails users use the |
To run the whole test suite:
To run the test file(s):
To run the test suite
For more information, see
rails test --help.This command will eventually replacing
rake test:*, andrake testcommand will actually invoking
rails testinstead.After this got merged, there'll be several things that need to be done:
rake test:*(but if you runrakeorrake test, there will no deprecation warning.Add a notification fortest:prepareevent, so that we can dropRake::Task['test:prepare'].invokeline.Add backuncommittedandrecentsuites.-nto specify the test name.