Using Testjour with Capistrano
I created the following capistrano recipe excerpt and loaded it in our main deploy file. We have our deploy separated between staging and production so naturally adding a testing deploy made sense. We can now run all our features in a distributed fashion using only:
cap testing deploy
To run with migrations we do:
cap testing deploy -s migrations=true
To run with migrations and less than a full test suite we do:
cap testing deploy -s migrations=true -s features=./features/subfeatures
This recipe excerpt requires a config/testjour.yml configuration file in the following format:
config/testjour.yml
master: testmaster.domain.tld
slaves: testslave1.domain.tld,testslave2.domain.tld,testslave3.domain.tld,testslave4.domain.tld,testslave5.domain.tld,testslave6.domain.tld,testslave7.domain.tld
repository: "ssh://user@testmaster.domain.tld/user/myapp.git"
master_user: user
root_path: /user
dbusername: masterdbusername
dbpassword: masterdbpassword
lib/testjour.rb
TestJour_config=Hash.new
TestJour_config.merge! YAML.load_file("config/testjour.yml") if File.exists?("config/testjour.yml")
task :testing do
role :app, testjour_master
role :web, testjour_master
role :db, testjour_master, :primary => true
set :application, "myapp"
set :repository, TestJour_config["repository"]
set :rails_env, 'test'
set :branch, get_branch
set :user, TestJour_config["master_user"]
set :deploy_to, "#{TestJour_config["root_path"]}/#{application}"
before :deploy, :role => :app do
`git push testjour #{get_branch}`
end
after :deploy, :role => :app do
begin
if migrations
run "cd #{current_path}; rake db:migrate:reset"
run "cd #{current_path}; mysqldump#{TestJour_config["dbusername"] ? " -u " + TestJour_config["dbusername"] : ""}#{TestJour_config["dbpassword"] ? " --password=" + TestJour_config["dbpassword"] : ""} -n -d myapp_development > #{shared_path}/development_structure.sql"
end
rescue
end
run "/bin/cp #{shared_path}/development_structure.sql #{release_path}/db/development_structure.sql"
run "cd #{current_path}; testjour #{get_slaves} --max-local-slaves=1 --create-mysql-db --mysql-db-name=myapp_test #{get_features}"
end
end
def get_branch
`git branch` =~ /^\*.(.*)/
$1
end
def testjour_master
TestJour_config["master"]
end
def get_features
begin
features
rescue
"./features"
end
end
def get_slaves
TestJour_config["slaves"].split(',').map{slave "--on=testjour://#{slave}/#{TestJour_config['root_path']}/#{application}/current/ "}.to_s.strip if TestJour_config["slaves"]
end
Hello,
ReplyDeleteThank you for this detailed write-up - I was just starting to look into testjour myself, and was about to have to do the same thing - figure out manually how it works.
Can you say a word or two about how it divides your features across the available slaves so that different slaves don't end up running the same features? How effective is it at doing this?
Thanks,
Avram