🥃

誰も教えてくれないテスト自動化が普及しない理由

に公開2

半地下のこのバーには不思議といつも、日本のIT業界の疲弊と倦怠感のような吹き溜まりが似合う。

Enterキーを叩く音が切なく響くような、鈍色の夜がまた凝りもせず繰り返し訪れる。今夜もまた、気を滅入らせる雨が降っている。

今夜もひとり、静かに飲んでいたら後輩がやってきた。珍しくスーツがよれている。


——先輩、あの

お前が言いたいことはだいたい分かる。聞いてやるから、まずはマスター、バーボンのオンザロックをダブルで。こいつにも同じものをやってくれ。ワイルドターキーにしてくれるか。

——相変わらずせっかちですね。いただきますよ。あの、実はテストの自動化がうまくいかなくて、上からはなんでそんなこともできないんだって言われてます。世の中もう、テストドリブン開発(TDD)だってなんだってググったらいくらでも出てくるのに、やる気あんのかって

そうだな、テストコードを書くってのは今や何も珍しいことじゃないな。中年の筋トレみたいなもんで、自慢にもならなくなって来たかもな。

——ただですね、最初は先輩格のメンバーが「これからはテスト自動化だ」って言ってたんですが、半年経っても結局浸透してなくて。エンジニアたちは結局、画面を手でテストしてます。バグも工数も減らせるって思ってたはずなんですけど、でもやれない理由がうまく言語化できなくて

案外とそれ、普通だぞ。

「テストコードを書けばいい」のか


外のアスファルトは雨に濡れて陰惨な色に染まっている。後輩の目の下には隈ができていて、その網膜にはEclipse IDEの狂ったパースペクティブが焼き付いているように錯覚させる。

俺はグラスを少し傾け、軽く喉を焼いた。灰皿を睨む。口唇の端を少し曲げて。


テスト自動化を導入しよう、やってみようって言い出すやつや、普通にできそうなもんだろって簡単に言ってる輩は、過度にシンプルにものを考えすぎている。そこが最初の間違いだ。

——間違い、ですか

Googleで軽く検索してみろ。テストコードを書くってこういうことだよ、っていう解説はいくつもあるが、単体完結するメソッドを実コードとして書き、そのメソッドにパラメータを渡して、返り値をアサートしたら、ほらできたね、で終わることが非常に多い。
足し算する関数を作って、2と3を渡したら5でassertみたいなやつな。

これは、なるほどと期待させてくれる。よくわかる。現実のアプリケーションでもこれやればいいな、って早合点する。

だがな、テストコードを書くこと自体は、実は話の半分以下だ。テストが「動く」ためには、いくつかの前提が揃っていないといけない。その前提を整えることが、テスト自動化の本当のコストだ。

——前提、というのは

一番デカいのがデータの問題だ。

テストを実行するためには、テスト用のデータが必要だ。当たり前のことに聞こえるが、重い。

例えば「ユーザ登録フローのテスト」を書くとする。登録できること、メールが送られること、重複登録がはじかれること。こういったケースを自動化したいとしよう。

——はい

まずテスト用のメールアドレスが要る。テスト用のメールサーバが要る。テストが終わったらデータをリセットする仕組みが要る。本番のデータと混ざらないように分離された環境が要る。環境が立ち上がるたびに、綺麗な初期状態に戻せることが保証されていなければテストコードの検証結果も毎回変わるからな。

ユーザ登録画面をテストするだけでも、所属コード、社員区分、社内のグレード、などのマスタデータを読みに行って、不整合があるかを見る必要もあるし、こうなってくると、テストを流す最初の時点である程度そろったデータベースが存在しないとまず最初からテストが書けない。

——……たしかに、それを揃えようとして詰まってました。テスト用のDBをどう用意するかとか、テストデータをどうシードするかとか、そこで時間がかかって

そこで止まるのは正常な反応だ。止まって当然だよ。これが最初の壁だな。

ここでそこそこ高度なアーキテクチャの設計が必要だ。誰でもできるような簡単な内容じゃなくなる。テスト用のデータベースを用意しても、複数のエンジニアが同時にテストすると衝突するし、久しぶりにアプリのテストを流すと「あれ、今DBどうなってたっけ?」から始まる。テストコードを流したあとに、DBを初期状態に手動で戻さないといけない、みたいになるとわけがわからなくなる。

時間依存データというやつ


マスターがカウンター越しに俺達の方をちらっと見た。表情は変わらないが、この男はいつも無言で俺達の会話を聞いていて、ときに冷たい炎のような鋭い視線を向けてくる。俺はギクリとしたことを悟られないようにしながら、汚い天井に目を逸らす。


さらにもう一段、厄介なのが時間依存のデータだ。

——時間依存?

例えば「今月の日付を取得して月次決算数値を取得するメソッド」のテストを書くとしよう。

今日の日付によってテストの結果が変わる。DBの状態が固定だと、月をまたぐとおそらく通らなくなる。テスト環境の時刻設定次第でもコケる。年度末に急に落ちだすテストが出てきたりな。

——あ、それ実際に聞いたことがあります。なんか年度またぎで突然CIが死んだって話

よくある話だ。日時の扱いはアプリケーション開発の中でも普通に難しく落とし穴も多い部類だが、テストと組み合わさるとさらにきつくなる。時間を固定する仕組み、モックを使った差し替え、テスト用の日時ファクトリ……こういうものを整備するだけで、それなりな作業だ。

——なるほど。道具を揃えるだけで時間がかかるわけですね

その通り。しかもその道具を揃える作業というのは、ビジネス的に価値が見えにくい。機能が増えるわけでもなく、バグが直るわけでもない。だから優先度が下がり続ける。

もう一つの壁:テストを書ける人材の話

インフラの話は一旦置く。もう一つ根本的な話をしてやろう。

テストコードを書くためには、三つのことを同時に高い水準で理解していないといけない

——三つ

一つは実装の知識。コードが何をしているか、どう動いているかを理解していること。

二つ目はバグやエラーへの経験。何がおかしい時に何が起きるか、どういうケースで壊れやすいかを知っていること。

三つ目はテスト設計の知識。境界値分析とか、同値分割とか、そういった考え方を理解したうえで何をテストすべきかを選べること。

——うーん、三つ全部ちゃんとできる人って……

そんなにいない。

普通にコーディングを覚えて、普通にバグに向き合いながらデバッグを覚えて、そこからさらに「テストとは何か」「何をどう確認するか」という世界を学んでいかないといけない。

テストを書ける人間というのは、そこまでキャッチアップしたエンジニアがさらに倍くらい勉強した結果としてやっと書けるようになる、という位置にある

——倍……

その倍の勉強を、業務の中でいつするんだ。締め切りがある。機能開発が優先される。バグ対応に追われている。そういう現場で、新しい概念体系を習得してテストを書き始める余裕はなかなかない。

——なるほど、突き詰めていくと、テスト自動化なんて当たり前でしょ・・・みたいな組織ってそんなに多くないかもしれませんね

ちなみに俺も、テストの自動化には強く興味を抱いてものにしてやろうと、凶暴に一時期取り組んだ。pythondjangoというフレームワークで作っているアプリケーションのテストを自動化したくて、以下の文書を15回くらい何度も読んだが「理解できた、使いこなせる」という実感は全然わかなかったし、今でも辛いな。

権威も歴史もあるWebアプリケーションフレームワークで、充実しているとも感じるが、そもそもの自動テストの難しさを感じる。

やれることからでいい

——じゃあ、うちのチームはどうすればいいんですか

まあ、正直知ったこっちゃない。俺も自分の人生で必死だし、明日の馬券の予想で忙しいしな。

だが、一つとても強く思うのはテスト自動化する=手動テストから卒業って盲信しなくてもいい、というのは言いたい。例えば、そのアプリの画面が30画面あるとして、その全ての画面をGETしたらHTTPステータスが200で返ってきたり、パラメータがおかしいときには404 Not Foundで返ってきたりすることを自動化して確認する、これだけでもまずはいいんじゃないか。

——しょぼすぎないです?

とはいえだよ。共通的なクラスとかをいじったときに、どこかの画面が動作すらしなくなった、ってことは意外と誰かがやらかすだろう。あらゆる画面が「最低限動いてだけはいる」ということがテストコードで確認できるようになれば、案外安心だよな。

——まあ確かに、ショボいバグだけでも意外と拾えそうですね。ちょっとコード変更するたびに全画面目視で見るわけにもいかないし。

コード化して確認できるテストは書けばいい。ただ、そこで悩まないといけないくらいなら、アナログなモンキーテストでいいって割り切って見てもいいと思う。なぜなら、どこまで書いても完全にテストをコード化することはできないからだ。色んな理由でな。

画面の表示の崩れなんていうのは結局目視だしな。AIでVision AIでやるとか、今後は手法も変わってくるかもだが。

AIコーディングアシスタント全盛の時代であることは、この辺の事情もどんどん変えていっているが、操る人間が何もわかってないと思い切り事故るのは承知の通りだ。AIに「このアプリ全体をテストするコードを書いて」なんていうと、何百テストも書いてくるが、これにも色んな落とし穴がある。

まあ、これ以上は長くなるから今度にしよう。マスター、俺とこいつにギムレットを。

長いお別れ

——少し、楽になった気がします。自分たちがさぼってたとか向いてないとかじゃなくて、本質的に結構難しいことをやろうとしてるってのがわかると、なんかこう、見方が変わってきました。

難しいのは本当だ。ただそれを言い訳にするのと、難しさを理解したうえで段階を踏むのは違う。ひとつひとつ解きほぐしていけばいいんじゃないか。フィリップ・マーロウみたいに気に入らないやつ全員ぶん殴ってれば生きていけるタフガイに、なれるわけでもないしな。

——わかりました。明日、チームで話してみます


そろそろ店を出ようかという頃に、雨は少し弱くなっていたが、止んだわけではない。濡れながら歩くのには慣れていて、俺の人生を囲い込む問題だって同じだ。解決なんてしない。問題と適当に付き合う方法が、なんとなくわかっていくだけだ。

Accenture Japan (有志)

Discussion

codesmithcodesmith

ハードボイルド(?)小説みたいで楽しく読めました!
自分はplaywrightでE2Eテスト書いてますが、データベース初期化とかテストケースごとの環境分離とか最後のデータ戻しとか、考えることがたくさんあって大変ですよね。
あと、周りの人が勉強熱心じゃないと自分だけ頑張っても意味ないなと感じます。
最近、アクセンチュアの人の記事がサジェストで出てくるのですが面白いです。テスト自動化小さいところから始めていきたいですね!

Inoue, TakuyaInoue, Takuya

コメントありがとうございます。ハードボイルド小説が好きなので、なぜかこうなってます。自分でも何やってるかよくわかってません。

アクセンチュア社員の投稿多くて盛り上がってますね。負けず嫌いが多いので、口には出しませんがお互い横目に見てる気がするw

2