テストなんか書かなくて良い 僕の考えるサービス開発の肝
世の中は一周まわってエンジニアリングの手法に溢れている。 テストを書け、ドキュメントを書いて冗長化しろ、コミットはわかりやすく、コーディング規約が、安定性が─── でも、それって本質なんだろうか?
新規サービスを作る際に肝だと思っていることをまとめてみた。
おことわり
- 以下は少人数で"普通"のアプリやWebサービスを自社で新規開発するときのことを想定しています。大人数で重厚なソシャゲを作るとか、ガチガチの金融系サービスを作るとか、コンシューマーゲーム開発とか、個人で好きなものを作るとか、受託とかは全く想定していません。
- 基本的に一通り現場をこなした中級以上のエンジニア向けに書いています。
- アンチテーゼとして、ややキツめに断定する箇所が多いです、こういう意見もあるんだな程度に受け止めてください。
- 所属する団体の意見とかは一切関係ありません。
目次
ユーザーのことだけ考える
まず第一に、サービスの主役はユーザーであり、その他の話は大体些細だ。
「事業計画がどうこう」「偉い人が」「新しい技術を試したい」「マネタイズが」「綺麗なコードを」その大体が些細だ。
ターゲットするユーザーは誰なのか、そのユーザーのどんな課題が解決できるのか。そのサービスを使うと何が嬉しいのか。なんでそのサービスを使うのか、他のサービスじゃダメなのか。いつ起動するのか、なんで起動するのか。どうして離脱するのか。
ユーザーとサービスのことだけ考えたら、後のことは大体ついてくる。
企画が最も大事
サービス開発におけるプレイヤーの役割を「企画」「デザイナー」「エンジニア」などとざっくり分けるなら、企画(要件決め)が最も大事だ。企画がクソなものをどんなに上手く作ってもクソだからだ。
だから「俺はエンジニアだから言われたものを作る」とかは態度としてありえない。(スペシャリストなら別だけど、スペシャリストほどなぜかこういう態度はとらないものだ。)
サービスの成功を考えるなら立場によらず最も肝である企画フェーズからどんどん意見すべきで、開発工数的にコスパが合わないと思ったらどんどん代替案を提示すべきだ。
(話は逸れるけれど、設計にはドメイン知識と未来予知のスキルが必要で、「ここはきっとこう要件が変わる可能性があるからこうしとくか」だとかの温度感が掴めないとロクなものができない)
スピード
開発スピードより優先するものはほとんどない。
開発スピードと"品質"は両立できる。さっさと作って、触ってみてイケてないところを直して、リリースして数字や反応をみて直して─── サービス開発はその繰り返しだ。
リリースに関しても、今の時代"普通の"新規サービス開発に1年かかるとしたら遅すぎる。作っている間に競合が出るか市場が変化しているし、万一3年とか言い出すと市場が別世界になっている。そもそも当たってるサービスを数えた方が早いのだから、何年かけて作ったところで当たる保証なんて全く無い。
さらに言えば数年越しの事業計画なんて偉い人向けの説明以上の何者でもない。
※Appleの「ベスト新着App」とかもあるので最初はクソクオリティでも出すべきだとは言わない
開発スピードを妨げるものはとにかく排除すべきだ。
オナニーをやめよう
僕らが作っているのはサービスだ。どんなにコードが綺麗で、カバレッジが100%だろうと、使われないサービスだったらそれは残念ながら意味のないコードだ。
僕らがコミットするべきはサービスの"質"とユーザーへの価値であって、コードの綺麗さではない。全くない。 サービスはユーザーに価値を提供するものであって、エンジニアがオナニーする場所ではない。
オナニーチェックリスト
よく陥りがちなオナニーを項目化した。上から順にオナニー度が高い。
- カバレッジ100%を求める
- ドキュメントを完全に書こうとする
- テストコードの綺麗さや品質にやけにこだわる
- gitコミットの分割とコミットメッセージにこだわる
- 「やってみたいから」で言語やフレームワークを選ぶ
- サービスの安定性に過剰にこだわる
- サービスのバグのなさに過剰にこだわる
- コードの(見た目の)綺麗さにやけにこだわる
- コードレビューフローが整備されすぎている
ここからはやっておいた方が良いかなと思うもの。もちろん程度による。
- 命名にこだわる
- 効率化のためにテストを書く
カバレッジ100%を求める
テストというのはサービスの質を継続的に提供するために書くものだ。金を生んでいるサービスでないと基本的にコスパが悪い。多くのユーザーに使われているサービスならさておき、新しいプロダクトにおいてテストを書くモチベーションはかなり低い。
僕らは1日で新機能のプロトを作って、良ければリリースダメなら廃棄、そういう時間軸で生きている。リリースしても数字がダメなら機能ごと削除するなんて日常茶飯事だ。
「理由があればテストを書かなくてもいい」ではない、「理由がなければテストを書いてはいけない」くらいだ。過度なテストは書く時間の無駄なだけでなく、リファクタや機能追加の邪魔になるからだ(いちいちメソッド名変更などに対応しなければならないため)
もちろん開発効率化のためや、複雑な部分の必要なテストは書いてもいい。大事なのはその見極めだ。
そしてUI周りやリコメンドロジックなど、テストを書いても本質的なところは担保できない(または難しい)ところは沢山ある。人手による確認の質と効率を舐めてはいけない。
ドキュメントを完全に書こうとする
そもそも使われるかわからない(3ヶ月後あるかわからない)機能のドキュメントを完璧に書く必要なんてあるんだろうか? 大人数で開発をしているならわかるが、新規プロダクト開発を大人数でやること自体が悪手だ。
システム体系の伝達は残念ながら一子相伝だ。口頭で伝えて、コードを読んで、実際に書いてみて血肉にしていくものだ。少人数で開発するなら、実は口頭やホワイトボードでの伝達が、同期的という欠点があっても一番効率的だったりする。
そして少人数開発においては、冗長化よりも本来の目的であるスピードを重視すべきだ。
僕らにはドキュメントを完璧に書く時間も、読む時間も、メンテする時間も全く無い。(そしてこのメンテというのが本当に厄介なのだ)
ただし、APIインターフェース/データベーススキーマ/認証フロー 等は最低限書いておくのを勧める。ここで言ってるのは、内部の処理フローを完全に書くとかそういうレベルの話だ。ドキュメントは100点を求めようとすると途端に運用上のコスパが悪くなる。最低限書くべきことを決めて、50点でもいいから運用可能なレベルで妥協すること。
テストコードの綺麗さや品質にやけにこだわる
「テストの独立性が」「振る舞いで書く」とか色々だ。やってもいいけど時間はかけないでくれ。
gitコミットの分割とコミットメッセージにこだわる
とにかくコスパが悪い。そんなに古く遡られることも、コミットメッセージがないとわからないことも稀。コード読んでわからないような話ならソースにコメントとか残しておけば良い。書いた人に聞けば事足りることも多いし。
「やってみたいから」で言語やフレームワークを選ぶ
気持ちはわかるが家でやろう。要件を満たせて、チームが最適に能力を発揮できる言語を選ぶべきだ。勿論採用戦略なら別だが。個人の好みで技術選択をしてはいけない。例えばサーバーサイドの言語選択なら、運用面だけ考えてもこの記事くらい考えることは多いのだ。
ユーザーは何の言語で動いているかなんて興味が無い。
サービスの安定性に過剰にこだわる
これはあまり無い話だとは思うんだけど、神経質にダウンタイムや応答性等にこだわってしまう状態。技術のある大きめの企業だとある話だと思う。
勿論サービスの安定性は死ぬほど大事だし、サーバーエンジニアの腕の見せどころではある。けれどユーザーにとってサービスが凄い安定していることと、それを犠牲にしてでも機能改善のスピードが速いこと。どっちが今のフェーズにとって大事かは考えたほうが良いと思う。スピードと安定性はトレードオフなんだから。
(余談だけど僕はソシャゲは不安定で侘び石がもらえる方が嬉しい)
初めからスケールを気にしすぎてリリースが遅くなるのも少し考えものだ。そもそも2016年現在でも、スケールできるサーバーをきちんと組むのはまだ難しい。それを時間をかけずにできるエンジニアがいるのは稀有なケースだ。極論を言えば、完璧にスケールできるシステムなんて最初から考えるだけ皮算用で、サービスがある程度大きくなってきたら良いエンジニアが採用できるので、そこからシステムをリプレイスしてしまえば良い話だったりもする。だから初めの段階で過剰にこだわるよりも、そこそこにしてさっさと価値を届けることの方が事業としては大事かもしれない。どうせ新規事業なんてほとんど当たらないんだから。
サービスのバグのなさに過剰にこだわる
これも前項と似ている。
ユーザーにとってバグがほとんどないことと、少しバギーだけど機能改善のスピードが速いこと。どっちが今のフェーズにとって大事か。スピードとバグのなさはトレードオフだ。
成長したサービスにおいてバグは命取りだ。それだけで一瞬で何千ものユーザーが離脱したり、数億円レベルの損失が出たりする。けれどひよっこサービスがバグをそんなに恐れるべきだろうか。
バグのなさを品質と呼ぶことも嫌いだ。サービスの"品質"はあくまでユーザーに届ける価値で決まる。
(余談だけど僕はソシャゲはバグがあって侘び石がもらえる方が嬉しい)
コードの(見た目の)綺麗さにやけにこだわる
ここまで読んだ方ならだいたい意図は伝わると思う。勿論綺麗に、一貫して書かれているに越したことはないけど、それに時間を使いすぎるのは違う。そのコードをまるまる破棄することなんて日常茶飯事だからだ。
コードレビューフローが整備されすぎている
これも大体わかると思うので省略。
おわりに
念のため補足するけれど、僕が言いたいのは「テストもドキュメントも全く書かない、焼け野原みたいな現場で戦おう」では無い。そうじゃなくて、「どんな手法もメリット・デメリットがあるんだから、現場のフェーズやプロダクトに合わせて捨てられるものは捨てて、自己満足もやめて、コトに向かおう」ということだ。
だいたいのケースにおいて、技術は目的じゃなくて手段だ。オーバーエンジニアリングをやめて、楽しくユーザーに向き合おう。プロダクト開発はとても面白いのだから。