imedo Development Blog

there is no charge for awesomeness

Archive for the ‘test’ tag

Overriding rake tasks and db:test:prepare strangeness

without comments

Some time ago our CC.rb build started to fail with errors like this:

Mysql::Error: Can't create table './cc_test/#sql-8e7_5bab.frm' (errno: 150): ALTER TABLE questions ADD CONSTRAINT questions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE

We’re using the foreign key migrations plugin which automatically generates foreign keys for mysq. It works fine but somehow the db:test:prepare rake task started to fail – everytime at a different key and only on the build server.

After hours of hunting down the problem I finally gave up and did what you always can do if you can’t solve a problem: cheat. So I just created a new db:test:prepare task which calls the mysql commands and basically does the same as the rake task. It’s not as portable as the default one, of course, but it has one property that the default one had lost: It works.

Rake doesn’t allow redefining task by default. So to override a rake task you have to delete the task and then define the new one. I opted for the manual remove task and redefine option.

Here’s my task in case anyone experiences similar problems:

We call rake using “rake -I /path/to/override.rb” in our build scripts and it works fine now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

namespace :db do
  namespace :test do
    remove_task :"db:test:prepare"
    desc 'prepares the db - mysql style'
    task :prepare do
    
      require 'yaml'

      config = YAML::load(File.read('config/database.yml'))

      devdb = config['development']['database']
      devpass = config['development']['password']
      devuser = config['development']['username']
      testdb = config['test']['database']
      testpass = config['test']['password']
      testuser = config['test']['username']

      puts "dumping development schema"
      puts %x{mysqldump -u #{devuser} --password=#{devpass} -d #{devdb} > dev.sql}
      puts "dropping test db"
      puts %x{mysqladmin -u #{testuser} --password=#{testpass} -f drop #{testdb}}
      puts "recreating testdb"
      puts %x{mysqladmin -u #{testuser} --password=#{testpass} create #{testdb}}
      puts "loading development schema into test db"
      puts %x{mysql -u #{testuser} --password=#{testpass} #{testdb} < dev.sql}

    end
  end
end

Popularity: 1% [?]

Written by hvolkmer

August 18th, 2008 at 12:58 pm

Posted in Deployment

Tagged with , , ,

Shaped Test Output

without comments

Last month I had to write some stuff that affected our whole application and therefore I had to run the full test suite several times a day and wait for it to finish every time to find out what the errors are that it displays.
The output in the shape of “…E..F..FE..” is usefull to get an overview of the amount of errors but unless you wait til the end you can’t get a clue as to where the error occurred.

That bugged me quite a while and finally I wrote a plugin that shapes the output much better (at least to my mind).

When you use the TestOutputShaper you get this:

AlbumTest:    ....F.F...
AlbumControllerTest:    FF......FF...
PictureTest:    FFFFFFFFFF

At that point – without knowing the actual error – you can stop the suite and run the particular test to see what is broken.

When you work with small test suites that may not be a big win, but when you have a lot of code and have it well covered by tests, it can be a huge time saver.
Especially when you test for valid html your test suite can take like hours.

Popularity: 1% [?]

Written by cweis

July 5th, 2008 at 12:29 pm