Rails testing with factories. Transactional uniqueness problem - ruby-on-rails

I keep getting validation errors when running factories due to uniqueness constraints on fields. I am using shoulda with factory_girl. I have a both a unit test and a functional test creating 2 products in the database. I can run 'rake test:units' and 'rake test:functionals' over and over in any order and everything is will be green but when I run 'rake test' which runs the units followed by the functionals I get errors due to uniqueness.
I also tried creating models to break uniqueness in 2 different unit tests and I get the error then as well.
I have been playing with these settings in test_helper.rb but can't get anything to work
class ActiveSupport::TestCase
self.use_transactional_fixtures = true
self.use_instantiated_fixtures = false
end
Does the transactional_fixtures setting take any effect of factories. Whats the best way to handle cleaning the database between tests?

(sigh..)
So the problem was that I was copying code from the shoulda docs and ended up declaring my test classes like so:
class UserTest < Test::Unit::TestCase
However for the transactional fixtures setting to have any effect you need to inherit from ActiveSupport::TestCase by declaring your classes
class UserTest < ActiveSupport::TestCase
Hopefully this can help save someone else some time.

Related

Rails fixtures dumping all data in the db

I've been in Factory land for the past few years and have decided to come back to fixtures but am running into a problem.
In my test_helper.rb I have
class ActiveSupport::TestCase
fixtures :all
end
Then in an individual test case I might be doing something like users(:one) however the data for users(:two) and the data for other tables that I am not calling on seems to be present in the test database.
So, is this the expected behavior? I have a hard to believing it is, seems strange from an isolated testing perspective.
This happens because you load all the fixtures at once from fixtures :all statement. A rule of thumb in tests is to load only the required data for a given test (not all). This also could slow down your test running time.
If you want to load only the selected fixtures you could do
fixtures :<fixture name>
Ex:
fixtures :users
Read more about fixtures.
One more thing, do you have a particular reason to comeback to fixtures. Factories are the way to go; they allow you do organize your test data cleanly.
Read more about factories.

How can a person toggle the use of transactional_fixtures for one set of tests using Test::Unit?

I have some thinking-sphinx tests that I need to turn off transactions for to prevent mysql locks, but in doing so I break a lot of other tests previously written, so I need to be able to toggle the setting.
I have found similar questions regarding rspec, but none for Test::Unit.
I have tried self.use_transactional_fixtures = false which is what allows the sphinx tests to pass, but causes others to break. I am sure I could set that to true in all the other tests, but that would also require all other tests to include the code snippet as well which is messy.
I have also tried uses_transaction :test_method_name, but that works the same as the previously mentioned method.
Thanks in advance for any help.
You should be able to set use_transactional_fixtures to false for just the sphinx related tests that you have, but leave it true for the other tests you have. The key will be to split your tests into separate test classes. So in test_helper.rb you'll still have:
self.use_transactional_fixtures = true
But then for your other tests you'll do something like
class PostTest < ActiveSupport::TestCase
# your normal post tests that require transactional fixtures
end
class SphinxRelatedPostTest < ActiveSupport::TestCase
self.use_transactional_fixtures = false
# your other tests
end
That should mean that your regular tests run using the fast transactional fixtures, but rails will use the DELETE / INSERT method as required.
You can also use uses_transaction to disable them for specific method/test.
class MyTest < ActiveSupport::TestCase
uses_transaction :test_something
test "something" do
"test something like callback"
end
end

Where to put common Unit Test code in ruby on rails environment?

Using Rails 3.0, I have a small bit of code that I seem to be calling in all my Unit tests.
Is there a common place to put shared unit test code that won't be incorporated into both unit and functional tests? I'd rather ONLY incorporate it into the needed files, just the unit tests.
I'm new to testing practices in general. Is it common in Rails to test validations (for example, test: validates_presence_of :name)? Most of my functions that test validations on a model are all basically the same (just swap in and out correct fixture and attribute name). Doesn't seem very DRY. Looking for a way to refactor.
Thanks.
You can place the code in the test/test_helper.rb file.
You should already find a code fragment that looks like this
class ActiveSupport::TestCase
self.use_transactional_fixtures = true
self.use_instantiated_fixtures = false
end
If the code should be used in all your tests, you can add your methods in the ActiveSupport::TestCase class. Otherwise, wrap them into a Module and mix the module where required.
It's a good practice to test validations not to test the validation itself (the validates_presence_of macro is already tested in the Rails codebase), but to make sure chances in your code don't affect your class business.
For instance, there might be validation which needs to be triggered only in specific events. Or you might want to make sure no one removed your super-secret validation on that specific model.
If you want to test your model validations, I encourage you to check out shoulda. Shoulda provides several handy methods to test your validations.
class PostTest < ActiveSupport::TestCase
should belong_to(:user)
should validates_presence_of(:id)
end

Rails3: Unit testing a library doesn't load the fixtures

I added a unit test manually to test a library I'm building. I have some fixtures which are tested in their corresponding models without any issues.
The test case inherits from ActiveSupport::TestCase which runs fixtures :all.
require 'test_helper'
require 'mylib'
class MyLibTest < ActiveSupport::TestCase
#user = User.find(1)
test "Setup" do
assert_equal(#user.id, 1)
end
end
Even though user = User.find(1) works fine in every test that is actually for a model, this test raises an exception: /Library/Ruby/Gems/1.8/gems/activerecord-3.0.0.beta4/lib/active_record/relation/finder_methods.rb:287:in 'find_one': Couldn't find User with ID=1 (ActiveRecord::RecordNotFound)
I have tried moving fixtures :all into the MyLibTest-class (suggested in another post) but with no difference.
How can I make my test work?
EDIT
I found out what was wrong, and it wasn't at all related to the fixtures. I wanted to use the same User object in several test cases so I added #user = User.find inside the class, but not inside a testcase. When I realized this and tried putting it in a test case, everything worked. Awkward :)
I can't be too sure exactly whats up without seeing how your Fixtures file is set up, but try these:
Try moving "fixtures :all" to test_helper.rb.
In the fixtures files, are you setting "id:" on each record? If not, the id is actually not going to be simply incremental - it is created based on the name of the fixture. Try using "User.first" instead of User.find(1). If you need the id to be 1, then set "id: 1" on the fixture.
Hope this helps.

Rails unit testing doesn't load fixtures

rake test:units fails in my current application, because the needed data of the fixtures is missing.
If I'm loading the fixtures manually via rake db:fixtures:load RAILS_ENV=test the unit tests are working, but rake purges the test database.
My test_helper includes fixtures :all and my tests are inheriting from it - but the fixtures are simply not loading.
I'm kind of clueless at the moment and could really need some help!
I've tried a lot and I think it has to do with some environment settings or plugins used in this project. Does anyone know where to read about which files are loaded for the testing environment?
Put the call to fixtures :all in your test class, not the super class (test_helper). My guess is that initialization of the super class isn't working the way you're expecting and that fixtures :all isn't be called. Perhaps try putting the call in the initialize method of test_helper.
My test/test_helper.rb looks like this:
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
# Add more helper methods to be used by all tests here...
end
I finally found the problem, although the solutions is kind of hacky.
One plugin is relying that there is some data in the database, at least one row. So what happened was:
rake loads database schema
rake tries to load environment
environment includes plugin
plugin loading fails because of missing at least one row
no fixtures are loaded
The hacky solution is: put the needed data directly into schema and not into a fixtures, because it's loaded to late.
I'll search for a more convenient solution and will update this answer if I found one.
Another approach is to write your own custom rake task for testing.
For example:
task :test_units do
RAILS_ENV = 'test' # Force the environment to test
puts "Recreate the test database"
Rake::Task['db:test:prepare'].invoke
puts "Seed the database with fixtures"
Rake::Task['db:fixtures:load'].invoke
puts "Executing Unit Tests"
Rake::Task['test:units'].prerequisites.clear
Rake::Task['test:units'].invoke
end
My problem is forgot to put "require 'test_helper'" at the head.
eg.
require 'test_helper'
class AdminUserTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
I had the same problem. Or rather, the problem was that my fixtures were not current with the database schema. Instead of throwing an exception, rails just used the test database as a fallback solution. Most iffy.

Resources