モチベーション
Rakeタスクを作成に伴い、どのように利用するかを知ること!
Rakeタスクって?
Rake ファイルにおける基本単位です。タスクは名前と、事前タスクと、実行するアクションのリストを持ちます。
RakeというRubyで書かれたビルドツール利用される基本単位のことらしいです。
***.rake
というファイル名でRubyスクリプトを実装し、Rakeタスクとして実行することができます。
ユースケース
下記のユースケースが考えられます。
- Railsのアプリケーションコードを利用した、一回だけ実施したい処理
- バッチなどの定期実行処理
利用方法
namespace:task_name
の形式で呼び出すことができます。
# 引数なしの呼び出し方
bin/rake 'test:argument_parse'
# 引数ありの呼び出し方
bin/rake 'test:argument_parse[this,is,test,desu]'
引数と関数の間にスペースを入れるとスペースまでタスク名として判断されるため
「そんなタスク知らないよ!」ってエラーが出ます。
rake aborted!
Don't know how to build task 'test:argument_parse ' (See the list of available tasks with `rake --tasks`)
タスクの作り方
Railsコマンドを実行すると lib/tasks
配下にrakeタスクファイルが作成されます。
rails g task test argument_parse
lib/tasks/test.rb
が生成され、下記の内容が書き込まれます。
namespace :test do
desc "TODO"
task argument_parse: :environment do
end
end
実利用に合わせてタスクの微修正とファイルのリネームを実施しました 😅
namespace :test do
# desc はrakeタスクで何をするかを説明する部分
desc "TODO"
# :environment でRailsのアプリケーションコードを読み込んでいる
# See https://qiita.com/FumiyaShibusawa/items/11035fc640bb36a615ad
task argument_parse: :environment do
p "This is argument_parse task!"
end
end
rake --tasks
で作成したRakeタスクが読み込まれているかを確認して、タスクを実施してみましょう!
rake --tasks
rake action_mailbox:ingress:exim # Relay an inbound email from Exim to Action Mailbox (URL and INGRESS_PASSWORD required)
... 省略 ...
rake test:argument_parse # 引数の挙動確認用rakeタスク
... 省略 ...
rake test:argument_parse
"This is argument_parse task!"
引数を含めたタスクを設定するには
[:first, :second]
のようにハッシュの配列形式で設定できます。
namespace :test do
desc "引数の挙動確認用rakeタスク"
task "argument_parse", [:first, :second] => :environment do |_task, args|
# argsは Rake::TaskArguments で取得でき、設定したシンボルで値を「文字列」として取得できる
first = args[:first]
second = args[:second]
# シンボルで指定していない余剰の引数については extras で配列形式で取得できる
extra = args.extras
p "first: #{first}, second: #{second}, extra: #{extra}"
end
end
bin/rake 'test:argument_parse[this,is,test,desu]'
"first: this, second: is, extra: [\"test\", \"desu\"]"
テスト(RSpec)の仕方
初期のRSpecの初期設定ではRakeタスクの読み込みが実施されないため、「タスク定義が見つからないよ」エラーが出ます。
Failure/Error: subject(:argument_parse){ Rake.application['test:argument_parse'] }
RuntimeError:
Don't know how to build task 'test:argument_parse' (See the list of available tasks with `rake --tasks`)
そのため、Rakeタスクを読み込むためにヘルパーを作成してSpecファイルから読み込んであげるようにします。
Rakeヘルパー関数
RailsでRakeタスクをシンプルかつ効果的にテストする手法 のヘルパー関数を利用させていただき、実際のRailsアプリケーションと同様の手順でRSpecでもRakeタスクを読み込めるようにします。
require 'rake'
# See https://qiita.com/aeroastro/items/c97bd26ce8b8818b6bed
RSpec.configure do |config|
config.before(:suite) do
Rails.application.load_tasks # Load all the tasks just as Rails does (`load 'Rakefile'` is another simple way)
end
config.before(:each) do
Rake.application.tasks.each(&:reenable) # Remove persistency between examples
end
end
RSpecの実行
RSpecで利用する場合は、作成した rake_helper.rb
を読み込むことを忘れないようにしてください 🙏
# frozen_string_literal: true
require 'rails_helper'
require 'rake_helper'
RSpec.describe 'test:argument_parse', type: :task do
subject(:argument_parse){ Rake.application['test:argument_parse'] }
context "引数が1つ与えられたとき" do
# extras を利用する都合上、Rake::TaskArgumentsを利用してパラメータを設定する
# See https://docs.ruby-lang.org/ja/latest/class/Rake=3a=3aTaskArguments.html
let(:args) { Rake::TaskArguments.new([:first], [1]) }
it 'firstに設定した値が標準出力に表示される' do
expected = "\"first: 1, second: , extra: []\"\n"
expect { argument_parse.execute(args) }.to output(expected).to_stdout
end
end
context "引数が2つ与えられたとき" do
let(:args) { Rake::TaskArguments.new([:first, :second], [1, 2]) }
it 'first, secondに設定した値が標準出力に表示される' do
expected = "\"first: 1, second: 2, extra: []\"\n"
expect { argument_parse.execute(args) }.to output(expected).to_stdout
end
end
context "引数が2つを超えて与えられたとき" do
let(:args) { Rake::TaskArguments.new([:first, :second], [1, 2, 3, 4]) }
it 'first, secondに設定した値、余剰の引数が標準出力に表示される' do
expected = "\"first: 1, second: 2, extra: [3, 4]\"\n"
expect { argument_parse.execute(args) }.to output(expected).to_stdout
end
end
end
レポジトリ
GitHub - watame/rake_test: rakeを学ぶためのレポジトリ
参考記事