Redmineのpluginを開発した際にrspecを使って自動テストがしたい

  • 0
    Like
  • 0
    Comment

    結構苦戦したので、次回は苦戦しないようにここにメモしておく なお、各バージョンなどは以下

    • OS(Windows7)
    • ruby (2.0.0p648)
    • rails (4.2.7.1)
    • rspec-rails (3.5.2)
    • poltergeist (1.12.0)
    • database_cleaner (1.5.3)
    • capybara (2.11.0)
    • launchy (2.4.3)

    環境構築

    参考にしたサイト様達

    http://ylgbk.hatenablog.com/entry/2015/02/16/120000

    Redmine pluginの開発について当初自分が疑問に思ってたことに回答 ほか

    ※ほかは後ほど本文中に記載

    フォルダ構成

    プラグイン名/spec/spec_helper.rbとかもなかったので作成

    redmine/
    ├(略)
    ├plugins
    │ ├(プラグイン名)
    │ ├(略)
    │ ├spec/
    │ │ ├factories/
    │ │ ├models/
    │ │ ├views/
    │ │ └spec_helper.rb
    │ └ (略)
    ├spec
    │ └spec_helper.rb
    └(略)

    各種ファイルの内容

    gemfile
    group :development, :test do
        gem 'pry-rails'  
        gem 'pry-doc'    
        gem 'pry-byebug'
        gem 'pry-stack_explorer'
        gem 'rspec-rails'
        gem 'factory_girl_rails'
    end
    
    group :test do
        gem 'minitest'
        gem 'rails-dom-testing'
        gem 'mocha'
        gem 'simplecov'
        gem 'capybara'
        gem 'poltergeist'
        gem 'selenium-webdriver'
        gem 'database_cleaner'
        gem 'faker'
        gem 'database_cleaner'
        gem 'launchy'
        gem 'timecop'
    end
    

    ↑TODO:そもそも、試行錯誤した後なので使っていないのも結構ありそう

    redmine/spec_helper.rb
    ENV['RAILS_ENV'] ||= 'test'
    require File.expand_path('../../config/environment', __FILE__)
    require 'rspec/rails'
    
    Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
    
    ActiveRecord::Migration.maintain_test_schema!
    
    RSpec.configure do |config|
        config.fixture_path = "#{::Rails.root}/spec/fixtures"
        config.use_transactional_fixtures = true
        config.infer_base_class_for_anonymous_controllers = false
        config.order = 'random'
        RSpec.configure do |config|
            config.include FactoryGirl::Syntax::Methods
        end
    end
    

    ↑ここはほぼ手を入れてないはず?

    redmine/plugins/(プラグイン名)/spec/spec_helper.rb
    require File.expand_path(File.dirname(__FILE__) + '/../../../spec/spec_helper')
    require File.expand_path('../../../../config/environment', __FILE__)
    require 'rspec/rails'
    require 'capybara'
    require 'capybara/rspec'
    require 'capybara/poltergeist'
    require 'selenium-webdriver'
    
    Capybara.javascript_driver = :poltergeist
    Capybara.current_driver = Capybara.javascript_driver
    
    RSpec.configure do |config|
        config.use_transactional_fixtures = false
        config.infer_spec_type_from_file_location!
        config.include FactoryGirl::Syntax::Methods
        FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
        FactoryGirl.find_definitions
        config.before(:all) do
            FactoryGirl.reload
        end
    
        config.before(:each) do
          DatabaseCleaner.strategy = :truncation
        end
    
        config.before(:each) do
          DatabaseCleaner.start
        end
    
        config.after(:each) do
          DatabaseCleaner.clean
        end
    end
    Capybara.register_driver :poltergeist do |app|
        Capybara::Poltergeist::Driver.new(app, inspector: true)
    end
    

    ↑TODO:ここも明らかに使ってない設定とか残っていそうなので後で整理する

    実行

    後は普段と同じように(プラグイン名)/spec/models/hogehoge_spec.rbなどを作成して実行する。

    ちな実行コマンドは下記

    bundle exec rspec ./pulgins/(プラグイン名)/spec/models/hogehoge_spec.rb

    ※一括実行する場合はmodels~は省略

    躓いた問題達

    1.
    問題:jsのテストができない(js: trueオプションをつけると動作がおかしくなる)
    原因:DriverがそもそもJSに対応してなかった
    参考:Capybaraを使う際に知っておきたいこと

    2.
    問題:SQLite3::BusyExceptionがおきる
    原因:database_cleanerで以下設定を行っていたから?(なぜか要調査)
    DatabaseCleaner.strategy = :transaction
    transaction→truncationにすると動作は遅いがなぜか動く
    と思ったらそれらしい記事があった↓
    参考:http://stackoverflow.com/questions/29387097/capybara-and-chrome-driver-sqlite3busyexception-database-is-locked

    3.
    問題:spec実行時にpoltergeistのドライバーがないって言われる
    原因:spec_helperにrequireを書いてなかった
    phantomjsを環境変数のパスに追加していなかった
    参考:初心者大歓迎!RSpec 3でドラッグアンドドロップ機能をテストする方法(スクリーンキャスト付き)

    その他

    viewのテストでログインしたい

    Redmineではユーザーのパスワードは暗号化されているため、テスト時に強引に上書きしてやった。

    test_view_spec.rb
    let!(:user) { FactoryGirl.create(:test_admin) }
    before do
        visit home_path
        find('.login').click
        @user = User.find_by_login(user.login)
        User.find_by_login(user.login).update_attribute(:password, 'password')
        User.find_by_login(user.login).update_attribute(:must_change_passwd, false)
        fill_in 'password', with: 'password'
        fill_in 'username', with: @user.login
        find('[name=login]').click
    end
    

    一応国際化はしたけど、要件が日本語のみなので日本語固定でテストする

    デフォルトの言語はSettingに保存されているみたいなので、対象のレコードを作成。

    Setting.create(name: 'default_language', value: 'ja')

    ...普通にI18n使えばいいじゃん...

    ちな参考↓

    http://easyramble.com/rspec-tests-with-i18n.html

    Viewのテスト中でどんな画面が開かれているのかを確認したい(度忘れしてた)

    save_and_open_pageを使いましょう

    ふりかえり

    ツッコミどころが多そうなのはご愛嬌...