モニクルAdvent Calendar 2023の2日目です。昨日はCTOのがぶちゃんによる「エンジニア10人を超えて複数チームになった開発組織でCTOとして最近やっていること」でした。
2日目の今日は、筆者(@Nkzn)が入社直後に開発に携わった「3分投資診断」というサービスの思い出話をします。
3分投資診断とは
3分投資診断は、モニクルグループのワンマイルパートナーズが運営している、はたらく世代のお金の診断・相談サービス「マネイロ」が提供するサービスのひとつ*1です。
年齢や年収、現在の資産形成の概要、老後の過ごし方などを入力していくと、老後までにあとどのくらい資産形成が必要で、そのためにはどういった施策が有効そうなのかを、ざっくり診断してくれます。
思ったより反響があった
オウンドメディアのモニクルプラスでも話したことがあったのですが、思った以上の反響がありました。
実は、筆者は計算エンジンの部分を2021年の秋ごろに実装し終えたあたりで開発から離脱しており、その後にこだわりのUI開発戦記があった時期については別のプロジェクトをやっていました。運用周りも当時のグロース関連のチームに任せてしまったので、あまり数字を追いかけることもしていませんでした。
そんな筆者が驚くことになるのは、ちょうど一年前、昨年の12月に上記のインタビューを受けたときです。創業者の泉田さんから「3分投資診断すげーことになってるよ!めっちゃ使われてる!」と教えてもらって、そんなことになってんの!?と驚いた記憶があります。
診断結果を受けてもっと詳しい対策を知りたくなったお客さんが、診断後にマネイロの相談サービスを申し込んでくれるケースも診断数に応じて増えているらしく、マネイロの2022年の成長を強力に後押ししたとのことでした。
筆者からすると、入社から半年も経たないうちに作っていたものということもあり、がむしゃらに取り組んだいくつかの施策のうちのひとつ、くらいの感覚でした。入社から1年半経った頃に、1年越しに大ヒットを知らされて、やってきたことは無駄じゃなかったんだなあ、としみじみしたものでした。
ドメインエキスパートとの共同開発で気をつけたこと
あまり表舞台で開発の話をしたことがなかったので、少しだけ開発の思い出話もしようと思います。
基本的には役員の皆さんがドメインエキスパートとして仕様をまとめてくれていました。大量のスプレッドシートに根拠資料や計算式が並んでいるイメージです。
筆者は計算エンジンの作成担当だったので、簡単なUIだけを用意して、基本的には数字のインプットとアウトプットが正しそうかどうかをドメインエキスパートと擦り合わせていく作業を行っていました。
ここで特に意識したのが「正しさの確認しやすさ」です。プログラマーではないドメインエキスパートから「○○の項目のアウトプットが怪しい気がするんだけど、動作確認してる時はどんな数字が出てた?」と聞かれたときに、ソースコードを見せながら議論するわけにもいきません*2。次善策として、できるだけテストコードの処理結果で各種の途中計算の結果が見えるようにしてみました。例えば、年金の算出のために必要な「厚生年金対象勤務期間」や「標準報酬月額」の算出の自動テストでは、次のような実行結果が表示されます。
PASS hoge/services/index.test.ts 「厚生年金対象勤務期間」の算出 ✓ 退職年齢65歳、勤務開始年齢24歳、未加入期間5年の場合、厚生年金対象勤務期間は432ヶ月である (1 ms) ✓ 退職年齢75歳、勤務開始年齢23歳、未加入期間10年の場合、厚生年金対象勤務期間は504ヶ月である 「標準報酬月額」の算出(令和3年3月データによる検証) ✓ 年収が0万円のとき、標準報酬月額は88000円である ✓ 年収が468万円のとき、標準報酬月額は380000円である ✓ 年収が720万円のとき、標準報酬月額は590000円である ✓ 年収が1000万円のとき、標準報酬月額は650000円である ✓ 標準報酬月額表を検索できる(表はテストデータで代用) (2 ms)
これなら、ドメインエキスパートに見せたり、検算してもらったりするのも、ある程度は容易です。最終的に数百件のテストケースを作成しましたが、ほぼすべてのテストケースをこのノリで作り、順次ドメインエキスパートに確認してもらいながら開発を進めていきました。
こういったテストの作成においては、JUnitで学んできた*3Parameterized Testの考え方が役立ちました。今回はテスティングフレームワークとしてJestを採用していましたが、 test.each()
を用いると、次のように簡単にParameterized Testが書けるので、重宝しています。
describe("「標準報酬月額」の算出(令和3年3月データによる検証)", () => { test.each([ [0, 88_000], [468, 380_000], [720, 590_000], [1000, 650_000], ])( "年収が%i万円のとき、標準報酬月額は%i円である", (yearlyIncome, standardMonthlySalary) => { const actual = calcStandardMonthlySalaryYen(yearlyIncome) expect(actual).toBe(standardMonthlySalary) } ) test("標準報酬月額表を検索できる(表はテストデータで代用)", () => { ... }) })
「読みやすいテストケース」というのは、かなり認知負荷を下げるのがわかったので、無理に慣れない英語でテストケースの名前を書いて、書いた人も読んだ人もパッと意味がわからないものになるくらいなら、躊躇わずに日本語で書いていくのがよいと思います。
宣伝:マネイロの広告を探せ!
12月1日から、東京メトロにマネイロの広告を掲出しています。
新潟からフルリモートで働いている筆者はなかなか見る機会がないので、もし見つけた人は #マネイロ
のハッシュタグと共に @Nkzn まで「見つけたよ!」のリプをいただけると、めちゃくちゃ喜びます。
中旬には筆者もモニクルグループの全社納会へ参加するために東京へ行く予定なので、そのときに探してみようと思っています。
明日は新潟メンバー仲間の@circled9です。よろしく!