freee流、クレジットカードのマイクロサービス設計構築術

こんにちは、DevBrandingのellyです。10月29日に配信した「freee Tech Night 〜freee流、クレジットカードのマイクロサービス設計構築術」の様子をご紹介します。

先日freeeは、法人向けに企業成長を支援するための統合型ビジネスカード「freeeカード Unlimited」β版の提供を開始しました。

今回はfreeeカード Unlimitedのシステムをつくったエンジニア2人をゲストにクレジットカードの仕組みをどのように作っていったのかを聞きました。リリースまでの道のりをfreee Developers Blogでも全8回で連載していますのでぜひ合わせて読んでいただけると嬉しいです。

登壇者集合写真
登壇者集合写真

tabachain:写真左上。決済チームのエンジニア。2016年7月入社。freee会計、freee申告のエンジニアを経てエンジニアリングマネージャーを約3年担当。2020年10月に再度エンジニアとして決済チームに異動。

imamura:写真右上。2017年4月に新卒入社。入社当初はfreee申告を含む税理士向け機能開発を担当。2019年から金融事業部に異動し新規のサービス開発に取り組み、2020年からfreeeカード Unlimitedの開発を担当。

のぶじゃす (@noblejasper): 写真右下。ラジオパーソナリティ、2017年に中途入社。mixi、ソーシャルゲーム企業でソフトウェアエンジニアを経験し freee に。入社後はエンジニア→エンジニア採用担当→エンジニアと DevBranding を担当。しゃべりたがり。声が大きい。

法人向けのクレジットカードをリリース

ーfreeeカード Unlimitedとはどのようなサービスなのですか?

imamura:端的に言うと、freeeが提供する法人向けのコーポレートカードです。freee会計と連携することによってfreee会計のデータと独自の審査モデルを使って高額な与信を付与することができます。

スモールビジネスを経営されている方にとって、創業間もないタイミングだと、クレジットカードを契約しても限度額が低かったり、そもそも契約できないという課題がよくあるんですが、今回freee会計のデータを使うことによって、サーバー代や広告費といった高額サービスの決済もできるようになっています。

また、通常だとクレジットカードの明細は1ヶ月程待ってから来ると思いますが、freee会計と連携していることによって、決済するとすぐに通知が来て月次の決算処理がよりタイムリーにできるようになるので、そこが大きなメリットだと思います。

ークレジットカードの裏側の仕組みってどうなっているんですか?

tabachain:入会、審査、発行、与信、決済、請求、そして決済後のユーザーへの通知などの仕組みがあり、すべてをモノリシックにやっているのではなくそれぞれの機能を1対1対応でマイクロサービスでやっているという感じです。

ーマイクロサービスは何で実装しているんですか?

imamura:基本的にバックエンドの部分は Goを使っています。フロントエンドはTypeScriptとReactを使って開発していたり、一部、画面側に対するAPIを提供するためのバックエンドはRailsを使って開発しています。

tabachain:イメージしやすく言うとフロントエンドとしてRailsを使って、これがBFFの役割をしていて、バックエンドはGoでマイクロサービスがいくつか立っていて、gRPCを使ってフロントエンドのRailsがバックエンドのマイクロサービスにリクエストを投げるイメージです。ユーザーはフロントエンドのRailsにHTTPリクエストを投げるイメージですが、裏側ではいろんなマイクロサービスにリクエストを投げるイメージです。

ーfreeeは全社的にはRailsが多いですが、今回Goで作ることにした理由は何ですか?

imamura:実は社内でも既にいくつかGoを使ったマイクロサービスがあり、ロギングやエラー通知、SQLの発行などマイクロサービスに必要な機能が共通パッケージとして提供されていました。(こちらの記事で詳しく紹介しています)今回新しくマイクロサービスを開発するにあたって、車輪の再発明を避けてドメインロジックの開発に集中したいと思い、その共通パッケージを使うために採用したというのが一番の理由です。

マイクロサービス化を選んだ理由と切り分け方

ーサービス自体が大きいことからマイクロサービス化することを決めたと聞きましたが、どのように切り分け方を判断したのですか?

tabachain:そもそもマイクロサービスでずっと開発してましたと言えるような経験者がいない状態から始まり、どういう切り分け方をするかという共通認識もなかったので、まずは勉強会という形で本を買ってきて、1ヶ月くらいみんなで切り分け方を話し合って、まとまったものをドキュメントに落とし込むというのを繰り返していましたね。

その中で、例えば「決済のマイクロサービスの障害で他のサービスも動かなくなったら問題なので、そういった単一障害点が生まれないようにここは非同期通信を使おう」「この本によるとDDDの手法でマイクロサービスの切り分け方を決めると良さそう」みたいな話が出てきて、実際に実践してみました。エンジニアだけじゃなくPMにも入ってもらって、どこで非同期通信を使うか、どういったモデルを使っていくかを言語化していきました。

大体こんな感じだよね、と認識が合ったのが去年の12月くらいで、そこから実際に実装していきました。事前にじっくり話し合ったおかげで実装がスムーズに進められたと思っています。

エンジニア→EM→エンジニアという少し変わった経歴の持ち主tabachainさん
エンジニア→EM→エンジニアという少し変わった経歴の持ち主tabachainさん

ー手を動かす前に、開発メンバー全員で議論して認識を合わせることに時間を使ったんですね。

tabachain:そうですね、みんなで自分の設計のベストアイディアをぶつけ合いました。

ーそれぞれ違うものなんですか?

imamura:全く違うわけではないのですが、システム全体がかなり大きいので、特にサービスの分割単位の部分はそれぞれ意見がありました。

tabachain:「このサービスにはこの機能が必要」「この機能はスピード重視」「この機能はクオリティ重視」みたいな肌感も違うので、どうあるべきかを話し合うのに結構時間を使いました。

imamura:マイクロサービス化を選んだのはサービスの大きさももちろんですが、他にも観点はありました。

例えば今回の場合だと、ユーザーが決済をした時にもいつでもリクエストが送られ残高を確認して即時で応答する機能や、毎月決まっているカードの請求といった機能は、他の機能に障害が起こったとしても常に起動させておく必要があります。

それぞれが互いに影響しあって全部が止まってしまうという状況は避けたかったのでマイクロサービス化を選んだというのも大きな理由です。

5年目とは思えない落ち着きのimamuraさん
5年目とは思えない落ち着きのimamuraさん

ークレジットカードの機能の特性上、障害発生時でも動いていなきゃいけないということですね。

imamura:マイクロサービスの分割の議論も時も、「互いにサービスが疎結合になっても起動できるか」であったりとか、「この分割案だと同じようなデータを持っているのに頻繁に連携しないといけないからまとめてしまった方がいいんじゃないか」とか、そういう議論がよくありました。

ー現在はβ版でサービスがリリースされていますが、いまのところ大きな課題は発生していないですか?

tabachain:所々全体に関わる修正が入ったりはするんですが、根本的に間違っていたみたいなもの幸い起きていないです。そこはやはり初めにしっかり議論できていたのが大きくて、その時の判断が間違っていなかったんだと思います。

imamura:一番良かったなぁと思ったのが、分割案を決めるときにエンジニアだけで決めてしまうんじゃなくて、社内に決済領域にかなり詳しいPMの方がいたので、その方に今作ろうとしているものはもちろん、今後作ろうとしているものやそもそも業界としてどういう仕組みになっているのかというのを相談しながら分割したので、リリースした後も大きな乖離が発生せずに済んでいるのだと思います。

本格的なマイクロサービスを開発する上での苦労や工夫

ー初めて本格的なマイクロサービスの構成で開発する上で難しかったところ、困った所はどんなところですか?

imamura:サービスを分けた場合、サービス間通信をしないといけなくなると思うんですが、一方のサービスが通信に失敗した場合や受け取る側が失敗する場合、遅延が起こった場合、エラーが起こった場合など様々なケースを想定して、それをリカバリーできるような方法を考えるのがすごく難しかったなと思っています。

実際freee Developers Blogでも非同期通信について書いたんですけれども、失敗しても再送して再処理を進めるようにしたりとか、同じようなメッセージが届いても問題ないように重複排除できるようにしたりとか、そのあたりは最初の設計のタイミングで皆とかなり議論したので、納得感を持って進められたと思っています。

ーユーザーの利便性に直結する機能なので大事ですね。

tabachain:僕はデータベース設計が難しかったです。マイクロサービスってひとつひとつのデータベースを分けて管理しているので、すべてのサービスが独自のデータベースを持つという形になっているのですが、難しかったのは他のサービスが持つデータをどう持ってくるか、参照するかみたいなところです。

同期的に他サービスから参照する形だと他サービスが落ちていると影響を受けてしまうので、あるサービスに書き込みが走ったら「書き込みが起こった」というイベントとして非同期で他のサービスに伝播させて、他のサービスではその変更を検知して書き込みが起こるというようにして、全てのサービスで不整合が起きないように設計するというのが難しかったです。

ー聞いているだけで難しそうですね。

tabachain:結果的に順番依存しない機能がほとんどだったのですが、いろんなユースケースを考えて、全員でレビューして、順番が前後してもなんとかなるような設計にして基本的に非同期通信でつながるようになっています。

ーマイクロサービスを開発してみて、普段のモノリシックな開発とは違う部分で工夫していたりとか気をつけていたりするところはありますか?

tabachain:モノレポを採用したのは工夫のひとつです。一つ一つリポジトリを分けるというやり方もあるんですが、今回はモノレポで一つのリポジトリに複数のサービスが入っています。

どういう狙いがあったかというと、例えば0→1フェーズだとサービス横断での変更がたくさん発生しますが、モノレポだと横断してレビューすることができます。

また、リポジトリが分かれていると、リポジトリA、リポジトリBがそれぞれこの状態じゃないとレビュワーが正常に動作確認できないということが起きるのですが、モノレポでひとつのリポジトリにすることで、あるコミットハッシュを持ってくれば動作確認することができます。

他にもProtocol Buffersというメッセージのスキーマを定義するデータファイルをモノレポで管理したり、デプロイも一気にできたりというメリットもあります。

ーモノレポのデメリットはありますか?

tabachain:いまのところデメリットは感じていないですが、サービスが大きくなって複雑化していって、もしひとつのサービスをひとつのチームが見るというような規模になった場合、サービス横断での変更もなくなってくるしプルリクとかも分かれているほうがやりやすいので、リポジトリを分けたほうがいいと判断する時が来るかもしれないです。

生産性でいうとモノレポを採用してかなり良かったです。そうじゃなかったらどうなっていたか、想像がつかないです(笑)

ー今後やっていきたいこと、課題などはありますか?

imamura:何かシステムエラーが起こったときに手動で対応しないといけない部分がまだ残っています。エラーや不具合の発生は避けて通れないので、規模が広がる前に自動化してリカバリできるような仕組みにしていきたいなと思っています。

tabachain:品質を担保するためにクリーンアーキテクチャでいうユースケースのテストをかなり厚めに書いたりしているんですけど、サービス間連携でのバグやデグレをまだ完全に防ぎきれていないので、どのテストでどのレイヤーをまかなうかみたいなところを明確にしていかないとなという課題感を持っています。例えばe2eテストをいまQAの方に書いてもらってますが、エンジニアが書いたほうがいいかもしれないといった話です。

ー機能を増やすというよりも、品質・クオリティを上げていくところを重視しているんですね。今後の進化も楽しみです。

最後に

すでにβ版をリリースしたfreeeカード Unlimitedもまだまだ開発が続きます。サービスの品質にこだわり抜いてきた方、サービス全体を見てアーキテクチャを考え構築したい方を募集中です。ご興味のある方はぜひこちらからエントリーください。お待ちしております!

エンジニア採用 | freee株式会社 採用情報

▶次回freee Tech Night

11/19(金)「マネーフォワード vs freee、もし名古屋で開発するなら?」というテーマでお送りします。 これから名古屋に開発拠点を立ち上げるマネーフォワードと 2020年に拠点を構えたfreee。 なぜ名古屋に開発拠点が必要なのか、メリットやデメリット、作っているプロダクト、目指している本社との関わりなど、 両社が思っていること考えてることを対比しながら赤裸々に語ってもらいます。

freee-tech-night.connpass.com

▶今回のイベントのアーカイブ(録画)


www.youtube.com

CloudNative Days Tokyo 2021 に参加しました

こんにちは。 freee の SRE チームでプレイングマネージャーをしている @manabusakai です。

最近は "CONTAINER LOGISTICS Co." (長いので普段は CLC と呼んでいます)というサブチームで Kubernetes の CI/CD 周りの改善に取り組んでいます。直近では Argo CD や Argo Rollouts といった Argo Project の OSS を触っています。

さて、みなさんは先日開催された CloudNative Days Tokyo 2021 はご覧になられたでしょうか?

CloudNative Days Tokyo 2021
CloudNative Days Tokyo 2021

event.cloudnativedays.jp

今年は 11 月 4 日 〜 5 日の 2 日間に渡ってオンラインで開催されました。 freee は Platinum スポンサーとして協賛させていただき、さらに CLC チームから 2 人が登壇しました。今回はその登壇内容をお伝えします。

Argo CD Deep Dive

1 日目に登壇したのが @renjikari で、タイトルは「Argo CD Deep Dive」です。

公式ドキュメントを読むだけではわからない Argo CD の挙動を、コードを読み解きながらより詳しく理解していく内容になっています。実際に運用してみて実感しますが、100 以上の Application を抱える Argo CD を安定運用するには深い知識が必要になります。この発表内容はその足掛かりになってくれると思います。

Argo CD Deep Dive
Argo CD Deep Dive

実践! Argo CD & Rollouts による canary release

2 日目にスポンサー枠で登壇したのが @kumashun88 で、タイトルは「実践! Argo CD & Rollouts による canary release」です。

彼は昨年入社の新卒 2 年目でインフラ未経験で配属されましたが、今では一人前の SRE として活躍してくれています(今回が人生初の登壇!)。

今まさに CLC チームが取り組んでいる Argo CD と Argo Rollouts をテーマに、運用中の SaaS プロダクトにどのように canary release を導入しようとしているのかが伝わると思います。

実践! Argo CD & Rollouts による canary release
実践! Argo CD & Rollouts による canary release

おわりに

どちらのセッションもアーカイブ視聴ができるので、当日見れなかったという方は以下のリンクからご覧いただければと思います。

event.cloudnativedays.jp

event.cloudnativedays.jp

コロナ禍のため昨年に引き続き、今年もオンライン開催になりました。オンラインだと参加しやすい一方で、スポンサーブースを回ったり、知り合いとわいわい雑談するのが懐かしいです。

freee では大規模な SaaS プロダクトの CI/CD をより良くしたり、開発者の生産性を高めることに熱意のあるエンジニアを募集しています。興味のある方は、ぜひカジュアル面談でお話しさせてください!

jobs.freee.co.jp

freeeのエンジニアサマーインターンって実際何やるの?一例をご紹介

こんにちは。id:tomoz6o9 です。 大阪開発拠点の所属のソフトウェアエンジニアで、普段はfreeeプロジェクト管理というプロダクトの開発を行っています。最近はマネジメント寄りの役割を担うことが多いです。

freeeでは例年夏にサマーインターンを2週間ほどで実施をしています。今年は例年通りのサマーインターンに加えて、弊社でも初の取り組みとなる「プログラミング未経験者」に向けたサマーインターンという2種類のサマーインターンが実施されました。Wantedlyにも実施報告の記事が書かれています。

www.wantedly.com www.wantedly.com

私の所属しているfreeeプロジェクト管理の開発チームでは通常のサマーインターンを2名、未経験者サマーインターンで5名と、どちらのインターンでも学生を迎え入れたので、数あるチームの中であくまで一例ではございますが、実際にインターンに来ていただいた学生さんたちにどのようなことをやっていただいたのかを担当チームの立場からご紹介できればと思います。

前期サマーインターン(プログラミング経験者向け)

このサマーインターンでは計13名の受入をし、基本的に様々なチームに1名ないしは2名でバラバラに配属されインターンが行われました。 プロジェクト管理チームでは2名の受入をしました。 せっかく2人できていただいたので、別々に課題をするのももったいないというところで、2人で一緒に課題に取り組んでもらいました。

「一覧」ページを改善する

この課題の選定にあたっては、以下のような点を意識しました。

  • 折角のサービスのコードベースを触ってもらう機会、「ここだけみてれば解決する」ようなスコープの狭い課題にならないようにしたい。
    • 合わせて、広い範囲を触ってもらう過程で様々な機能に触れ、サービス全体としてどのようなものであるかを知ってもらいたい。
  • 使ってくださっているユーザーのことが思い浮かぶような課題にしたい。具体的な使い方を思い浮かべて、どのようにすれば価値が届くかを考える経験をしてもらいたい。

そうして選んだ課題が、Webアプリを触っているとよく見るいわゆる「一覧」ページにこれまで実は表示されなかった「全部で何件あるか」という情報を追加してもらうというものです。

freeeプロジェクト管理のサービス画面
freeeプロジェクト管理のサービス画面

サービス内にはたくさんの一覧ページがサービス内には存在していますが、今回は以下のようなことをインターン生2人で調べたり、話し合ったりするところから始めてもらいました。

  • どれだけの一覧ページがあるか
  • そのそれぞれでどのような全件表示をするのが望ましいか
  • それらの全件表示を対応していく優先度はどうか

つまり、「事前の影響調査」「具体的なユースケースの想定」「優先度を決めてやる/やらないのラインを決める」という部分を議論していただきながら自分たちで実装まで進めてもらいました。

「具体的なユースケースの想定」では、その画面が何の機能に紐づくものであるか、そしてそれらはどのように使われているかを把握し、その上で今足りていない要素は何かを考えることが必要になります。 また優先度に関しても、気持ちとしては「全部やらないと!」という考えになりがちなところですが、短期インターンという限られた時間を考えると全てをやりきるのは現実的ではないこともしばしばです。その中でもユーザーへのインパクトという軸でしっかり考えて優先度をつけることは、限られた時間の中で成果を最大化するための非常に重要なポイントだと考えています。

後期サマーインターン(プログラミング未経験者向け)

今回はじめての試みとなる「未経験者」という枠は、エンジニアリング暦・(アルバイト等の)実務経験の有無などを基準にしました。 そのような経緯のためインターン生の知識量もまちまちだったので、初日に全体で簡単な座学を実施していただきました。

speakerdeck.com

この講義は実際にWebページを操作しながら、その動作を一つ一つ観察し、その裏でどのようにサービスが動作しているかを確認していくというものです。

この後各チームに分かれ作業を行いました。今年はモバイルチームで4名、freeeプロジェクト管理のチームで5名のインターン生を受け入れました。

弟子入りスタイルでのインターン実施

(以降は私が担当したプロジェクト管理チームでのお話になります。) 未経験者対象、かつ実質本題にに費やせるのは1週間程度という比較的短めな期間だったため、何をやってもらうかは非常に迷いどころでした。

そこで、「弟子入り」スタイルで課題に取り組んでもらいました。 これは1〜2人のインターン生に対して「師匠」となる社員を一人アサインし、いわゆるメンターという立場を超えて、常に一緒に仕事してもらうというやり方です。

特に今回は、ロードマップの開発とは別に定期的に実施している改善系のタスクや要望などに対応していくというプロセスに一緒に参画してもらうことにしました。

「弟子入り」というと、ちょっと上下関係感がありますが、単にアドバイスする/されるという関係ではなく、一緒にワイワイ作業などをできればいいなという思いでこの方法を選択しました。

実際には3チームに別れての実施となりましたが、今回はそれぞれのチームで別のテーマをすえて実施しました。実際に各チームがどのようなことをやったのかをご紹介します。

課題の内容

チーム1: Webサービスの開発を知る

このチームではエンジニアとしてWebサービスを開発というものが一体どういったものであるかを知るということを中心に進めていきました。すなわち、Webサービスが「正しく」動作するとはどういうことなのか、またそのような「正しく動く」アプリを作るとはどうすればいいのかいうことを実際に開発フローに沿って体験してもらうことで進めていきました。

具体的には、freeeプロジェクト管理に対しUI上の使い勝手の改善の余地があるポイントを伝えた上で、今なぜこうなっているのか、どのようにプログラム変更することでそれがクリアできるのかをモブプロ形式でドライバー・ナビゲーターを交代しながら実施し、結果数点の改善を達成させることができました。この最中にはコードを書いていくためのポイント、動作確認とレビューの進め方なども含まれており、チームでWebサービス開発を行っていく流れが体験できたはずです。

また課題を実施する中で、「テストコードを書く」ことの重要さや、プログラミングにおける設計の話、またちょっと毛色を変えてfreeeが組織的に取り組んでいる「アクセシビリティ」についてなど、アプリケーション開発を取り巻く様々なトピックにも触れ、その世界の広さ・面白さを体験していただけたのではないかなと思います。

チーム2: APIを知る

我々が普段使うWebサービスが、他のサービスとは相互に連携し合っていることも珍しくありません。それはfreeeのプロダクトにおいても例外でありません。 freeeではPublicに公開しているAPIがあり、APIを活用した外部サービス連携を強化し、APIエコノミー形成を目指しています。 また一方で、我々もまた他サービスの公開されてるAPIを利用してより便利にプロダクトを使っていただけるような機能も作っています。(Googleカレンダー連携など)。 このチームではそのような内外のAPIに焦点をあて、そもそも連携がどのように実現されているのかも含めて体験していただき、その改善を行ってもらいました。

「APIって何?」という状態からのスタートでしたが、実例として「郵便番号を渡すとJSON形式で住所を返すAPI」を題材に、APIがあるとどんなメリットが有るのかを理解し、その重要性を理解できるように進めていきました

ゴールは既に公開されているPublic APIの改良でしたが、手を加えることをで何が良くなるのかインターン生に考えてもらい実装しました。PostmanというAPIを叩くツールを使って動きを確認しながらAPIに手を加えました。 また実装の変更だけではなく、その定義を示すドキュメントであるOpen APIのファイルの変更も行ってもらいました。

修正したのは小さな改善ではありますが、開発する上で必要な基礎知識や、問題解消までのアプローチ、コードの意図や背景を読み解く方法を伝え、この改善がどんな価値を提供するのか考えてもらうことで、チュートリアルでは味わえない開発の現場の空気感を味わってもらえたのではと思います。

チーム3: ユーザーを知る

このチームでは、実際にプロダクトを使っているユーザーさんから寄せられた要望である「エクスポート機能」の改善に取り組みました。 この開発はボリュームそのものは大きくありませんがプロダクト開発の楽しさをいろんな角度から感じることができる内容だったと思います。

一口に要望といっても、単に要望をそのまま実現することが要望実現ではありません。

ユーザーさんはその機能を使って業務を回しています。 その業務を正しく理解した上で要望の本質を捉え、解決方針が真にユーザーの業務を改善しているかどうかを見極める必要があります。個人的にはこういうところがBtoBのプロダクト開発の醍醐味だと思っています。

このチームでは、その「要望」に対して「解決方針」を議論することから始めました。 実際に想定されるユーザーの業務やユースケースを考え、実際に自分の手で同じことを試行し、どのように改善すべきかを考えました。 その上でPM(仕様とかを決めている人)への提案、さらなるディスカッションを経て実際に開発をします。

実際にはサマーインターンが終了した後になってしまいましたが、この際の改善はきちんとユーザーに届けられました。

実際にリリースされた機能のリリース告知の画像
freeeプロジェクト管理のリリース情報サイト
他のチームとは少し毛色こそ違いますが、これもまたプロダクト開発の重要な側面をしっかり感じていただけたのではないかなと思います。

補足

技術的にはどのようなことをやったの?

内容の説明が結構コンテンツによっていて、技術的にどんなことをやったの?という疑問を持たれる方がいらっしゃるかもしれませんね。 技術的には、まさに動いている我々のプロダクトのコードベースに対して作業してもらったので、freeeの典型的な技術スタックを触ってもらったという状況です。 freeeプロジェクト管理では、バックエンドにruby on rails, フロントエンドにはReact/Typescriptを採用しています。

実際リモートでのインターンってどんな感じ?

今回はリモートでの実施となったサマーインターンですが、会議等はGoogle Meetで行いつつ、日常の作業はSlackで、通話が必要な際はSlack huddleを利用してコミュニケーションをとりつつ実施していきました。

特にモブプロをするようなシチュエーションでは、VSCode LiveShareを利用していました。これは、我々としても日常的にモブプロなどで利用していることもあり、ほとんど問題なく開発を進めていけました。

まとめ

いずれのサマーインターンも一貫して、「現場だからこそできる」「freeeだからこそできる」学びを提供できたらいいなという思いでそれぞれの課題設定をしました。 実際、プログラミング学習とその実務との間には、特にプログラミング以外の部分に関して(例えば仕様を決めていくプロセスなど)、ギャップがありどんなものかの想像もつきづらく、エンジニアになることへの不安になったりすることもあるかと思います。 このインターンの取り組みで、実際の現場を体感したことにより、一層「エンジニアになる」ということの具体的なイメージを持ってもらえたならいいなと思っております。

23新卒採用のエントリーも開始しています!

サマーインターンは終わってしまいましたが、23新卒採用のエントリーが早速開始されています。 以下のような項目にピンとくる仲間を探しています。

  • 価値あるプロダクトをつくり、顧客に最速で届けたい方
  • 動作の遅いアプリケーションや使いにくいアプリケーションに憤りを感じる方
  • ベンチマーキングやパフォーマンスのデバッグが好きな方
  • 面倒なことは全部自動的にやってもらいたいと思う方
  • 世の中の既存の仕組みに疑問を持つことが多い方
  • 常に新しいことに挑戦していたい方

もし興味があれば、是非応募してみてください! jobs.freee.co.jp

【連載 第8回】QAがfreeeカードUnlimitedのスクラムチームメンバーとして取り組んでること

こんにちは、freeeでQAエンジニアをしているymty(ゆもつよ)です。この記事はfreeeカード Unlimited の開発の裏側について紹介する連載の第8回目(最終回)になります。

今までの連載の中で、freeeカード Unlimitedのアーキテクチャーやインフラといった技術的な側面や、若い優秀なエンジニアや、EMからエンジニアにロールチェンジした敏腕エンジニアが取り組んでいること、そしてEM(エンジニアリングマネージャー)がどのようにチームに関わっているかといった話題がありました。

この記事では、freeeカード Unlimited の開発でQAの人たちがどのようなことをしているかを書きたいと思います。 スクラムチームでのQAのやり方の参考になれば幸いです。

freeeカード Unlimited の開発でアジャイルQAを始めた経緯

freeeカード Unlimited の開発は、スクラムで行っています。スクラムでの開発に適したQAの実践方法を私たちはアジャイルQAと呼んでます。

アジャイルQAを行うきっかけは、金融開発チームのEMであるyokotaさんと約2年前に話をしたときでした。

yokotaさん

「現状はQAにテストをして欲しい時に依頼をして、それから入ってもらっているが、今後はQuality Firstでやっていきたい。」「小さい単位でテストしていけるといい、と考えている。」「金融特有の言葉があるので、それも追々理解いただけるといいな。」

ymty

「ぜひやりたい!(アジャイル開発の経験ないので超やりたい...yumotsuyoの心の声)」「KickOffの段階から入りたい!スクラムイベントにも参加するようにします!」「金融のアジャイル開発にあったQAの形を作ってきます!」

この会話が発端で、アジャイルQAは始まりました。

QAのテストはアジャイル開発ではどうあるべきか

アジャイル開発に適したテストをQAが行うために大事なことは、ビッグバンテスト(開発が終わったらQAがテストを一気に始める)を行うのではなく、早い段階からテストを始めて、安心を積み上げていくことだと考えます。結果的に、ビッグバンテストを行うよりも開発を速くする効果があります。

f:id:yumotsuyo_freee:20211015082656p:plain
アジャイルQAで実現したいこと

QAのメンバーがアジャイル開発の一員になるにあたり、最初に決めた行動指針は以下のことでした。

できるところからどんどんテストする

  • プロダクトの全体像/仕様はengとQAで一緒に理解していく
  • 仕様が理解できたらすぐにテストケースを設計していく
  • QAの観点で(なるべく早くからテストが始められるように)何から開発をして欲しいか意見をいう
  • 仕様が変わったらテストケースもメンテする
  • 開発が完了したら後はリグレッションテストだけにする

少人数でテストをする

  • テスト設計とテスト実行は同じ人が行う(仕様を詳しく知ってる人がテストをするのがよい)

QAのメンバーへは...

  • 開発チームの一員として価値がある行動をしよう!(テストするだけがQAじゃないよ!)
  • リリースされる前に(ユーザーと同じ目線で)プロダクトに最も触れているのは自分なんだと自負できるようにしよう!
  • 「バグを見つける」「テストを進捗させる」常に「足りないor余計なテストはないか」を考える

そうして、金融開発チームにてアジャイルQAを取り入れた開発の経験を積んでいき、 freeeカード Unlimited の開発もアジャイルQAで行うことになりました。

freeeカード Unlimited の開発でQAがやってること

ここからは、freeeカード Unlimited の開発でQAがやってることを書いていきます。

スクラムイベントへQAが参加してチームの一員となる

私は、freeeカード Unlimited の開発が始まった当初にチームに合流しました。当初は、ユーザーストーリーマッピングやストーリーチケットの見積もり会などに参加しました。このころ、QAは私一人でしたが、今ではQAのメンバーも増えて、朝会、リファインメント、振り返り、プランニングといったスクラムイベントには全て参加しています。

QAがチームの一員として参加することで、今の開発全体の状況がわかり、QAは自分たちが何をしていくのがチームにとってよいことなのかが判断できるようになります。できるところからどんどんテストしていくためには、チームの状況を把握したうえで、どこからテストしていきたいかをチームに伝えることが大切です。結果的に早い段階からQAがテスト可能になり、エンジニアもQAも待ち時間が発生してしまうといった状況に陥らずに開発を進めていくことができます。開発が終わった後からQAが本格的にテストを始める方法とは異なり、開発が終わった時には計画したテストが終わっているので、一通りリグレッションテストをすれば、すぐにリリースができます。

前述したように、金融開発チームは、freeeカード Unlimited の開発よりも前からアジャイルQAの経験を積んでいます。前回のyokotaさんの記事にあるように、金融開発チームは、チームとしてうまくQAと連携する方法を知っていたので、freeeカード Unlimited の開発でも問題なくアジャイルQAを適用することができました。

できるところからどんどんテストをする

アジャイルQAでは、スプリントごとにdoneしたストーリーチケットを、その後のスプリントでまとめてテストします。

freeeカード Unlimited のQAとしては、具体的にどんなことをやったのか、オーソリ*1のテストを一例として紹介します。オーソリのテストは、ざっくりいうと下図の中の「ここのテスト」という部分のテストになります。

f:id:yumotsuyo_freee:20211021075041p:plain
テストをする処理全体の中のオーソリの位置

オーソリのテストでは、事前準備として、画面上の申し込みからデータ登録を行い、一連の処理をしていくことが必要です。しかし、一連の処理が完成するのを待っていると、アジャイルQAになりません。なので、以下の箇条書きで示すように準備して実行します。

  1. freee会計の事業所を用意して、テスト設計したオーソリのパターンに沿ってデータを作る。
  2. カード発行依頼に必要なデータをデータベースからSQLで取ってくる。
  3. カード発行をするためのAPIをPostman(APIテストのツール)で実行し契約番号を取得する。データは [2. ]のデータを使う。
  4. アクティベート状態にするためのデータをinsertする。データは[2.]と[3.]で持ってきたデータを使う。
  5. テスト設計したカード利用パターンが確認できるJSONを作ってPostmanでPOSTする。
  6. 期待した通りのデータで登録されていることを確認できるSQLを実行する。 →5と6でのレスポンスはテストの期待結果として確認する。

f:id:yumotsuyo_freee:20211022115222p:plain
オーソリのテストをするための準備

テスト設計したオーソリのパターンの一部を以下に掲載します。表の上段のまとまりが「オーソリ→クリアリング」といったテスト実行の際の処理順序を定義しています。中断のまとまりが、処理順序の中でどのような内容のデータを組み合わせていくかを決めています。3つ目のまとまり(最初の列に連番をつけている項目群)がテスト条件を列挙したものになります。このパターンは、ドメインエキスパートであるプロダクトマネージャーに抜け漏れがないかをレビューしてもらい、テストとしての質を確保しました。

f:id:yumotsuyo_freee:20211021080343p:plain
テスト設計した実行パターン

QAとしては、オーソリ処理の品質が重要だと考えていたので、このような方法でなるべく早くにオーソリのテストを始めるようにしました。

画面がない段階からテストする

画面がない段階からAPIを叩いてテストをするのは、設計面のハッピー(freeeではバグのことをハッピーと呼びます)を見つける効果もあります。

例えば、画面入力のバリデーションチェックを確認するテストをする際にも、APIテストだとバリデーションがバックエンドで効いているかをテストできます。他にも、マイクロサービス間の不整合がないかといったテストもUI上からテストするよりも確実に行えます。

チームとしてQAに取り組むからこういうことができる

エンジニアには、QAがRDSに接続できるよう権限を絞ったアクセス権を作ってもらったり、テストデータ作成ミスでうまくいかない時に助けてもらったり、逆に手間をかけてしまってるかもしれないという噂もあります(笑)。しかし、そのおかげで早い段階で安心感を積み上げるようテストができています。できるところからどんどんテストしていくのは、チーム全員の力で実現できていると実感します。

受け入れ基準はQAが書く

freeeカード Unlimited でのアジャイルQAとしての他の取り組みとして、ストーリーチケットの受け入れ基準を書くことについて言及したいと思います。

まず、アジャイルかどうかに関わらず、QAが予定しているテストはチーム内で共有する必要があります。freeeの中でよくやる方法は、テストプランのレビューと一緒に、QAがテストすること一覧の内容をチーム内で確認する時間を取る方法です。この方法は完成したプロダクトに対してのエンハンスではやりやすいのですが、全くの新規開発だと実施するタイミングや回数に課題がありました。

freeeカード Unlimited の開発に参画して間もない頃、ふと「QAがテストすることって、ストーリーチケットの受け入れ基準と一緒なんじゃないかな」とひらめきました。そして、「QAが受け入れ基準を書きたい」とプロダクトマネージャーに提案をして、受け入れてもらいました。

エンジニアは、リファインメントにてストーリーポイントをつけていきます。QAは、仕様を理解したらすぐにテストすることを考えて、リファインメントより前に、ストーリーチケットへ受け入れ基準として記載するようにしていきました。受け入れ基準を記載しておくことで、QAは何をテストしようとしてるのかがエンジニアに共有できました。エンジニアは、ポイントをつける際に受け入れ基準も考慮していました。そして、プロダクトマネージャーとエンジニアとQAで、OKとすることの認識に齟齬があれば、早い段階で解消ができるという効果もありました。しかし、一番の効果としては、QAがテストすること一覧を確認するミーティングでチームのみんなの時間を余計に使わなくて済むようになったことだと思います。

重篤度(Severity)をチームで合意する

ハッピーには、重篤度(Severity)を付けます。重篤度(Severity)は優先度(Priority)とは異なり、ユーザーが利用している時に発生するとどれだけ良くないことになるかの度合いです。

ハッピーに重篤度(Severity)を付けることで、リリースまでに絶対直すべきか、リリースブロックにはせずに、なるべく早く修正してhotfixをリリースするという判断ができるようにしました。

重篤度(Severity)を付けることは、昔からあるプラクティスであり実践している人たちも多いと思います。freeeの全プロダクトでも重篤度の定義をして運用をしています。

重篤度(Severity)は、エンジニア、プロダクトマネージャー、UX、QAのみんなで意識合わせをして、同じ目線で見れることによって初めて迅速な判断が可能になります。freeeカード Unlimited は全くの新規プロダクトなので、この合意をするタイミングが難しかったです。ドッグフーディングをするあたりでみんなに集まってもらい、何度かのディスカッションを行って決めました。リリースが近づいてくると、朝会などの場で修正が終わってないハッピーを確認し合いますが、その時にも重篤度(Severity)は判断基準として役に立ちました。

テスト自動化への取り組み

freeeでは、エンジニアが自分で書いたコードのテストを書いています。freeeカード Unlimited も他のプロダクトと同様に、エンジニアがテストを書いて、実行結果がOKであればチケットが完了になります。

QAは、前述したように、エンジニアが完了にしたチケットのうち、ストーリーチケットをQAで行うテストの単位としています。 freeeカード Unlimited では、ストーリーチケット単位で行うテストは、全て手動テストで行っています。

「あれ、自動化はしないの?」と思う人たちも多いかもしれないですが、QAが行う最初のテストは、ユーザーが使うのと出来る限り同じように操作したほうがよいというのが私の考えです。そうすることで、UXと一緒に見た目の動きも確認できます。

ただし、前述したオーソリのテストのように、最初はPostmanを手動でポチポチしながらテスト実行していたものを、前段の一連の処理が繋がってもポチポチ手動でテストをやっていると、テスト実行に果てしなく時間がかかってしまいます。

一連の処理の手動テストが終わったころ、QAメンバーのひとりが、オーソリまで全ての処を一発で実行できるAPIテストを作ってくれました。APIテストによって、オーソリの後の処理(例えば、請求など)を手動テストする際にも、テストのための準備が一瞬でできるようになりました。テスト準備が一瞬で出来るので、常に新しくデータを作ってテスト実行ができます。これは、オーソリまでの一連の処理を常にリグレッションテストしているのと同様の効果もあります。

f:id:yumotsuyo_freee:20211022062652p:plain
一連の処理を一瞬で行うAPIテストで作業効率が向上

APIテストによって、申込からオーソリまでの一連の流れを一瞬でテスト出来るようになったのも、エンジニアと同じチームとして取り組めているからこそだと思っています。一つ例を挙げると、APIテストにおけるバッチ処理の対応が挙げられます。オーソリまでの一連の流れの中には、いくつものバッチ処理が裏側で実行されています。それらはAPIでは操作できないものもありました。APIテストでコントロールできない場合は、テスト環境にセットしたスケジューラーがバッチを稼働させるのを待つ必要があります。こうなると、申込からオーソリまでの一連の流れは一瞬で実行できません。一連の流れを全て終わらせるのに丸1日かかってしまうこともあります。

「これじゃテストのスピードが出ないのでなんとかしたい!」と、APIテストを書いてるQAメンバーがエンジニアに相談し、テスト用にバッチ実行のAPIを作ってもらいました。そのやりとりを見ていて、「あー、アジャイルQAってスクラムチーム全体で取り組むから実現できるんだな!」と改めて感じることができました。

最近は、一度実行した手動テストから、リグレッションテスト用にSeleniumをベースにしたe2eの自動テストを書いて、常に実行するようにしています。開発対象の一連の処理が完成し、安定してきた今だからこそe2eの自動テストが作れるようになりました。

今後は、APIテスト、e2eテストの両方を増やしていき、リグレッションテストの高速化を図っていこうと思っています。

まとめ

今回、この連載にて、freeeカード Unlimited の開発チームとしてアジャイルQAの話ができる機会をいただけたことに感謝です。QAとして取り組んでることをもっとたくさん書きたいのですが、すでに結構な文字数になっているので、ここで終わりにします。

この連載も今回で終わりになりますが、2021/10/29 (金) 19:00〜のfreee Tech nightには、freeeカード Unlimited のエンジニアであるtabachainさんとimamuraさんが登場し、記事では語り尽くせなかった開発秘話を話してくれる予定です。私も楽しみです。

freee-tech-night.connpass.com

freeeカード Unlimitedの開発は、これからも続きます。チームのみんなで、より良いプロダクトに進化させていきますので、どうぞご期待ください。


freeeのQAでは仲間を募集しています。 アジャイルQAによって「マジ価値を届けきる」ためのリリースが速くなるという世界を一緒に実現しませんか! https://freeecommunity.force.com/jobs/s/detail/a4l1000000170iZAAQ

*1:クレジットカードのサービスには、オーソリと呼ばれる、お客さまのクレジットカードが決済可能かを確認する処理があります。カードで買い物をするとき、お店のカードリーダーにクレジットカードを差し込んだ直後に「通信中」になり、「カードを抜いてよい」という状態になるまでの間に内部でいろいろやっているのがオーソリです。