テストとデプロイ開発プラクティスとしてこんにちは、CTOの冨田です。以前の記事ではkippのチームについて理念をベースに方針や取り組みを説明しました。新しいメンバーを探すなかで、この記事に魅力を感じてくださった方が多数いらっしゃいました。一方で抽象的、長期的な内容にとどまっていて、実際の働き方がイメージしにくいという感触も得ました。この記事では今まさに実践しているワークフローを紹介します。開発チームメンバーの視点でお話ししますが、他のチームに興味がある方にも参考になるでしょう。先述の記事とあわせて読むと、理念と実践がペアになり理解しやすいです。複数のチームがどのようにコラボレートするのか、開発チームのメンバーがどう作業を進めているか伝われば幸いです。チームの構成kippには開発に携わるチームが開発チームの他に2つあります。この他に運用担当、コーポレート業務のチームがあります。開発チーム:サービスの開発、運用を担当します。正社員の開発チームメンバーは輪番でオンコールも担当します。事業開発チーム:社外のパートナーと共に新プロダクトや改善の企画をします。プロダクトマネジメントチーム:全サービスの妥当性・整合性に対して責任を持ちます。仕様の調整から受け入れテストまで開発の全ライフサイクルを管理します。事業開発チームとプロダクトマネジメントチームはもともとビジネスチームとしてひとつに数えられていました。人数が増えるに従い開発チームの役割をすこし分担したプロダクトマネジメントチームと、新企画に専念する事業開発チームが出来ました。すべての開発のスタート地点:提起いかなるプロダクトも改善も、課題や要望があって始まります。新規プロダクトの立ち上げであればプロダクトで実現したい内容が最初にあります。改善要望であれば現在のプロダクトで困っている状況と実現したい希望があります。リファクタリングでも、現在のコードの課題点と、こう変えたらこの実装がスムーズになるというビジョンがあります。これら開発を始める動機を示すことをまとめて提起と呼びます。リファクタリングやパフォーマンス改善を別として、提起は開発チーム外からやってきます。社内の他チームの場合も顧客企業のスタッフの場合も、エンドユーザの場合もあります。私達はこれらの意見に耳を傾けるべきですが、一から十まですべて鵜呑みにすべきではありません。提案者は業務のプロフェッショナルであってもシステム設計や実装のプロではありません。注意深く要望を聴取すると、当初案より包括的で効率の良い案が出てくることがよくあります。kippでは提案者の要望を理解すること、要望を実現するとどう変わるのか理解してもらうことに時間を使っています。規模の大きい変更や新機能の提案であればドキュメントにまとめ、議論の全体が一箇所でわかるようにします。(PSD)と呼びます。PSDは設計や実装でも提起の原点を振り返る資料として有用です。このステップは事業開発チームが中心となって進行します。関係者との調整と並行して、法的な確認やパートナーの選定も行います。ビジネス案を多数の金融関連法に照らし、弁護士とともに懸念点を潰します。カードの印刷や決済ネットワークへの接続といった自社で賄えない機能を提供してくれるパートナーと交渉し、タイムスコープや収益性を確認します。小規模な困りごとにはプロダクトマネジメントチームが対応します。サービスを使っているうちに要件と現実が乖離してきたり、要件定義時に想定していなかったケースが出てきます。エンドユーザ、利用社、オペレーション担当者から広くフィードバックを受け、疑問や希望を改善提案に繋げます。事業開発チームが新しい価値を生み出す動力源であり、プロダクトマネジメントチームが既存の価値を高める精錬機であると対比できます。Service)として提供しています。個々の利用社が別々のシステムを使うのではなく、ひとつのシステムの個々の側面を利用しています。提起された課題はその関係者のためだけに実装するのではなく、BaaS全体の資産価値を高めるために実装します。機能が提案者に提供されるのはもちろん、将来の利用社に対しても提供でき、kippのシステム、会社としての価値が高まります。この目的のために、提起内容をBaaSの文脈に置き直す必要があります。前提として既存の仕様、実装と矛盾しないことが求められます。同一のカラムを異なる利用シーンで別々の解釈をしてしまうと今後全ての実装が分岐を意識しなければなりません。似ているが実は異なる概念も実装ミスの遠因になります。負債になりうる仕様は実装前に回避します。BaaSの発展性に寄与するかという観点から検討を加えます。特定の業務フローのためだけに実装してしまうと、業務内容は同じでも手順が違うシーンで再利用できません。フロントエンドの画面ステップなどに合わせず、BaaSとして妥当なように実装します。この観点を取り入れた事例のひとつが過去ご紹介したGraphQLの活用です。要件定義はプロダクトマネジメントチームが中心になります。提起内容をBaaSの文脈で評価した結果、一部を変更してもらうこともあります。したがって要件定義作業は提起作業に一部食い込む形で行い、手戻りを避けます。同様に次の設計ステップも要件定義や提起に食い込む形で行います。事業開発チーム、開発チームと相談しながら進行します。(BRD)にまとめます。BRDはその名のとおりビジネスを成功させるために必要なことを過不足なく記述するものです。情報を取得・保存するタイミング、バリデーションなど業務を間違いなく行うために必要な内容は記載しますが、テーブル設計など内部の実装方針は記載しません。社外のチームと同時並行で実装を進める場合、このタイミングで仕様書や説明書を配布します。設計BRDをもとに実装方針を立てます。要件定義段階から開発チームのメンバー(おもにCTO)が議論に参加し、現在のコードベースに合う形でインテグレートする方法を想定しています。設計段階ではその想定を書き起こし、開発チームの全メンバーに同じ方針を共有します。大規模なプロジェクトでは新しくテーブルをたくさん作ったり、新しい通信相手にAPI定義を提供します。これらの作業を実装する各人が一部ずつ進めるとコンフリクトが起きやすくなります。先行の作業が詰まって新しいタスクに着手できない状況も起きます。トラブルを回避するため、新サービスを提供するような規模では、設計段階でテーブルとAPI定義を一気に作ります。大規模なプロジェクトでは、タスクを複数人で分担する必要もあります。Scalaで実装し、各コミットに実装した分のテストを義務づける環境ではタスクの分割や依存管理も重要です。でたらめな単位でコミットするとコンパイルが失敗しマージできません。利用者に提供するほど完成していなくてもテストで確認できるくらいの粒度で分割します。各タスクの期日を設定し、全体スケジュールに対しては余裕があり、各メンバーの負担がきつくなりすぎないよう調整します。依存関係によって手があいてしまうメンバーがでないよう工程を引くのも設計の一部です。設計は開発チームが中心になりますが、要件定義に加わったメンバーがほぼ独力で行います。内容は多岐に渡りますが作業量はさほど多くありません。成果は、分量が多ければ実装メモという文書にまとめます。それほどでもなければタスク管理の説明文に方針を記述します。この準備によって作業中やレビュー時の手戻りを減らせます。開発チームのメンバーはそれぞれのペースで未アサインのタスクに着手します。タスクは自分ができる範囲で締切が近いものから順に行う決まりになっています。これまでのステップでPSD、BRD、実装メモやタスク説明が準備されています。担当者はこれらの文書を丁寧に読むことからスタートします。文書化されているため休日や深夜早朝、他のメンバーが勤務していないタイミングでも着手できます。わからないところ、疑問、誤解しそうなところがあれば質問します。改善案もこのタイミングで提案します。実装中に疑問が出てきた場合、都度チャットで質問します。記述がわかりにくい部分は修正し、次以降に読む人がわかりやすいように改善します。BRDに制約が足りなくて振舞が一意に定まらない場合、BRDに追記し明確に定めます。既存のコードの類似箇所を参考にしながら実装者自身が処理を設計し実装を進めます。実装しやすくするための小規模なリファクタリングは実装前にちょっとやってしまうことも多いです。実装と同時にテストを書き、BRDに記述されているケースを中心に自信がない部分、複雑なケース、壊れそうなケースを保護します。kippは機能レベルのすべての動作を自動テストで担保しています。テーブルやAPIを定義していても、実装をすすめていく上で不足していたテーブルやカラム、APIメソッドが出てくることがあります。設計者と相談しつつ不足や間違いを訂正し、機能が正しく動くようにします。実装したものは1人以上のコードレビューを受けます。テストの網羅性まで詳細にチェックします。デッドロックやパフォーマンスの問題はテストで検知しにくいので他の開発者の目で丁寧に検査します。Requestに相当)がマージされると、自動的にAWS上の開発環境に展開されます。次の週に自動的に本番環境に展開されます。社内外の関係者はこのあいだに受け入れテストを行います。実装者が追加したテストは、あくまで実装者の理解にもとづいたテストです。丁寧にドキュメントを記述しレビューしても実装者の理解が間違っているリスクは残ります。そこでプロダクトマネジメントチームを中心に関係者が変更された部分をテストし期待通りか確認します。間違いがあった場合はBRDに照らして再確認し実装を修正します。修正が次のリリースサイクルに間に合わない場合はrevertで該当部分を外します。開発プラクティスとしてここまでkippで実践している開発ワークフローを具体的に説明してきました。最後にこのワークフローを開発プラクティスの観点でどう考えているか紹介します。以上から分かるように、kippの開発プロセスはウォーターフォールに近く見えます。継続的デリバリーを実践している点などアジャイルのプラクティスを取り入れている部分もあります。私達はこれを、アジャイル志向のウォーターフォールと捉えています。Manifestoを参照している一点に尽きます。要件定義と受け入れテストという顧客の意思を受け止めるべきステップでは協調を重視してます。要求を整理するドキュメントは丁寧に作成する一方、実装のためのドキュメントは最小限に抑え、開発成果物を早く、読みやすく作ることに注力しています。提起から実装は速ければ2週間で完了します。新規サービスの立ち上げも4ヶ月から6ヶ月で完了した実績があります。ウォーターフォールのワークフローでありながら個々のトピックを高速で処理し、開発イテレーション数を稼ぐことで変化への対応力を身につけています。私達が広く共有されている開発プラクティスを採用せず、このような手法を取っている理由をスクラムとの対比で説明します。スクラムではチームの一体性を重視し、デイリースクラムをはじめ会話の場が多く準備されます。イテレーションが軸となり、計画と振り返りを行います。スクラム開発がkippにそぐわない第一の理由は直接の対話を重視する点にあります。kippは個人主義が強く、業務委託メンバーも多いため、毎日決まった時間に全員が集合するのは不可能です。正社員でさえ全員揃うタイミングがない日もあります。時間、場所に囚われない働き方を前提としたチームには対話を強制できません。第二の理由はイテレーションの考え方とkippのタスク管理がマッチしないことです。スクラムのイテレーションの背景には単一の目標にむかってチームがイテレーションごとに前進していく像があります。kippのタスク管理表には緊急の障害対応から数カ月先のタスクまで規模も重要度もプロダクトも様々なタスクが混在しています。これらをひとつのスプリント計画に落とし込むのは時間がかかるわりに無益な作業でしょう。どのようにタスク管理をするのでしょうか。答えは3つのルールだけでコントロールされています。充分な時間を取る出来ることをやる締め切り厳守タスクを作成するとき、すべての開発タスクは締切を2週以上先に置くルールがあります。重厚なタスクでも、改善レベルであれば2週間で分担して終わらせられます。大規模な新機能開発は例外で、戦略上のリリース時期から逆算して締切を順次設定します。開発者はその時々で出来ることをやることを期待されています。締切が短かったり不慣れなタスクで終わらなそうな場合は他のタスクを選択するべきです。タスクの説明やBRDを読んですんなり理解できれば完遂できるだろうと見込めます。締め切り厳守は一番身も蓋もないルールです。スクラムで振り返りが必要なのは、締切を守れないことがあるからです。初めから全ての締切を守れば振り返りは不要です。一度タスクを取った以上、なにがあってもそれを完了させる責任があります。完了する方策のなかには他のメンバーのヘルプを仰いで移譲することも含まれます。締め切り厳守の仕組みとして、締切2日前から完了するまで、毎日Slackでメンションが飛んできます。本人だけでなくチーム全員の目に触れるので、終了見込みを尋ねたりタスクを分担する契機にもなります。これらのルールは開発者が高い実装能力を持つことを前提としています。kippの開発者には行き詰まらず、常に見積もった日数で作業を完了する能力が求められます。このワークフローに魅力を感じ、堅実で責任感ある開発ライフを送りたいと思った方はぜひpeople@kipp-corp.comにご連絡ください。