🚴

自動テストについて: 自分なりのSMURFを考えてみる

に公開

私は普段APIサーバーの開発をしていることが多いのですが、だいぶ前から「単体テストよりも統合テストを充実させた方が良いのでは」と考えていました。
なんとなく「単体テストでカバーしても結局手動でテストしている。本当にコスト面で優れているのか?」と感じていた/感じているのかもしれません。

2024年にGoogleが出したテスト戦略(?)を統合テスト過激派の私なりに恣意的に改変してみました。

海外ニキ/ネキの検索にもヒットしてもらいたいので下の方に翻訳を貼っておきます。

前提: SMURFとは

Googleの開発者ブログで "TotT" のラベル("Tech on the Toilet"の頭文字)が付いた投稿記事の各エピソードを元に作ったらしい、旧来の "Testing Pyramid" よりも現在に即したテスト戦略(概念?)。

"TotT" のラベルが付いた記事一覧: https://testing.googleblog.com/search/label/TotT?updated-max=2008-06-11T09:20:00-07:00&max-results=20&start=36&by-date=false

前提: テスト戦略について話す時は対象のソフトウェアの種類を決めたい

テストの対象がAPIサーバーなのか、フロントエンドなのかとかで全然話が変わってくる。
例えば同じ「統合テスト」でもフロントエンドとAPIサーバーでは得られる自信の度合いは異なり、APIサーバーの方が比較的高い(これはSMURFでいうところの忠実性に当たると解釈している)。

テスト戦略の一般論を話す時は、想定でも良いので対象を決めないと間違った評価に基づいた結論になってしまいかねない。
(そういった意味では、"Testing Trophy"は出自がフロントエンドであることがハッキリしているので間違った評価になりにくい気がする。)

本題: 自分に合ったSMURFを作ってみる

前提を踏まえて、以下の条件で作ってみる。

  • APIサーバーを対象にする
  • APIサーバーの統合テストの忠実性は高いのでオリジナルでは3点になっているのを6点に変更する
  • 各特性の価値は等価ではないので係数をかける。S=3,M=4,U=1,R=2,F=5
    • 後述の補足に書くようにFlakyなテストでそんなに困っているわけではないので信頼性の係数は低めにした

とても満足のいく、現実味のある結果となりました。
半分は冗談ですが半分は本当です。

補足: 信頼性、Flakyなテストについて

どんなFlakyがあるか

ChatGPTに数回質問してFlakyになる原因の分類をしてもらった。

Flakyなテストの原因が起きやすい順に並べると、以下のような分類になります(上から順に起きやすい原因):

  1. 非同期処理
  • タイミングの問題や、非同期処理が完了する前にテストが終了してしまうことが原因で、最も一般的で起こりやすい。
  1. 外部依存

    • 外部のAPIやネットワーク、サーバー、外部サービスが一時的にダウンしたり遅延したりすると、テストが不安定になる。
  2. 並行性・競合状態

    • マルチスレッドや並行処理によるレースコンディションやデッドロックが原因で、テスト結果が予測できない。
  3. 日時・タイムゾーン

    • 現在の日付や時刻、タイムゾーンに依存したテストが、特定の時間帯や日付でのみ動作する場合が多く、簡単にflakyになる。
  4. 依存関係・リソースの状態

    • データベースやキャッシュ、ファイルシステムの状態によって、テストが失敗したり成功したりする場合。
  5. 配列の順番

    • 配列やリストの順番に依存したテスト。順番を保証しないロジックでも順番に依存して比較している場合。
  6. システム・環境依存

    • 開発環境、OS、ハードウェア構成、設定に依存したテストが、異なる環境で実行されると失敗する可能性がある。
  7. 乱数・ランダム性

    • ランダムに生成される値やシャッフルされた順番に依存するテスト。期待する結果がランダム要素によって異なる。
  8. 不安定なアルゴリズム

    • ソートやシャッフルなど、非決定的なアルゴリズムに依存したテスト。異なる実行ごとに結果が変わる。
  9. テストの順序依存

    • テスト間で状態が共有されていたり、前後関係に依存している場合。テストの順番が変わると結果が変わる。

この順番は、一般的に開発の現場でよく見られるFlakyなテストの原因に基づいています。特に非同期処理や外部依存は、テストが不安定になる最も一般的な原因となります。

9番はよくわからない。
10番は5番と同じような気もする。
APIサーバーの開発をしていると6番が99割で、5番が1割、4番が1割くらいの感覚。
みたいな感想になった。

APIサーバーならそんなに困らなさそう

テスト戦略の話をする時、よくFlakyテストが論点に挙がるけど、個人的にはAPIサーバーの場合は原因は前述の通りソートのかけ忘れ、DBのID依存、日付依存あたりが殆どな印象で、どれもすぐに直せるし、ソートのかけ忘れなんかはちょっとしたバグとも言えるのでFailしたらむしろ嬉しい。

冒頭でも書いたようにテスト戦略を考える時に対象のソフトウェアの種類は重要、種類によってはFlakyや信頼性は無視できるかもしれない。


I usually develop API servers, but I've been thinking for a while that it would be better to have more integration tests than unit tests.
You may have been feeling/feeling that "Even if you cover it with unit tests, you still end up testing manually. Is it really cost-effective?"

As an integration testing extremist, I arbitrarily modified the testing strategy (?) published by Google in 2024.

I'll post the translation below because I want Niki and Neki overseas to find it too.

Prerequisite: What is SMURF?

A more current testing strategy than the old "Testing Pyramid," which seems to be based on episodes of posts labeled "TotT" (an acronym for "Tech on the Toilet") on Google's developer blog. (concept?).

List of articles labeled "TotT": https://testing.googleblog.com/search/label/TotT?updated-max=2008-06-11T09:20:00-07:00&max-results=20&start=36&by -date=false

Premise: When talking about testing strategy, you want to decide on the type of software you are targeting.

The story changes completely depending on whether the test target is an API server or a front end.
For example, even with the same "integration test", the level of confidence gained is different between the front end and the API server, with the API server having a relatively higher level of confidence (this is interpreted as corresponding to SMURF's fidelity).

When talking about test strategies in general, it's okay to make assumptions, so if you don't decide on the target, you may end up coming to a conclusion based on the wrong evaluation.
(In that sense, it is clear that "Testing Trophy" originates from the front end, so I feel that it is difficult to give a wrong evaluation.)

Main topic: Create a SMURF that suits you

Based on the premise, try making it under the following conditions.

  • Target API server
  • Since the fidelity of the API server integration test is high, the original score of 3 has been changed to 6.
  • The values ​​of each characteristic are not equal, so multiply them by coefficients. S=3,M=4,U=1,R=2,F=5
    *As I will write in the supplementary section below, I didn't have that much trouble with the Flaky test, so I set the reliability coefficient low.

The result was very satisfying and realistic.
Half kidding, half true.

Supplement: Regarding reliability and flaky testing

What kind of Flaky is there?

I asked ChatGPT several times and asked them to classify the causes of Flaky.

If the causes of flaky tests are arranged in order of likelihood of occurrence, they are classified as follows (causes that occur from top to bottom):

  1. Asynchronous processing
  • The most common and likely cause is due to timing issues or the test ending before the asynchronous process completes.
  1. External dependencies
  • Tests become unstable if external APIs, networks, servers, or external services are temporarily down or delayed.
  1. Concurrency/race conditions
  • Unpredictable test results due to race conditions and deadlocks caused by multithreading and concurrency.
  1. Date/Time/Time Zone
  • Tests that depend on the current date, time, or time zone often only work in a specific time zone or date, and can easily become flaky.
  1. Dependencies/resource status
  • Tests may fail or pass depending on the state of the database, cache, or file system.
  1. Array order
  • Tests that depend on the order of arrays and lists. Even if the logic does not guarantee the order, the comparison depends on the order.
  1. System/environment dependent
  • Tests that are dependent on the development environment, OS, hardware configuration, and settings may fail when run in a different environment.
  1. Random numbers/randomness
  • Tests that rely on randomly generated values ​​or shuffled order. The expected result depends on the random element.
  1. Unstable algorithm
  • Tests that rely on non-deterministic algorithms such as sorting and shuffling. Results vary on different runs.
  1. Test order dependent
  • If state is shared or context-dependent between tests. If the order of the tests changes, the results will change.

This order is based on the causes of flaky tests that are commonly seen in development. In particular, asynchronous processing and external dependencies are the most common causes of test instability.

I don't really understand number 9.
I feel like number 10 is the same as number 5.
When I'm developing an API server, I feel like 990% of the time is number 6, 10% is number 5, and 10% is number 4.
That's how I felt.

If it's an API server, it won't be that much of a problem.

When talking about testing strategy, Flaky testing is often brought up, but personally, in the case of API servers, I feel that the causes are mostly due to forgetting to sort, DB ID dependence, date dependence, etc. All of these can be fixed quickly, and forgetting to sort can be considered a minor bug, so I'd be happy if it failed.

As I wrote at the beginning, the type of target software is important when considering a test strategy, and depending on the type, flaky and reliability may be ignored.

Discussion