unit testの問題に取り組んでみた
自動unit testの問題点の一つに、「更新すると元に戻さなければならない」という課題がある。
DBを元に戻すコードやら更新する機能をテストコードで動かして・・・
それは本当に元に戻るんですかい?バグがあっても戻るんですかい?
この課題をクリアするためにORACLEで言うフラッシュリカバリが使えないか?と考えてみた。MYSQLにそんな便利な機能あったかな?そもそもORACLEのフラッシュリカバリってそんなに早くないぞ。。。unit testは平気で1万ケースとかになってしまうので高速に実行しなければ立ち向かえない。ORACLEのフラッシュリカバリってそんなに早くないし、MYSQLでやりたい。
結果
MYSQLで一瞬で元にもどして、テストを高速に無限に更新できるようにした。
もちろんDB部分だけなので、ファイルとか外部のデータは別です。
これが超便利。
自分の環境ではすこぶる便利につかえる。
ここから下は試行錯誤の中身
MYSQLってフラッシュリカバリないの?
ない。。。
探してもない。どこにもない。なんて不便な。。。。
無いなら作ればいいじゃない!!Replication Protocolでなんちゃってフラッシュリカバリ
Replication Protocolの記事でやった仕組みを使う。
考え方を説明する。
Replication Protocolで流れてるイベントを認識して、バックアップして逆順にもどせばいい。
準備として
unit testと会話するためのDB、TEABLEをつくる。このテーブルに向けてコマンドを投げるようにUPDATEする。
たとえば、UPDATE AAA SET COMMAND='バックアップ開始'; みたいな感じでdummy slaveに認識させる。こうすることで、会話が成立する。
コマンドのやりとりにredisとかmq使えそうだけど、Replication Protocolで繋がってるんだからコレを使った方が便利。
- unit testのSETUPメソッドで、バックアップ開始して!コマンドをなげる
- dummy slaveは更新記録モードに入る
- dummy slaveはポジティブアクノリッジ(ACK)的なOKを回答する
- unit testはACKを認識してテストを実行する(グリーンかどうかはどうでもいい)
- unit testのteardownで、リカバリして!コマンドを投げる
- dummy slaveは更新記録停止→記録を逆順に適応する(記録順に適応してももどらない)
- dummy slaveはACKを回答する
- unit testはACKを認識して一つのテストを終わる
Replication Protocolを使えば高速でこんなことができる。
unit testの確認を人間の目でやってるのであれば使えないが、1万ケースもあるのに人間が間に入ったら自動じゃないし。
感想
データの使い回しができるし、バグで間違っても戻るし、想定外の動作しても戻るしほんとに便利。
不便なところは、
・なんちゃってフラッシュリカバリがない環境に、あると思い込んでテストを実行してしまう
・同時実行ができない。共通の開発DB環境とかだったら使えない。