経緯
- github copilot と TDD が相性が良いという話を聞いて...
- 試しに ズンドコキヨシでやってみたという話です。
用意するもの
- github copilot が使える エディタ
- 自分は neovim を使いました。
- product code
- zundoko_kiyoshi.rb
- テストコード
- test_kiyoshi.rb
チャレンジ内容
- コードは極力打たない
- コメント文でgithub copilotを誘導する
問題文
- 「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」が出たら「キ・ヨ・シ!」と出力して終了
問題を分解する
- ランダムに ズンとドコを標準出力する
- 配列に出力予定を保存する
- 配列を 結合して ズンズンズンズンドコ が含んでいたら 真を返す
- ズンズンズンズンドコになるまで処理をloopする
- 条件が整ったら
- キヨシ! と出力する
- loop を抜ける
- 条件が整ったら
各個撃
- ランダムに ズンとドコを標準出力する
- 配列に出力予定を保存する
必要なライブラリを準備
- Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem "minitest"
gem "minitest-spec-context"
gem "minitest-reporters"
- bundle i
実行コード側を用意
- test_kiyoshi.rb
require './zundoko_kiyoshi'
require 'minitest/autorun'
require 'minitest/spec'
require 'minitest-spec-context'
require 'minitest/reporters'
Minitest::Reporters.use!
describe 'ズンドコキヨシ' do
before do
@ki = ZundokoKiyoshi.new
end
context 'ズンかドコをランダムに出す' do
it '@ki.zundokoがズンかドコか?' do
assert_includes %w(ズン ドコ), @ki.zundoko
end
end
end
REDを確認
- bundle exec ruby test_kiyoshi.rb
product code
- zundoko_kiyoshi.rb
class ZundokoKiyoshi
def initialize
@stock = []
end
# ランダムにズンとドコを返却する
# また、@stockに追加する
end
コメント文の後ろに挿入しようとしばらく待つと...
- あら、便利。下記のコードが出るのでタブキーを押してそのまま採用
class ZundokoKiyoshi
def initialize
@stock = []
end
# ランダムにズンとドコを返却する
# また、@stockに追加する
def zundoko
result = ["ズン", "ドコ"].sample
@stock << result
result
end
end
GREEN を確認
- bundle exec ruby test_kiyoshi.rb
- クリア: ランダムに ズンとドコを標準出力する
- リファクタリングを飛ばしてない?と思われるので一応
- ここまでコードが短いと「明白な実装」になってるので、飛ばしてます。
次の各個撃破
- 配列を 結合して ズンズンズンズンドコ が含んでいたら 真を返す
- test_kiyoshi.rb
require './zundoko_kiyoshi'
require 'minitest/autorun'
require 'minitest/spec'
require 'minitest-spec-context'
require 'minitest/reporters'
Minitest::Reporters.use!
describe 'ズンドコキヨシ' do
before do
@ki = ZundokoKiyoshi.new
end
context 'ズンかドコをランダムに出す' do
it '@ki.zundokoがズンかドコか?' do
assert_includes %w(ズン ドコ), @ki.zundoko
end
end
context 'ズンズンズンズンドコ を評価' do
it '@stockにズンズンズンズンドコ が含んでいたら 真を返す' do
@ki.stock = %w(ズン ズン ズン ズン ドコ)
assert @ki.kiyoshi?
end
end
end
RED を確認
- bundle exec ruby test_kiyoshi.rb
product code に追加
- コメント文まで書く
class ZundokoKiyoshi
def initialize
@stock = []
end
attr_accessor :stock
# ランダムにズンとドコを返却する
# また、@stockに追加する
def zundoko
result = ["ズン", "ドコ"].sample
@stock << result
result
end
# @stockをjoinして ズンズンズンズンドコを含んだら
# trueを返却する
end
コメント文の後に出るかな?
- 候補が出るので、同じようにタブキーを押して採用
class ZundokoKiyoshi
def initialize
@stock = []
end
attr_accessor :stock
# ランダムにズンとドコを返却する
# また、@stockに追加する
def zundoko
result = ["ズン", "ドコ"].sample
@stock << result
result
end
# @stockをjoinして ズンズンズンズンドコを含んだら
# trueを返却する
def kiyoshi?
@stock.join.include?("ズンズンズンズンドコ")
end
end
GREEN を確認
- bundle exec ruby test_kiyoshi.rb
条件が整ったら キヨシ! と出力する
- 疑似コード通りに整えるだけ
require './zundoko_kiyoshi'
require 'minitest/autorun'
require 'minitest/spec'
require 'minitest-spec-context'
require 'minitest/reporters'
Minitest::Reporters.use!
describe 'ズンドコキヨシ' do
before do
@ki = ZundokoKiyoshi.new
end
context 'ズンかドコをランダムに出す' do
it '@ki.zundokoがズンかドコか?' do
assert_includes %w(ズン ドコ), @ki.zundoko
end
end
context 'ズンズンズンズンドコ を評価' do
it '@stockにズンズンズンズンドコ が含んでいたら 真を返す' do
@ki.stock = %w(ズン ズン ズン ズン ドコ)
assert @ki.kiyoshi?
end
end
context 'ズンズンズンズンドコになったらキ・ヨ・シ!' do
it '条件が整ったらキ・ヨ・シ!と出力しloopを抜ける' do
loop do
puts @ki.zundoko
if @ki.kiyoshi?
puts 'キ・ヨ・シ!'
break
end
end
end
end
end
結論
- うまくいった
- メソッドが短くなればなるほど...リファクタリングがなくなる
- 自動生成で十分行けちゃう