เซตอัพ RSpec บน Rails Engine

ในบทความนี้ผมจะพูดต่อถึงการใช้ Rspec เพื่อรัน Test กับ Rails Engine ของเรา ซึ่งจะมีวิธีการ setup ที่แตกต่างจากแอพหลักอยู่พอควร เนื้อหาในบทความจะต่อเนื่องจากครั้งที่แล้วที่พูดถึงเรื่อง การใช้ Webpack บน Rails Engine ซึ่งจะเห็นว่าเราสามารถรัน webpacker จากฝั่งแอพหลักเพื่อคอมไพล์ไฟล์ javascript ของฝั่ง engine ได้

เราไปดูกันเลยดีกว่าว่ามีขั้นตอนอย่างไร

เริ่มเซตอัพ RSpec สำหรับ Rails Engine

ขั้นตอนการ Setup Rspec เพื่อใช้งานบน Rails Engine สำหรับคนที่มี engine เดิมอยู่แล้ว และต้องการจะเพิ่ม rspec เข้าไป ให้ทำข้อ 1-2 ก่อน

1) เปลี่ยนชื่อ folder เดิม จาก /<engine_name>/test ให้เป็น /<engine_name>/spec

2) แก้ไขไฟล์ bin/rails และ Rakefile ที่อยู่ใน root ไดเรกทอรี่ของ engine โดยเปลี่ยนบรรทัดที่มี APP_PATH ตามนี้

ที่ไฟล์ /bin/rails

APP_PATH = File.expand_path('../spec/dummy/config/application', __dir__)

ที่ไฟล์ /Rakefile

APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)

3) ระบุว่า rspec-rails เป็น gem ที่เราต้องการใช้กับ engine โดยโดยใส่โค้ดบรรทัดนี้ลงไปในไฟล์ <engine_name>.gemspec

s.add_dependency "rspec-rails", "~> 3.7"

แล้วรัน bundle install ที่ไดเรกทอรี่ /<engine_name>

4) บอก engine ว่าเราจะใช้ rspec สำหรับ Test โดยเพิ่มโค้ดด้านล่างนี้ในไฟล์ /<engine_name>/lib/<engine_name>/engine.rb

module EngineRspec
 class Engine < ::Rails::Engine
   isolate_namespace EngineRspec
           
    config.generators do |g|
    g.test_framework :rspec
    end
 end
end

5) install ไฟล์สำหรับ rspec โดยพิมพ์คำสั่งด้านล่างที่ root ไดเรกทอรี่ของ engine

$ ruby bin/rails g rspec:install

เราจะเห็นจาก console window ว่ามีไฟล์ถูกสร้างขึนตามนี้

create .rspec
exist spec
create spec/spec_helper.rb
create spec/rails_helper.rb

6) แก้ไขบรรทัดที่ 4 ของไฟล์ /<engine_name>/spec/rails_helper.rb ให้เป็น

require File.expand_path('../dummy/config/environment', __FILE__)

7) ตอนนี้ถือว่าเราเตรียมทุกอย่างพร้อมสำหรับ Rspec แล้ว ทีนี้ลองเขียน spec แรก โดยสร้างไฟล์ /<engine_name>/spec/engine_spec/first_spec.rb ตามนี้

require "rails_helper"

RSpec.describe "First Test Spec in Engine", type: :model do
    it "should pass silly test" do
           expect([1,2,3]).to include(1)
    end
end

จากนั้นรัน test ด้วยคำสั่งต่อไปนี้ที่ root ไดเรกทอรี่ของ engine
```console
$ bundle exec rspec                

จะเห็นว่าเรารัน rspec ได้แล้ว ซึ่งได้ผลลัพธ์ประมาณนี้

.

Finished in 0.01004 seconds (files took 3.2 seconds to load)
1 example, 0 failures

แถม Optional Setup

8) ทำการเปิดใช้การรัน Rspec แบบ focus คือการกำหนดให้รัน example เคสเฉพาะเคสที่เราสนใจเท่านั้น ทำให้เราไม่ต้องรัน example ทั้งหมด ซึ่งสามารถประหยัดเวลาในการ test ไปได้เยอะทีเดียว การเปิดใช้ทำได้โดย เปิดไฟล์ /spec/spec_helper.rb แล้วทำการปลด comment แถวๆ บรรทัดที่ 54 ตามโค้ดด้านล่าง

config.filter_run_when_matching :focus

9) เราสามารถ setup FactoryBot ซึ่งเป็น gem ที่เอาไว้สร้าง “test factory” หรืออ็อบเจกต์ตัวอย่างของโมเดลที่เราต้องการทดสอบ ซึ่ง FactoryBot นั้นนิยมเอามาใช้แทน Test Figure ที่เป็นรูปแบบของการสร้างอ็อบเจกต์ตัวอย่างที่มีมาพร้อมกับ Rails วิธีการ setup FactoryBot ทำได้ดังนี้

ระบุว่า engine ของเราต้องการใช้ FactoryBot เป็น dependency ลงในไฟล์ /<engine_name>.gemspec

s.add_dependency "factory_bot_rails"

แล้วรันคำสั่ง

$ bundle install

ไปที่ไฟล์ /lib/<engine_name>/engine.rb แล้วแก้ไขโค้ดด้านล่างเพื่อบอก Rails Engine ว่าทุกครั้งที่เราจะสร้างโมเดลขึ้นมาใหม่ต่อจากนี้ ให้ใช้ FactoryBot แทนที่ Test Figure และให้นำไฟล์ factory ที่จะสร้างขึ้นมาไปไว้ที่ไดเรกทอรี่ /spec/factories

เข้าไปในไฟล์ /spec/rails_helper.rb จากนั้นเอา comment อยู่หน้าโค้ดบรรทัดข้างล่างนี้ออก (แถวๆ บรรทัดที่ 23)

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

จากนั้น require ‘factory_bot_rails’ โดยเพิ่มโค้ดบรรทัดนี้ต่อจากบรรทัด require ‘rspec/rails’ ที่อยู่บริเวณต้นๆ ของไฟล์

require factory_bot_rails

เสร็จแล้ว สร้างไฟล์ /spec/support/factory_bot.rb แล้วใส่โค้ดด้านล่าง เพื่อ include โมดูลเมธอดของ FactoryBot เวลาเราเรียกใช้เมธอดจะได้ไม่ต้องพิมพ์ชื่อยาวๆ

RSpec.configure do |config|
 config.include FactoryBot::Syntax::Methods
end

ตอนนี้เราน่าจะสามารถใช้ FactoryBot ได้แล้ว ซึ่งสามารถลองสร้าง factory แล้วเรียกขึ้นมาใช้ตอนรัน example ของ Rspec โดยดูรายละเอียดวิธีสร้างและใช้ factory ได้จาก https://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Defining_factories

สรุป

เราสามารถนำ Rspec มาใช้กับ Rails Engine แต่ก็จะต้องทำการ setup เพิ่มเติมนิดหน่อย เพราะเรื่องของ path ที่โหลด rspec จะต่างจากของแอพ Rails ปกติ ซึ่งมีไฟล์ที่เกี่ยวข้องอยู่หลายไฟล์ตามที่เขียนมาในบทความนี้

แชร์โพสได้จากลิ้งด้านล่าง ขอบคุณครับ