Leanerのテスト事情(2022年2月版)
こんにちは、 Leaner Technologies の石渡(@mishiwata1015)です。
下の子(2 歳半)がついこないだ 3 語文話せるようになったと思ったら、あっという間に 4 語、たまに 5 語文まで話せるようになっていて圧倒的な成長速度に驚いています。
今日はLeaner見積のテストの現状を赤裸々にお伝えしつつ、今後の取り組み予定についてお話します。
Leaner見積の技術スタック
まずは、Leaner 見積の技術スタック・アーキテクチャについて簡単に紹介します。
Leaner の技術スタック紹介(2021年7月版) でも紹介していますが、ここから大きくは変わっていません。
バックエンドは Rails API モードで、ECS Fargate 上で稼働しています。
Rails のバージョンは 6.1.4.6 で、 Ruby は 3.0.3 です。
フロントエンドは Vue2 / Nuxt2 の SPA で、Amplify Console を使って CloudFront + S3 で配信しています。
バックエンドのサーバ 1 つに対して、以下 3 つの SPA が存在する構成です。
- 🙎♂️ バイヤー画面: 見積依頼・発注する買い手向けの SPA
- 👨🏭 サプライヤー画面: 見積回答・納品する売り手向けの SPA
- 🙍♀️ オペレーター画面: Leaner 社内向け管理画面の SPA
Leaner 見積は見積業務の効率化を目的としたプロダクトで、バイヤー企業がバイヤー画面、サプライヤー企業がサプライヤー画面をそれぞれ使用して見積業務を行います。見積業務の全体像のイメージは以下の通りです。
バックエンドのテスト
Rails API モードに対し、RSpec によるテストを行っています。
エンドポイント単位の Request Spec で、データの更新内容やメール送信の有無まで一通り確認する方針としています。
Request Spec でレスポンス以外の内容まで検査するのはやりすぎかなとは思いつつ、簡単なエンドポイントは Request Spec のみで済むため、Model Spec との兼ね合いやどこまでモックにするかなど考えることが減って結構楽です。
また、 rspec-request_describerを導入して、Request Spec を書きやすくする工夫をしています。
describe
と it
内で違うエンドポイントを指してる、みたいな悲しい事態を防げたり、params 等の指定が楽になるのでおすすめです。
describe 'PUT /api/v1/users/:id' do
let(:id) { user.id }
let(:user) { create(:user, name: '更新前の名前') }
let(:params) do
{
name: '更新後の名前',
}
end
it '更新できる' do
# これで `subject` が `put("/api/v1/users/#{user.id}", params: params)` になる
expect { subject }.to change { user.reload.name }.from('更新前の名前').to('更新後の名前')
expect(response.status).to eq(200)
expect(response.body).to eq('...')
end
end
複雑なエンドポイントの場合、さらにテストを追加しています。
Usecase 層を設けているので Usecase のテストとしてパターン網羅を確認したり、 Model Spec に単体テストを追加することで網羅性を高めています。
カバレッジの推移は以下の通りです。
日付 | カバレッジ |
---|---|
2021-06 | 79.13% |
2021-09 | 91.54% |
2021-12 | 92.39% |
2021-02(現在) | 93.56% |
2021 年 6 月頃は 70%後半程度だったんですが、そこから@nomnel の頑張りによってカバレッジ 90%を達成しました。
2022 年 2 月時点ではカバレッジ 93.5%程度となっています。じわじわ上がってきてますね。
まだ古いコードのテストは微妙なのも残っているんですが、手を入れる度にテストを充実させていっています。カバレッジの数字自体に意味はないですが、テストの網羅性を測る指標の 1 つとして重要だと考えています。
フロントエンドのテスト
ぶっちゃけほとんどテストがありません😇
一部のコンポーネント・ロジックには Jest によるテストがありますが、本当に一部だけの状態です。もともと Vuetify をベースにしたシンプルな SPA だったため、そこまで大きな問題にはなっていませんでした。
しかし、フロントエンドにも複雑なロジックやインタラクティブな UI が増えてきていて、手動テストではつらくなってきたのでなんとかしたいところです。
e2eテスト
e2e テストを行うために Cypress を導入しています。
3 つの SPA ごとに、一通りの機能を確認する e2e テストを作成しています。
代表的なユースケースは網羅していますが、全機能網羅できてるわけではありません。
例えば、サインアップなどメールを織り交ぜたユースケースの確認までは現状カバーできていません。
また、以下のような各 SPA をまたいだ一連のシナリオテストもまだ自動化できていません。
- 🙎♂️ バイヤー画面で見積依頼する
- 👨🏭 サプライヤー画面で見積回答を提出する
- 🙎♂️ バイヤー画面で見積回答を確認する...
現状は、e2e テスト用の seed データを用意しておいて、各 SPA の e2e テストでは seed データを参照する形にしています。
特定の機能の e2e テストは自動化できていますが、まだまだこのあたりの整備が必要、という状況です。
今後の取り組み
とにかく、e2eテストを充実させていきたいと考えています。
フロントエンドでも金額を扱う部分があるので、最低限そこはしっかりテストを書いていきたいです。
現在、1 日に数回デプロイを行っています。デプロイ回数の 4 週間移動平均が以下のグラフです。
2021 年 9 月頃からガッと上がっています。
この開発スピードと品質を両立するため、自動化できるものはできる限り自動化するよう工夫していきたいです。
あと、個人的にアプリケーションエンジニアが e2e テストを書くのはとても重要なことだと思っています。ユーザーがある業務を行うときにプロダクト上でどんな操作をするのか、改めて考える機会になるからです。
e2e テストを通して業務を詳しく知ることは適切な設計にも役立つと考えています。
現在 Leaner に QA や QC の専任はいないため、誰かが QA のロールを担う必要があります。
エンジニアや Biz 一人一人がプロダクトの品質について真剣に考えるチームでありたいですね。
まとめ
- バックエンドのテストはレイヤーごとのテスト責務をいい感じに分割できており、カバレッジも 90%を超えている💮
- フロントエンドのテストはほとんど実施できていない😇
- これからは e2e テストの充実に取り組む(手動テストがつらくなってきた!)
- アプリケーションエンジニアが e2e テストを書くのは大事
宣伝
Leaner Technologies ではテストに興味のあるエンジニアを募集しています!
Discussion