今回は直近のAndroidチームの品質改善の取り組みとして、ユニットテストを導入した件についてお話したいと思います。
- はじめに
- 実際にやった事
- ユニットテストを書く
- どこからユニットテストを書くか
- 技術スタック
- JUnit4 + Mockito-Kotlin + Truthを使用したテストコード
- カバレッジ率の可視化
- Jacocoの設定
- Jacocoの出力
- CIで自動でテストが実行される環境
- 導入したアクション
- ワークフロー
- ユニットテストを書く
- 最後に
今回は直近のAndroidチームの品質改善の取り組みとして、ユニットテストを導入した件についてお話したいと思います。
こちらはSafie Engineers' Blog! Advent Calendarの18日目の記事です。
こんにちは。セーフィー株式会社でバックエンドエンジニアをしている河津です。
私たちの会社は2023年10月27-28日に、PyCon APAC 2023への出展を行いました。この記事では、出展までの準備や当日の様子について紹介したいと思います!
メリー・クリスマス、セーフィーCTOの森本です。
こちらはSafie Engineers' Blog! Advent Calendarの25日目のエントリーです。
時間の経つのは早いもので、当社も少し前まで数十人でバタバタやっていたように感じていますが、それが今では400人を超え、いよいよ創業10年目に突入しました。
まだまだやりたいこと、やらなければならない事が山積みでそのために更に大きく成長していく必要も感じていますが、現在の姿も過去からの積み重ねですので、今後を考える上でもまずは年末のこのタイミングで今までの歴史を振り返ってみたいと思います。
セーフィー株式会社でバックエンド開発のテックリードをしております鈴木敦志と申します。セーフィー株式会社は創業から9年経過し、サービスの拡大と開発者の増加に伴う開発生産性の問題に直面しています。この問題の解消のため、職能横断型チームの再編成とコードベースの分割によるマイクロサービス化を進めています。
セーフィーのクラウドサービスはカメラ管理および映像閲覧のほか、業務システム、AI応用サービス、開発者向け機能および入退館管理システムなどで構成されており、サーバー/Webの開発者のほかモバイル/組み込み/QAエンジニアなど様々な職種が関わっています。チームは職能別に分かれており、チームごとに複数のプロジェクト (開発案件) に参加します。
開発組織の規模が増えるにつれ、様々な問題が明らかになってきました。
これらの問題を抜本的に解消するため、職能横断型チームの再編成とマイクロサービス化に取り組んでいます。
マイクロサービスとは、個別にデプロイ可能なサービスの集合体としてシステムを構成することで多人数による並列開発を効率化する手法です。今回は下記方針でマイクロサービス化およびチーム再編成を進めていきます。
マイクロサービスに関連する手法としてコードベースおよびデプロイ単位は単一のままモジュールのオーナーシップを明確化するモジュラーモノリスも知られており、マイクロサービス移行の前段階として、あるいはマイクロサービスの複雑さを回避しつつ大規模開発を行うために用いられます。弊社においてはモジュール間参照の規律を保つのが難しいと判断したため、マイクロサービスを選択しました。
既存コードベースのうち特にバックエンドのソフトウェアはAPIサーバー、デバイス接続サーバー、タスクキュー、バッチサーバー等多数のサーバーで構成され、いわゆるモノリスあるいは分散モノリスとなっています。これらのソフトウェアの機能を保ったままマイクロサービス化を進めるため、以下の手順を取ります。
場合によっては単純なAPI分割だけではサービスの分割ができず、再設計が必要な箇所があります。
例として、セーフィーではカメラごとに顧客とSaaS契約が締結され、契約プランにより使用できる機能が異なります。契約プランはフロントエンドチームの内製する管理ツールにより操作され、また社内の業務システム (Salesforce, Zuora等) と同期されています。チームをまたいだ複雑なデータの同期が行われ、またどこの情報が元データなのかがわかりづらくなっていました。
現在サーバー内では契約情報とそれにより有効化される機能が単一のRDBテーブルで表現されていますがこれを分離し、カメラの機能有効化API/ライフサイクル管理APIを業務システムチームに提供する形で連携することで、契約情報の一元管理を実現します。
セーフィーにおけるサービス規模・開発組織規模の増大に伴う開発生産性の問題に対応するため、既存システムのマイクロサービス移行を進めています。
現在セーフィー株式会社ではソフトウェアエンジニアを採用中です。マイクロサービスアーキテクチャや開発生産性の向上についてご興味のある方はぜひともご応募ください。
この記事は Safie Engineers' Blog! Advent Calendar 23日目の記事です。
企画本部のマネジメントをしております植松です。
本テックブログももうすぐ丸4年を迎えます(祝!)。テックブログのごく初期にプロダクト(商品)開発の歴史 を投稿してからもSafieは様々なプロダクトを世に出してきました。
そこで、本記事ではこの4年間でリリースしてきたプロダクト群の一部紹介と、今後の展望について書いてみたいと思います。
2020年迄はエンドユーザーやパートナーの方向けの製品を作っていましたが、開発者向けの初のプロダクトとして2021年2月に Safie API をリリースしました。 これにより、お客様の既存の業務ツールに我々の映像を組み込んでいただいたり、画像解析をお客様側で行っていただく、など、お客様側の使い方の幅が格段に広がりました。
元々の企画の始まりはパートナー様向けの案件があり、それは画像取得しViewerへのイベント登録をパートナー様側で画像解析して登録する、というものでしたが、我々のサービスとしては汎用化を見据え同時にストリーミングAPIを準備しました。かなりタイトなスケジュールでしたがなんとかリリースにこぎつける事ができました。このパートナー様向け機能については継続的に多くの台数使っていただいて売上高も順調に伸ばしており、今後のAPI利用の足がかりにもなったと思っています。
当初はβ版として限られたユーザにのみ使っていただいてましたが、今年頭から晴れてDeveloper(Safie API v2) として生まれ変わり、登録したユーザは誰でも使っていただけるようになっています。このブログではAPIの使い方 や、APIの便利なユースケース も紹介していますので、そちらもぜひご覧いただければと思います。
ウェアラブルカメラPocketシリーズは2020年にリリースしたPocket2 , 2023年にリリースした Pocket2 Plus と着実な進化を遂げていますので、その歴史について簡単に記したいと思います。
2020年一番の出来事は何と言っても新型コロナウイルスでした。弊社のサービスもコロナウイルス対策最前線の病院などで活用され、その事例は英国のBBCニュースでも取り上げられました。 そこに遠隔業務の切り札として満を持して2020年7月に登場したのが「Safie Pocket2」です。
初代Pocketは、所謂MVP(Minimum Value Product)と呼ばれる仮説検証のため、市販のウェアラブルカメラのソフトウェアをカスタマイズしたものです。静止画スナップショット機能やWebRTCによるリアルタイム双方向音声通話の実現といった新開発機能を盛り込んだ、新しいサービスでした。 私が入社した頃には既に初代Pocketは開発が終わっていましたので、伝え聞くところにはなりますが、カメラ本体に加えて無線LANルーターやモバイルバッテリーが別途必要で、ご利用いただいたユーザー様からもやはり、重い、持ち運びしにくい、というフィードバックを数多くいただいていたようです。そこで、エンジニアが、インターネットで見つけた世界中のウェアラブルカメラメーカー(英語では "body worn camera" と呼ばれます)に手当たり次第問い合わせをし、国内外のこれといった展示会を巡った末に実現したのが「Safie Pocket2」でした。
当初は3月に製造して4月販売開始の予定でした。新型コロナウィルスの脅威が日に日に高まり、外出自粛やリモート勤務が行われる中で、Pocket2をご活用いただけるはず、だったのですが、なんとPocket2の工場まで閉鎖されてしまったのです。メーカーさんが何とか頑張って工場を再開したのに部材も人も揃わない。組立が完成しても、物流が混乱しているので発送したカメラが届かない。お待ちいただいていた皆様にようやくお届けすることができたのは、3カ月遅れの7月になってしまいました。予定よりも遅れてしまいましたが、ユーザー様にはご満足いただき、さらにはテレビ東京 WBSで取り上げていただくなど、社会的にも注目される商品となっていきました。
ここで歩みをとめたわけではなく、使っていただいている中で様々な品質課題や改善要望が上がってきておりそれらを解消すべく、今年の5月に新たにPocket2 Plus をリリース。ウェアラブルならではの「手ぶれ補正」や、音声品質改善のための「スピーカー通話」、ウェアラブルといいながらも実際には固定して長時間利用されている方も多いため「モバイル給電」などの機能を搭載。より痒いところに手が届く、使い勝手の良さを追求したプロダクトとなっています。来年は海外にも羽ばたく予定です。
弊社CEOの佐渡島が創業当時から何度も語っていた「かしこくなるカメラ」の実現。Safie初のエッジAIカメラである Safie One は2022年9月にリリースされましたが、このリリースも苦難の連続でした。
CC2 / CC2Lという主力プロダクトの製造会社に開発依頼し、商品コンセプト、ハードウェアデザインについてデザイナーの方とコンセプト固めをして何度もやり取りを行い、試行錯誤を行いながらデザインを決めていきました。その後試作機が届いたのですが、SoCから発生する熱問題(AIを定常的に使っていると熱暴走して停止してしまう)・カチカチ音問題(カメラ内部で音が定常的に鳴る)・IrLED反射問題(レンズの下部に反射して映像にゴーストが発生してしまう)... などなど、大きな課題から小さな課題まで膨大な件数を、1つ1つ潰していきながらプロダクトリリース。
当初の構想から足掛け2年。やっとの思いでリリースした後も安定して量産にこぎつけるまでに様々な苦労がありましたが、現在はぽん置き出来る手頃なAIカメラとしてセーフィーの主力商品となっています。
当然ながら、エッジAIカメラというからには同時並行でAIアプリも開発が必要です。SPDP という主に店舗で使っていただくための立ち入り検知・通過人数カウント・立ち入りカウントがパッケージされたAIアプリを同時リリースしているのですが、これも途中で1度UI部分の仕様変更に伴った作り直しが入り、今の形となりました。もちろんViewerからスムーズに使える使い勝手の良さは他のアプリと同じ思想で作られています。
まだまだ書きたいプロダクトは色々あるのですが、長くなってしまうので改めての機会とさせていただき、ここでは今後の展望を記したいと思います。 セーフィーでは「映像から未来をつくる」をビジョンに掲げ、ユーザーの課題を解決するプロダクトを創業当初から作り続けて来ました。今後は、
といったあたりを中心に、セーフィーを使ってくださる方を増やし、セーフィーの映像を使って課題解決出来ることをどんどん増やしていきたいと考えています。
最後に、セーフィーでは新しいプロダクト、サービス、ソリューションを一緒につくっていただけるエンジニアやプロダクトマネージャーを大募集しています。面白そうだな、と思った方はカジュアルに話してみたい、で結構ですので是非コンタクトいただけると幸いです!
この記事はSafie Engineers' Blog! Advent Calendar 22日目の記事です。
セーフィー株式会社でソフトウェアエンジニアをしている大場です。
2022年10月に子供が生まれました。あれから1年という月日が経ち、育児の大変さを実感してきました。ソフトウェアエンジニアという職種はPC1台とネット環境さえあれば場所を選ばないため、コロナ禍もあり、リモートワークを中心として育児と仕事の両立を図りました。
本稿では育児の中で培ってきたあやし方や寝かしつけ方の回顧録を多少のエンジニア視点を交えてまとめておきます。尚、子供によって合う合わないはありますので、必勝の攻略法は(おそらく)存在しないことをご承知おきください。
この記事は Safie Engineers' Blog! Advent Calendar 2023 の21日目の記事です。
セーフィー株式会社で画像認識AIの開発エンジニアをしている木村(駿)です。主に、エッジAI搭載カメラで動作する人やモノを検出するアプリケーションの開発を行っています。
このAIカメラを使って、弊社では指定したエリアへの人の侵入を検知するサービスや混雑度合いを数値化するために滞留人数をカウントするサービスなどを提供しています。
これらのサービスが、必要な基準や要件を満たしているかどうかを確認するため、QA (Quarity Assureance) 評価を実施しています。具体的には、AIの検出性能や追跡性能のみを評価するのではなく、実際にユーザーが見る値(侵入検知のフラグやカウント数など)が正しく機能しているかを評価します。
このQA評価をするには評価用データ、つまりアノテーションされたデータが必要になりますが、動画のアノテーションデータの作成は非常に大変です。仮にFPS30の10分の動画に対してアノテーションデータを作ろうとすると、1フレームごとに5人映っていれば 30fps×600sec×5=90000個の矩形を手作業でつける必要があります。バリエーションを作ろうと思うと複数の動画のアノテーションデータが必要で、さらに大変です。
そこで、CGで映像を作成し、自動でアノテーションデータを作成できないかと考えました。 今回は、ゲームエンジンであるUnityを使ったCG映像の作成方法と、CGの人物に対して人検知を行った結果および簡易的なQA評価の結果をご紹介します。
続きを読むこの記事はSafie Engineers' Blog! Advent Calendar 20日目の記事です
はじめまして、セーフィー株式会社でSafieの映像サービスを支えるSaaSプラットフォーム プロダクト群のPdMをマネジメントしているマネージャーの光田です。
本日はPdM組織のマネジメントについて、発生した課題と解決のために取り組んでみた施策についてお話しさせていただきます。
この記事はSafie Engineers' Blog! Advent Calendar 19日目の記事です
こんにちは。2023年3月にセーフィーにジョインした入社一年目のQCDグループの森重です。
入社してからはカメラの対応機種拡大やマイページ、モバイルアプリと様々な領域・プロダクトにQAとして携わっていて、テスト設計や手動テストの実行だけでなく自動テストにも取り組んでいます。
この記事ではQCDグループで取り組んでいる自動化、特にMagicPodに焦点を当てて、QCDグループがMagicPodでどんなテストを自動化しているかをお話できればと思います。
そもそもMagicPodとはなんぞや?という方もいると思うので、簡単にツールについて説明します。
MagicPodは有償のテスト自動化ツールでWeb・モバイルに対応したE2Eテスト自動化ツールとなっています。
他の自動テストツールと比べて優れていると思うのは、自動テストの実行回数に制限がない点、メンテナンス性を確保し易い点です。
実行回数に制限がないので、毎日自動テストを実行したいプロダクトに向いているツールと言えます。
次にQCDグループで自動化に取り組んでいる目的ですが、これはテスト実行回数増加と広範囲化でバグの早期検出とバグ検出件数増加のためです。
MagicPodに決まったテストを毎日実行させることでエラーを早期検出し、今までリスクベースで切り捨てていたテストもやってもらうことで、カバーできる範囲を増やすようにしています。
対象のテストは、ずばりリグレッションテストになります。
テスト対象の変更が少なくメンテナンス性の確保が比較的容易なことが大きな理由です。逆にE2Eテストで自動化しないほうが良いのは頻繁に変更が入る新規機能だったり、変更が入りやすい画面を対象としているテストケースです。
実際の画面をお見せするとこんな感じです。失敗しているテストケースもありますが、定期実行して毎日結果をモニタリングしています。
メンテナンスはチームで毎日持ち回りで担当していて、日々やっているという感じです。
少し話はそれてしまいますが、先日のMagicPodのメジャーバージョンアップで追加されたアナリティクスで自動テストのヘルススコアを算出してくれます。参考までにマイページのヘルススコアを紹介しておきます。
マイページ
マイページではヘルススコア89です。このプロジェクトはQCDグループの中では後発で自動化を勧めており、パイロットプロジェクトでの運用経験からメンテナンス性を重視したテストケース作成をしています。
特にMagicPodの機能の中でも共有ステップ・変数は様々なテストケースの中の手順を一つの共有ステップで集約することで、テストケースのメンテナンス性・可読性が狙えるため積極的に活用しています。
一通りテスト対象や運用については書き終わりましたのでMagicPodを自動テストに取り入れたことで感じているメリットと使い続ける上での課題についてもここに書いておきます。
MagicPodを導入したことで感じたメリット
早期バグ検出に役立つ
テスト環境を広げたことによるバグ検出ができた
メリットですが、こちらはMagicPodを導入した当初の狙い通り、バグ検出関連の恩恵が大きいです。
MagicPodを使い続ける上での課題
一方課題ですが、MagicPod利用上のルールやそのデータを活用できていないことが多く挙げられています。今後の改善活動として取り組んでいく予定です。
以上、QCDグループで使っているMagicPodについて紹介させていただきました。
当初狙っていた効果は一定得られているものの、まだまだ課題が残っていますので、継続して改善が必要そうです。
MagicPodにとどまらずテスト自動化について今後もテックブログで発信していきますので、よろしくお願いします。
この記事はSafie Engineers' Blog! Advent Calendar16日目の記事です。
セーフィー株式会社 開発本部 第3開発部 AIVisionグループで画像認識AIの開発エンジニアをしている土井 慎也です。
セーフィーには2023年1月に入社し、もうすぐ1年が経とうとしています。
今年を思い返せば、生成系AIを中心とした、AI界隈の発展がすごい1年でした。
毎日のようにいろんな技術が発表されて、使えそうなものはすぐにOSSに実装されていて、技術進歩の速度がものすごく速く感じました。
さて、今回はそんなAI界隈で使われているWEB UIツールのGradioについて軽く紹介したいと思います。
Gradioは、機械学習モデルを簡単にデモするためのPythonライブラリです。Gradioを使用すると、モデルの入力と出力に対応するインターフェースを簡単に作成でき、モデルを試すためのWeb UIを生成できます。これにより、モデルの挙動を迅速に確認したり、他の人と共有したりすることが可能になります。
stable diffusionで有名なWEB UIの一つである、stable-diffusion-webuiもGradioを使用しています。
AI用のGithubともいえるHuggingFaceとの親和性も高く、HuggingFaceで公開されているものを簡単に試すことができたり、逆に公開することもできます。
また、機械学習モデルに関係なくても、Gradioには色々なインターフェイスが用意されているので、簡易的なWeb UIが簡単に実装できます。
Gradioは日々アップデートで変化しているため、今回はあまり深くは解説せず、基本的な紹介といたします。
python3.8以上が実行可能な環境を用意します。
pip install gradio
import gradio as gr def greet(name): return "Hello " + name + "!" demo = gr.Interface(fn=greet, inputs="text", outputs="text") demo.launch()
こんな感じに、少ないコードで、簡単にWeb UIを作成することができます。 HTMLやCSS、jsなどを意識する必要はありません!
https://gradio-hello-world.hf.space
Gradioには認証機能があります。
demo.launch(auth=auth_function)
とすることで、認証機能を有効にすることができます。
認証機能のベースはFastAPIのOAuth2PasswordRequestFormを使用しているようです。
import gradio as gr def greet(name): return "Hello " + name + "!" # 認証機能 def auth(user_name, password): # 例: ユーザー名とパスワード(反転)が一致したら認証OK # 実際にはDBと連携して認証するなどの処理が必要 if user_name == password[::-1] : return True else: return False demo = gr.Interface(fn=greet, inputs="text", outputs="text") # 認証機能を有効にする demo.launch(auth=auth)
gr.Interfaceでlive = True
を指定すると、入力値を変更するたびに、リアルタイムで出力が更新されます。
import gradio as gr def calculator(num1, operation, num2): if operation == "add": return num1 + num2 elif operation == "subtract": return num1 - num2 elif operation == "multiply": return num1 * num2 elif operation == "divide": return num1 / num2 demo = gr.Interface( calculator, [ "number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number" ], "number", live=True, ) demo.launch()
https://gradio-calculator-live.hf.space
Blocksを使用すると、より細かくレイアウトを指定することができます。
また、イベントリスナーを使用することで、ボタンをクリックしたときの処理を指定することができます。
Hello World!をBlocksを使用して書き換えると、以下のようになります。
import gradio as gr def greet(name): return "Hello " + name + "!" # Block with gr.Blocks() as demo: name = gr.Textbox(label="Name") output = gr.Textbox(label="Output Box") greet_btn = gr.Button("Greet") # イベントリスナー greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet") demo.launch()
https://gradio-hello-blocks.hf.space
詳しいBlocksとイベントリスナーについて
詳しいレイアウトの方法について
コンポーネントで用意されているもので一般的なものだと、text, number, checkbox, radio, dropdown, file, button, slider, などがあり、そのほかには、画像や音声、動画、グラフ、チャットなどの様々なンポーネントが用意してあります。
コンポーネントの種類
また、Gradioのメジャーアップデートでカスタムコンポーネントも最近追加されたので、今後ユーザーによって多くのカスタムコンポーネントが実装されていき、より種類が豊富になっていくと思います。
カスタムコンポーネントの作成方法
最近発表され、話題になっている動画生成AI、MagicAnimateのWebUIになります。
zcxu-eric-magicanimate.hf.space
Gradioが用意しているコンポーネントで事足りる場合、それらを組み合わせることで、AIに関わらずPythonで作られたソフトウェアは簡単にWeb UIを作成することができます。
フロントエンドの知識がなくても、簡単かつ迅速にWeb UIを作成することができるので、Pythonで開発したものをすぐにWebアプリ化したいAIエンジニアなどにとっては、非常に便利なツールだと思います。
セーフィーでも、Gradioを使用して社内向けに気軽にAIを試せるデモ環境を迅速に用意し、PoCやその他検証などに活用できないかを現在検証しています。
© Safie Inc.