LoginSignup
0
0

Rails環境でRakeタスク作成~テストまで

Posted at

モチベーション

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 が生成され、下記の内容が書き込まれます。

lib/tasks/test.rb
namespace :test do
  desc "TODO"
  task argument_parse: :environment do
  end
end

実利用に合わせてタスクの微修正とファイルのリネームを実施しました 😅

lib/tasks/argument_parse.rake
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] のようにハッシュの配列形式で設定できます。

lib/tasks/argument_parse.rake
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タスクを読み込めるようにします。

spec/rake_helper.rb
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 を読み込むことを忘れないようにしてください 🙏

spec/lib/tasks/argument_parse_spec.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を学ぶためのレポジトリ

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0