12/21 rspecの話 12/21 taca10
taca10.icon rpecの書き方は、再利用のある書き方。
共通化するところのrspecの書き方は?
参考資料
DHHはminitest派
fixtures vs FactoryBot
code: rb
def setup
@customer = customers(:two)
@customer_address = customer_addresses(:test_1)
@address_book_form = Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: true,
customer_id: 1
)
@address_book_form2 = Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: false,
customer_id: 1
)
@address_book_form3 = Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: false,
customer_id: @customer_address.customer_id
)
end
test "should be valid" do
assert @address_book_form.valid?
end
test "first_name" do
@address_book_form.first_name = ''
assert_not @address_book_form.valid?
@address_book_form.first_name = 'a' * 17
assert_not @address_book_form.valid?
end
test "last_name" do
@address_book_form.last_name = ''
assert_not @address_book_form.valid?
@address_book_form.last_name = 'a' * 17
assert_not @address_book_form.valid?
end
test "first_name_kana" do
@address_book_form.first_name_kana = ''
assert_not @address_book_form.valid?
@address_book_form.first_name_kana = 'a' * 17
assert_not @address_book_form.valid?
end
test "last_name_kana" do
@address_book_form.last_name_kana = ''
assert_not @address_book_form.valid?
@address_book_form.last_name_kana = 'a' * 17
assert_not @address_book_form.valid?
end
test "postcode" do
valid_postcodes.each do |valid_postcode|
@address_book_form.postcode = valid_postcode
assert @address_book_form.valid?
end
invalid_postcodes = '60088880', '600-08888', '77-99-00-1', 'aaaaaaa', '一二三四五六七'
invalid_postcodes.each do |invalid_postcode|
@address_book_form.postcode = invalid_postcode
assert_not @address_book_form.valid?, "#{invalid_postcode.inspect} should be invalid"
end
end
code:ruby
# RSpecだとletを使うことが多そう
let(:customer) { customers(:two) }
let(:customer_address) { customer_addresses(:test_1) }
let(:address_book_form) {
Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: true,
customer_id: 1
)
}
let(:address_book_form2) {
Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: false,
customer_id: 1
)
}
let(:address_book_form3) {
Ec::AddressBookForm.new(
address_book_id: '1',
name: 'お名前(名)お名前(姓)',
name_kana: 'おなまえ',
first_name: 'お名前(名)',
last_name: 'お名前(姓)',
first_name_kana: 'ふりがな(めい)',
last_name_kana: 'ふりがな(せい)',
postcode: '600-8888',
state: '京都府',
city: '京都市',
street_address: '21',
building: 'お野菜ビル0831室',
telephone: '075-200-9773',
is_default_address: false,
customer_id: customer_address.customer_id
)
}
# ↓RSpecっぽいやつ?
subject { address_book_form }
it { is_expected.to be_valid }
# RSpecではわりと細かくテストケースを分けがち?
# minitestではtest "first_name"でまとめて書いているテストケースを以下のように分割したり…
describe 'first_name' do
context 'when first_name is empty' do
before do
address_book_form.first_name = ''
end
it { is_expected.to be_invalid }
end
context 'when first_name is filled' do
before do
address_book_form.first_name = 'a' * 17
end
it { is_expected.to be_valid }
end
end
# ...
「間違ってるテストケースをeachで回して検証」というケースで議論になりましたyebis0942.icon
RSpecっぽくはない
が、べつにeachでも困らないのでは
mini testとrspecの違いは、TDDとBDDの設計方針の違いだったような?
テスト駆動開発の「付録C」に詳しかったような記憶があります。
できあがったテストで確認できることは同じだけれども、雑な説明ですがTDDはボトムアップ、BDDはトップダウンなイメージ。
ライブラリやフレームワークみたいなのはUnitっぽく書けるminitestのほうがもしかしたら相性がいいのかも?luccafort.icon
BDDとTDDの違いがちゃんとわかってないことが再認識できた luccafort.icon
Rails Developer Meetup 2019でのwillnetさん(前島さん)の「可読性の高いテストコード」についての発表資料
---
Clean Test Code Revised
https://youtu.be/P7cIfVl4T38
「テストコードをどう書くか」は音楽性の違いが生まれやすい印象があります。
関西Ruby会議06での伊藤さんの発表資料
---
RSpecとMinitest使うならどっち?
P18を見るとminitestでもrspecっぽく書くことができそう
最終結論→両方使ってからどっちがいいか考えようluccafort.icon(P76)