デイリー日々

生活ライフ

自動テストと初期化 - (3)初期データの勘所

※続きものです。前のやつはコチラ、最初の記事はコチラです!

はじめに

初期化がいかに大事なのか、2記事に渡って書いてきました。
ようやく、実際にどうするべきか?というところを書いていきます。

また「世界」の話が出ます。別のいい言い方が思い浮かばないので…ご容赦ください!

データの捉え方

ズバリ、ルートオブジェクトがあるかどうかによって並列性などの考え方が変わってきます。

ルートオブジェクトあり

一つルートとなる何かがあり、それに紐づいてデータができているパターンです。逆に言えば、全てのデータをたどると、最終的にルートとなるデータにたどり着きます。
toBのSaaSのプロダクトだとこの形式が多いかもしれません。

プロダクト例 ルートオブジェクト
病院カルテシステム 病院
BIツール 企業/法人

この場合、ルートオブジェクトが異なるものは独立しているので、それぞれの「世界」にそれぞれルートオブジェクトがあり、紐づくデータが含まれるわけです。このパターンは並列化も容易です。

それぞれの「世界」が干渉しないため、「世界」ごとにconstruct / destructしてテストを実施することができます。

ルートオブジェクトなし

分散型、とでもいうのでしょうか。ある「世界」にN個のオブジェクトがあったり、オブジェクトとオブジェクトがN対Nで結びついたりしているものです。

プロダクト例
証券口座システム
社内管理システム

私が業務で扱っているのは「ルートオブジェクトあり」のものなので、この「ルートオブジェクトなし」のものについてはあまり明るくないです…。
今扱っているプロダクトに「社内管理画面」があり、そのテストの知見を少し書きます。

コチラは若干面倒で、「世界」を区切るのが面倒です。そのため、このパターンだと実行順序性などを考慮する必要があります。

例えば、BIツールSaaSプロダクトの導入企業管理システムで「導入社名で検索する」ようなユースケースがあると思います。このとき、テストを並列実行すると、各テストストリームで似た名前の社名を使用している場合にテスト実行のコンテキストによって表示される導入社の件数が異なることがありえます。

結局どうしたらいいの?

基本戦略は大体こんな感じです。

  • ルートオブジェクトあり / なしで分ける
    • あり: 「世界」ごとにシナリオを分け、並列実行する
    • なし
      • 並列実行せず、ルートオブジェクトなしシナリオだけ直列実行する(最低限にする)
      • プロダクト環境も並列化し、テストストリームごとに一つのプロダクト環境をアサインし、干渉しないようにする

ルートオブジェクトがあるものは並列化し放題なので、基本的にルートオブジェクトがあるものを起点に考えるといいと思います。
また、ルートオブジェクトなしパターンでも、細かくみていけばルートオブジェクトありパターンにすることができます。例えば証券口座システムでも、一つの証券口座をルートオブジェクトとみなし、その情報の設定などをテストすることができます。
さらに、ルートオブジェクトありパターンでも、ルートオブジェクトが常に同種とは限らないこともあります。電子カルテシステムなら通常は病院がルートオブジェクトですが、医療法人(複数病院を保持する)をルートオブジェクトとすることも考えられますし、病院内の1つのカルテをルートオブジェクトと考えて診断内容・投薬内容などを記載することも考えられます。

実例

電子カルテシステムのテストで、setupをスクリプト的に行なったものとして記載します。今私が携わるプロダクトでも同じように初期化スクリプトを作成しています。

/* ルートオブジェクト(病院)のinsert */
const hospital_id = await DB.insert(
  'hospitals',
  [
    {
      'name': 'dummy病院',
      ...
    },
  ]
);
/* 付帯データのinsert */
// (病院の)医師
const doctor_id = await DB.insert(
  'doctors',
  [
    {
      'name': 'ドクターX',
      hospital_id,
      ...
    }
  ]
);
// (病院の)患者
const patient_id = await DB.insert(
  'patients',
  [
    {
      'name': '患者A',
      hospital_id,
      ...
    }
  ]
);
// (患者の)カルテ
const karte_id = await DB.insert(
  'kartes',
  [
    {
      hospital_id,
      patient_id,
      ...
    }
  ]
);

ルートオブジェクト(病院)から芋づる式に付帯データまでつながっているのがわかるかと思います。逆に言えば、このようにルートオブジェクトから全てがつながっていなければ、ルートオブジェクトなしパターンです。

なお、このとき、teardownは逆順(付帯データ→ルートオブジェクト)としたほうがいいです。ID類を内部にストアしておいて、自動teardownを作成することもできます。
というより、そもそもteardownをする必要もないかもしれません。全て個別の「世界」で完結していれば不要です!

いかがでしたか?

初期化について3記事に渡って書いてきました。さすがに読んでて疲れますね〜。でもここに書いたのがほぼ全てです。

本当に、初期化を制すことができれば、自動テストも怖くないです。初期化がうまくできれば、あとはテスト内容に注力できます。これは結構強力だと思うんです。特にUI使うテストだと安定化させるために何回も実行する必要があるので、再実行が容易なことが実質必須です。そういったことも結局初期化がうまくできているかどうかです。

というわけで誰かの役に立てたらいいなと思います。幸あれ!

自動テストと初期化 - (2)並列実行性・再実行性

※続きものです。前のやつはコチラ、次のやつはコチラ

はじめに

自動テストを正しく並列実行できるよう、容易に再実行できるようにするためには、テスト開始時の初期化をうまくやることが重要です。
私の今までの経験から、どうすればうまくいきやすいか書いておきます。

並列実行性・再実行性の実際

並列実行性

並列実行ってそんなに重要?と思う方もいると思います。めっちゃ重要です。

テスト実行時間を考えたとき、直列でのみ実行していると、リニアに伸びていきます。
UIベースのテストであれば、1シナリオ30秒程度として、120シナリオで1時間になります。
120シナリオも作らない?自動化が進むにつれ120シナリオなんてすぐに到達します。
1時間くらいだったら待つ?システム全停止してhotfixを入れて、急がないとビジネス的価値を毀損するのに待つことができますか?

並列実行を前提としていれば、リソース量さえ増やせれば、実行時間は(総テスト時間) / (並列数)で済みます。
ちなみに、現在携わっているプロダクトのテストは、200シナリオ4並列で30分を切ります。分割・最適化の最中なので、それが完了すればもっと並列数を増やしてもっと短時間で実行できるようになり、CIでも軽量に回せるようになります。

そして、忘れてはいけないのは、並列実行前提で作られていないテストを並列実行するのはかなり厳しいということです。実質無理です。
実行順に依存していたり、データ構造に依存していたり、失敗する理由が大量にあります。

ということで、最初から並列実行できることを前提とした初期化システムにしておいた方がいいです。自動テストが成功するかどうか、ここにかかっていると言っても過言ではないです。

再実行性

再実行ってそんなに重要?と思う方もいると思います。めっちゃ重要です。

UIベースのテストはどんなに丁寧に作ってもFlakyです。APIのレスポンスが100ms遅延しただけでFAILします。0.1秒ですよ!
Flakinessをテストで吸収するための最も手っ取り早い方法が、リトライ設定を入れることです。不安定なテストでも3回もリトライすればそれなりに動くはずです。

しかし、ここもまた初期化の壁が立ちはだかります。固定IDでデータをinsertして初期化する仕組みにしていると、再実行時には「すでにあるよ」エラーになります。upsertでうまく避けるようにしたとしても、前回の実行で何かレコードができていると、勝手にリレーションができてしまい、表示が変わってFAILします。

さらに、テストを作っている間、動かして様子を見て変更して動かして…ということを繰り返します。そのとき、簡単に再実行できる仕組みを作っておかないと、本当に面倒です。以前はテスト実行後にDBを自動で吹っ飛ばすようにしたこともありましたが、そうするとDBコンテナが正しく立ち上がるまでテストできず、イライラしました。

ということで、最初から再実行できることを前提とした初期化システムにしておいた方がいいです。自動テストが成功するかどうか、ここにもかかっていると言っても過言ではないです。

実際どうするべきか

前回の記事の「世界」を用います。表現として好みでなければ、「状態」などと読み替えてください。

「世界」を構築する

簡単に言うと、「テスト実行ごとに独立した『世界』を作り出し、その中でテストが完結するようにする」と言うのが要点です。図にするとこんな感じです。

2並列実行してストリームが2つ生成されると、(テストランナーにもよりますが)各ストリームに適宜テストシナリオが割り当てられ、実行されます。そのシナリオごとに、「世界」が生成されます。その「世界」には、シナリオを実現できる最低限のデータを設定します。
前回の記事に倣った例(カレンダーの月曜始まり/日曜始まりをトグル)であれば、「カレンダーを表示できるユーザー」だったり、「カレンダーそのもの」だったり、それから「月曜始まり/日曜始まりを設定する何かしらのデータ」とか、です。

そして、重要なのは、これらの「世界」は全て独立しているというのが重要です。それぞれの「世界」が独立していれば、並列実行時に順序を組み替えたり、並列数を増やしたり、FAILしたときに再実行しても問題なく実行できます。

また、同じシナリオであっても、実行されるごとに別の「世界」が生成されることが大事です。テストがFAILし、再実行されたときのことを考えます。

世界1でFAILして、その再実行した世界1'が全く別のものであれば、全く別のテストと同様に実行することができます。そうでないと、例えば「カレンダーに予定を登録する」のようなステップがある場合、「世界1でFAILする前に入力した予定が世界1'で出てきてしまう」ようなことが起こりえます。こうなると、テストがFAILするのはもちろん、FAILしたときの原因の分析などが非常に面倒になります。

どうしたら実現できるか?

動的にデータを作成・挿入するに尽きます。

かつてCSVでデータを作成することも試しましたが、その場合固定IDとなってしまい、再実行時など「独立した『世界』」を初期化時に作成することができませんでした。したがって、何かしらスクリプト等で動的に作成した方がいいです。私は現状、TypeScriptで動的importを用いて実現しています。

カレンダーの例では、このような感じになるでしょうか。

  • ユーザーを挿入する: user_id を取得する
  • カレンダーを挿入する: user_id を用いる → calendar_id を取得する
  • 月曜始まり設定を挿入する: calendar_id を用いる

また、「基本的なデータをまとめておいた『世界』のスクリプト」を用意しておく、というのも便利です。そうすれば、今回のカレンダーの例は「月曜始まり設定を挿入する」くらいでOKになります。

いかがでしたか?

より具体的に「世界」を構成することによって、並列実行性・再実行性を担保し、テスト開始時の初期化をうまくやる方法について記載しました。
そして、今回記載したことは、現に私が運用して強力さを体感しています。開発エンジニアからの評価も良好です。

次は初期データ構成の勘所について書こうと思います。今扱っているプロダクトでしか実例がないので自信がない部分もありますが…まあ大丈夫でしょうたぶん〜!

自動テストと初期化 - (1)なぜ初期化が重要なのか?ストーリー分割の観点から

※続きものです。次のやつはコチラ、最後のやつはコチラ

はじめに

以前投稿した、登壇内容のセルフライナーノーツ記事で、「初期化大事だよ」って話をしました。今回はその、もうちょい詳細です。

blog.dashi-no-ajiwai.net

基本的にはUIベースのE2E的なテストの場合の話ですが、他のテスト(APIテストや単体テスト)にも適用できると思います。

あったらうれしい事前知識

そんなに難しい話にはならないつもりですが、「状態遷移図」「プロセスフローダイアグラム(PFD)」あたりご存知だとわかりやすいと思います。
それぞれ「各状態がイベントを介してつながっている図」「プロセスが成果物を介してフローでつながっている図」くらいの認識があればOKです。

自動テストにおける初期化・初期データとは

自動テストのパターンには、3Aと呼ばれるArrange - Act - Assertのパターンだったり、BDD的なGiven - When - Thenのパターンをよく見聞きすると思います。
どちらも、「被テスト状況を生み出す」というところから始まります。これがこの記事で指す初期化です。

一つ注意しておくと、「初期化」と「初期データ」は必ずしも同一ではありません。
データがない状態で画面から操作してデータを作成するのも「初期化」です。しかし、この方法はUIベースのE2E的なテストでは避けておくべきです。イタズラにFlakinessを増すだけです。
というわけで、ここから先は「初期化」は「初期データをうまく構成することで(初期化操作は最少にして)被テスト状況を生み出す」ことだと考えてください。

テストシナリオ(ストーリー)を分割する

あるアプリ内のカレンダーで、「設定をトグルして、日曜始まり・月曜始まりが変更できる」ということをテストすると、こうなります。

非常にアレだなあ、という感じですが、ただただ「人の操作をシナリオに起こしたもの」だと、こんな感じになりえますよね?

で、このままのシナリオだと、Flakinessが下げられません。Flakinessは確率的にステップ数乗で表されるので、基本的にステップ数が少ない方が有利です。「初期データをうまく構成して被テスト状況を生み出す」ことを前提に、シナリオを細かいストーリーに分割します。

この通り、初期化がうまくできれば、テストシナリオが細かいストーリーに切り出せて、Flakinessも下げられて、HAPPYですね!

「世界」?

ここで私個人の考え方なのですが、「世界」というものを用いています。
状態遷移図の各状態と捉えてもらってもいいですし、PFDの「成果物」を抽象化したものと思ってもらってかまいません。
もしくは群論とか圏論とか数学的な捉え方をしてもらってもいいと思います。

特にレガシーシステムにおいては、「どの操作をするとDBのどのテーブルのどのレコードの値が変わるかわからない」ということがあると思います。
それを諦めつつ初期データをうまく作成するために、「ある操作をした後のDBをダンプしておき、それを次のテストの初期状態とする」ことがあります。PFDの「成果物」よりもブラックボックスで曖昧なため、これを「世界」と表現している、と思ってください。

ということで「世界」はブラックボックスではありますが、ストーリーを細かくするにつれ、操作前後の「世界」の差分は小さくなっていくはずです。そうすると、「どの操作をするとDBのどのテーブルのどのレコードの値が変わるか」ということがわかってきます。これがわかると、レガシーシステムにおいてはかなり有益です。

「世界」と expect / assert

先ほど切り出した細かいストーリーについて、「世界」を起点に整理してみます。

日曜始まりの「世界」でカレンダーを開けば日曜始まりになっている、月曜始まりの「世界」でカレンダーを開けば月曜始まりになっている、はずです。
ということは、「日曜始まりの『世界』になっている」ことを確認できれば、「カレンダーが日曜始まりになっている」といえる、ということです。

これの嬉しさは、「画面の表示をアサーションしなくとも、DBのレコードを確認するなどすればOKとみなせる」ことにあります。
E2E的なテストの難しさは、「何をもってOKとみなすか」というところにあります。「〜という文言が表示されている」であれば明確ですが、上記の例のカレンダーのようなものであれば「th要素の1番目が〜」などと一気にしゃらくさくなります。明示的でないステップはFlakinessも上がりがちです。
「日曜始まりの『世界』になっているとき、カレンダーが日曜始まりになっている」ことを1つのテストシナリオで確認できれば、残りのテストシナリオでは「日曜始まりの『世界』になっている」ことを確認できれば良くなります。このようにできると、テストシナリオ群全体が一気に安定します。DBアサーションならFlakinessはありません。

さらにいうと、「世界」を起点とすると、細かいストーリーを結合して大きなストーリーを表現することができます。
もちろん、プロダクト自体が素直にステートレスに実装されていることが前提なんですけどね。何かそれまでの操作に依存して…のようなことになると、ここまでのストーリー分割の話は全く無意味になります。残念なことに、そういうのもなくはないです。

いかがでしたか?

表現したいことは状態遷移図・PFDと大差ないのですが、「初期化」にスコープしたいので「世界」という変な表現を持ち出しました。伝わるはず…と思っていますが、何かあればぜひマサカリを投げつけるなどしてください!

今回の記事はストーリー分割の話だったので、まだそこまで自動化っぽい話は出ていません。次からはもっと実装っぽい話になります。役に立てば幸いです〜。

セルフライナーノーツ: みんなで自動テストに取り組むために必要だったこと

はじめに

2025/03/25(火)に、QA Test Talk Vol.4に同僚QAエンジニア経由でtarappoさんからお招きいただき、登壇してきました。
登壇内容について、お話しできなかった内容を補足しながらつらつら書いておこうと思います。

主にQAエンジニア向けの記事なので、一部QA業界の用語が出てきます。そこはご容赦くださいね〜!

ちなみに

登壇前の週末にぎっくり腰をやらかし、壇上でクネクネしながらの登壇でした。録画がなくてよかった。アラフォーこわいな〜〜〜

スライド

こちらです。 speakerdeck.com

さあ本題

タイトル

「みんなでテストする」ということの重要性については理解されている方も多い?のでは?と思っています。
でも、「みんなでやる、ってどうやるんだよ〜」と思っている方々も多いと思います。なので、「みんなで」というところから内容を組み立てました。

私は一人目QAエンジニア(しかもQA初心者)としてJOINして、まずぶち当たったのがQAエンジニア一人で開発エンジニアに向き合うのは無理だ!!!ということでした。
なので、とても消極的な理由で、「みんなでテストする」しかない、と思ってQAエンジニアとしてのキャリアをスタートしたんです。 とはいえ、開発エンジニア経験から、開発者も事前にテストをしたい・知っておきたい、というのは理解していました。

「実装前後の自動テスト」

本当にシフトレフトしようと思ったら、ビジネスサイド(PdM)とのテスト(仕様レビューなどですね)が重要です。
しかし、リファクタリングできていない、現状動いて(しまって)いるプロダクトのテストだと、そうはいかないケースが多いです。

ということで、「まずは開発エンジニアにテストを作ってもらう」ことから始めています。
特に現在は内部の構造改善について、開発エンジニア主体でテストを作ってもらっています。
という意味でスコープを絞ってお話ししました。若干の逃げですね〜。

思想

開発エンジニアやってたときから「最後にテストするのおかしくない?」と思ってたのです。特に前職の組み込み系のテストはひどかったので…! (そのうち記事にしよう) 開発エンジニアが実装してんだから降りてきた仕様は知ってるはずだし詳細仕様も知ってるんだからテスト作ればいいじゃん、というところです。

あと「最後の砦」というのは本当にキライです。孔明がいなくても負け戦だとわかる。

頓挫と再構築

自動テストにおける最重要(だと思っている)な部分は、いかに被テスト状況を生み出せるかということです。それを初期データで生み出すことができれば、テスト自体は容易に実施できます。
個人的な感覚では、BDD的にいえば、Givenが8・WhenとThenが各1くらいです。

テストが遅い・再実行できない・メンテナンス性が悪い、というのは結局この初期化ロジックによるところが大きいです。
初期データは主にDBへのinsertになりますが、固定IDでの操作は並列化・再実行と非常に相性が悪いです。
そのため動的にテスト対象環境を生成するようにしました。動的に"閉じた"環境を都度作成することで、強烈に並列実行でき、FlakinessのせいでFAILした場合はリトライできるようにしています。これもそのうち記事にします。

ここ5年間

ATDDもTDDも以前からあったはずですが、ここ数年で普及した印象です。もはや「アジャイル開発でないのはダサい」という風潮になってきているから?でしょうか。5年ほど前はそこまでではなかった気がします。
ウォーターフォール開発であれば不確実性を許容しないので、ATDD・TDDの恩恵はあまり受けられませんからね〜。

本当にやるべきだったこと

開発者体験(DX)の向上は、5年前には全く勘案できていませんでした。反省点でありつつも、まあしょうがないよな、と思っています。
テストを作ることが重要で、どう実行するか?どうFAILを拾うか?まで考えられていない、ということは今でもそれなりにあるはずです。
また当時は私自身CI/CDの重要性がそこまで腹落ちしていませんでした。自動で全て実行されることのとんでもない強力さは実際に作って使ってわかる部分も大きいのではないかと思います。実際に体験するからこそDXが向上できる、と確信しています。

自動テストの好循環

自動テストが作りやすいこと

ここはどこに重点を置くか、というところで「作りやすい」は変わります。
今はGauge(テストランナー)と、マニピュレータとしてPlaywright(UIテストツール)・Axios(RESTAPIクライアント)を使用しています。この構成、実は開発エンジニアとしては作りやすくはないです。あと多分AI類にも作りやすくないと思います。
開発エンジニアが作って実行するならコードベースのものが最適です。AIに任せたい場合もそうだと思います。

私としては、最終的には「ビジネスサイド(PdM)とレビューしあいながら仕様を具現化しながらテストを作れるようにする」ことを目標としているので、ヒューマンリーダブルなmarkdown記法で書けるGaugeが最適だと考えています。
他にも、Gherkin記法で書けるCucumberなどもあります。テストするストーリーが十分小さければ、Gherkin記法の方が書きやすいかもしれないです。

そして、ここでももちろん、「初期データが作りやすいこと」という観点が重要です。
かつてCSVでデータを用意することも試しましたが、リレーションをIDでたどる他なく、メンテナンスが困難でした。
現状はTypeScriptのファイルです。シャローなクエリビルダーを用意して、insertしたレコードのIDを返し、他のテーブルのレコードにセットできる仕組みにしています。

作ったテストが実行されること

本当にやるべきだったこと、で出てきたCIの話です。
テスト実行自体は通常コマンドライン一発だと思います。なので、実際には被テストプロダクトの実行環境構築とそこに向けたテスト実行環境の構築です。

コンテナ化してあるプロダクトであれば、ECSでもEKSでもいいですし、GitHubホステッドランナー内でも動かすことができると思います。
もしコンテナ化していなかったとしても、それ用のEC2インスタンスを立てるなど、やりようはあります。
「コスト的にどうなの?」と思わなくもないですが、不具合が出て1レーンで半日費やすよりよっぽど安いです。

また、「おもしろそうなおもちゃ」のような環境であることも大事です。個人的にはCI環境を「ピタゴラ⚪︎イッチ」と呼んでいます。
ピタゴラス⚪︎ッチの、目覚まし時計が鳴って、おもりが落ちて、なんかゴウンゴウン動いて、パタっと旗が立つの、なんだかワクワクしませんか??
そんな感じで、「動いた!」と思えることが大事です。開発エンジニアの快感のひとつは、実装したものが「動いた!」ときなので!

実行され続けること

何度でも言いますが、動いていないテストは害悪でしかないです。
動いていないと勝手に腐ります。中途半端に資産なので簡単に捨てられません。
そして、FAILしたら「そりゃそうか」ですし、PASSしたとしても「これはテストとして正しいのか?」と疑心暗鬼になります。そんなテストに何の意味もありません。

あと、「ローカルで実行してください」は誰もやらないですし、commit等でhookしてローカルで強制的に実行するのもbadです。commitするたびに待たされたい人はいないです。アジリティも爆下がりです。
というわけで、マトモに自動テストを回しておくためには、やはりCIは必須だと思っていいと思います。

次なる課題

「もういつでも自動テスト作れる!」という状態になったからこそ、見えてきたものがあります。

開発者が自動テストを作れるようになると、今動いているプロダクトについては、まず「内部のロジックに沿って」テストを作ることになると思います。
基本的に最初はAPIテストにとどめておくのがベターです。APIテストなら高々数秒で1シナリオ終わりますし、Flakinessもないです。
逆にUIベースのテスト(E2Eテスト的)は数分かかることもありますし、正しく作らないとすーぐFlakyになります。作らないと確認できないことについては作ってもいいんですが、最低限のストーリーにしておいた方がいいです。そこも初期データでうまく作るのがコツです。
テストの信頼性を保つには、QAエンジニアによるテスト分析・計画・設計のノウハウが必要になります。そこがQAエンジニアのスペシャリティだと思っています。
新規にフルスクラッチで作れる場合は、あらかじめQAエンジニアを交えてテスト計画をしておけば、大きくズレることはないかな?と思います。楽観的かもしれませんけどね…。

全体最適化は、現在ちょうど悩んでいる部分です。テスト関連語彙のユビキタス化から始めています。

シフトライトっぽい文脈については、やはり測定をするところからになるだろう、と考えています。
比較的取りやすいのはコードカバレッジですが、開発エンジニアにテスト作成を促す契機にはなると思っています。ただカバレッジを上げればよいわけではないですが、テストできていない部分を明確にしてテスト作成を促す効果はあるだろうと推測しています。
今進めつつあるのは、CREチームと連携し、利用率・不具合率・対応工数などを取得して、その部分を厚くテストする・修正するようなことです。
偉そうに言っていますが…まだなーんにも見えていません!

包括的にテストせず開発するのはダサい、というのは、アジャイル開発の隆盛と共に少しずつATDD・TDDが普及していったのと同様に当たり前になっていくといいなあ、と思っています。仕様など早くから、モニタリングなどずーっと、テストし続けることが最適なプロダクトを作る最短経路ですからね〜。

いかがでしたか?

15分枠のLTだったので、話せることは限られており、色々書いたらこんな分量になっちゃいました!まあいいか!
私が体験して頓挫しまくったことを他のみなさんには経験してほしくないな〜と思ってるのは確かです。

自動テスト取り組んでみたいとか、始めてるけどまだみんなでできてないとか、十人十色有象無象な状況だと思います。
役に立つかどうかわかりませんが、「こんな経験をした人がいた」くらいでも役にたてば幸いです〜!