Archive for August, 2006

More Rails Testing SQLite Woes

So the other day when I posted about SQLite and Single Table Inheritance, I never did actually get around to writing any tests. Today, I wrote my first test. An easy one, and it exploded all up in my face.

<pre> 5 tests, 5 assertions, 0 failures, 0 errors rcov.rb:642:in `[]': no implicit conversion from nil to integer (TypeError) from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.7.0.1/lib/rcov.rb:642:in `aggregate_data' </pre>

Grr. I keep fussing with various things and nothing works. I take out my test and rcov runs fine, but of course that’s with out any real tests. Oh a hunch, I set up a MySQL database and run my tests there, and they run great. I turn to google, and nothing. I have SWIG installed- or do I? As it turns out I must have skipped installing SWIG on my mac when setting everything up. I uninstall the SQLite3/Ruby gem, build and install SWIG, reinstall the SQLite3/Ruby, and boom. My tests are up and running.

Steps for building and installing SQLite3, SWIG, and SQLite3/Ruby on OS X Tiger if you need them. These assume you’ve already installed the Xcode Tools, and possibly already followed Dan Benjamin’s Guide to install Rails.

Install SQLite3

<pre> curl -O http://www.sqlite.org/sqlite-3.3.7.tar.gz tar xzvf sqlite-3.3.7.tar.gz cd sqlite-3.3.7 ./configure --prefix=/usr/local make sudo make install cd .. </pre>

Install SWIG

SWIG is distributed through SourceForge, so download the latest release (currently, 1.3.29 at the time I’m writing this).

<pre> tar xzvf swig-1.3.29.tar.gz cd swig-1.3.29 ./configure --prefix=/usr/local make sudo make install cd .. </pre>

Install SQLite3/Ruby


sudo gem install sqlite3-ruby

Select which gem to install for your platform (i686-darwin8.6.1) 1. sqlite3-ruby 1.1.0 (mswin32) 2. sqlite3-ruby 1.1.0 (ruby) 3. sqlite3-ruby 1.0.1 (mswin32) 4. sqlite3-ruby 1.0.1 (ruby) ... 10. sqlite3-ruby 0.5.0 (ruby) 11. Cancel installation
> 2

Choose the most recent “ruby”; version, in this case I chose “2”;. And that’s it you should be good to go. Some more info about using RCOV with Rails.

Rails, Meet SQLite and It’s Cryptic Errors.

Yesterday afternoon, I setup rcov and got ready to start writing tests for my new Rails app. In stead of the the expected, rake rcov greets me with this.

/usr/local/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.1.0/lib/sqlite3/errors.rb:94:in `check': SQL logic error or missing database (SQLite3::SQLException)

“What?” I say. “Oh, I forgot to set up the schema in my test database.”
One rake db:test:prepare later and we’re dandy. Today, I go to do the same and I’m greeted with the same error.

/usr/local/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.1.0/lib/sqlite3/errors.rb:94:in `check': SQL logic error or missing database (SQLite3::SQLException)

“Oh, hmm, maybe test database isn’t at the latest migration.”

rake db:test:prepare

Wrong.

“Um, Okay…”

rake db:migrate RAILS_ENV=test

Nope.

“Well, WTF^^.”

So I turn to google. A message on the Ruby on Rails mailing list suggests I disable transactional fixtures in test/test_helper.rb.

self.use_transactional_fixtures = *false*
 

So, I run my tests again.

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: initiates: DELETE FROM initiates WHERE 1=1

“Oh. That’s different. Wait.”

There is no initiates table.

“Oh, DUH.”

An Initiate is a subclass of Person using Single Table Inheritance. A quick fix to initiate_test.rb and I’m good to go.


class InitiateTest < Test::Unit::TestCase
  fixtures :people

 

Of course, fixtures for an Initiate in people.yml would look something like this:


somebody:
  id: 2
  type: Initiate
 

The moral of the story? Disabling transactional fixtures in your tests will (while slowing them down) gives less cryptic errors from SQLite. Also, remember to set up your fixtures correctly when using Single Table Inheritance.