Tuesday, June 4, 2013

Running slow test (with rake)

Situation: I have a test file that takes a really long time to run. What do I do?

Propose solution: Don't test the file? Of course not! The test file is there to ensure I didn't break anything.  If I don't test it, how do I know my code is working as intended? How do I know the new code didn't break existing code? 

Real solution: Separate out the tests. 

Example: I am working on a TicTacToe game. The game has a computer player that uses minimax to compute the next step. This algorithm takes a long time to calculate when the board has a lot of empty squares. So whenever I add new code and run rspec, it takes a really long time to run, even though the new code has nothing to do with the computer logic. So what I really want is simple command to:
  1. run all test
  2. run slow test
  3. run all test excluding the slow test
If I separated it out like that, I can run most of my test regularly and the slow one before I check in or when I actually change the file. How do I do this? Use Rake. 

Rake is a build tool created by Jim Weirich for Ruby. There are many articles on Rake, including Martin Fowler's detailed explanation. Most didn't really explained what I wanted, so I asked other apprentices for help. Thankful Taka is knowledgable on the subject and offered to help :)

Steps:

  1. Install rake "gem install rake"
  2. Create a file in your project directory call "Rakefile"
  3. Add the tasks to your rake file. This is what my rake file looks like: 
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:default)

RSpec::Core::RakeTask.new(:slow_test) do |t|
  t.rspec_opts = "--tag slow_test"
end

RSpec::Core::RakeTask.new(:test) do |t|
  t.rspec_opts = "--tag ~slow_test"
end
What the file say?
  • Line 3 says, run all tests as the default. 
    • Command: rake
  • Line 5 created a new task called "slow_test" which runs all the test with the tag "slow test" (more on this later). Note that you specify the task name with ":task_name".
    • Command: rake slow_test
  • Line 9 created a new task called "test" which runs all the test excluding the one with the tag "slow_test".
    • Command: rake test
In addition, I can also create a command to run my game. Normally, I would type in "ruby bin/tictactoe", but I can make a shorter command using rake. I called my task play, so I can just type "rake play" and it will start the game for me. Cool eh?
task :play do
  ruby "bin/tic_tac_toe"
end

Tagging test files

I will need to do more research on the topic, but for this rake file to work, I need to add this to my computer test file.
Normal
describe TicTacToe::Player::Computer do
end
Tagged.
Note Taka added a comma after the class under test, then the tag.
describe TicTacToe::Player::Computer, :slow_test => true do
end

0 comments:

Post a Comment