社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

動的テストスメル検出のための Gradle プラグインの試作谷口真幸†

柗本 真佑†

楠本真二†† 大阪大学大学院情報科学研究科
E-mail: †{m-tanigt,shinsuke,kusumoto}@ist.osaka-u.ac.jp
あらましテストコードの可読性や保守性に対する潜在的な問題を表す概念として，テストスメルが知られている．

一般的なテストスメルはテストの長さや複雑さといったソースコードの静的な側面に着目しており，検出が容易な一方で常に問題につながるとは限らない．他方で，テスト実行時の振る舞いに基づく動的スメルは，テストの実施が不十分であるにも関わらず，問題なくテストが成功したという誤った認識を開発者に与えるなど，テスト結果の誤解につながることが多い．そのため，可能な限り早期に検出し対策することが望ましい．本研究では，動的スメルを検出する仕組みを，ビルドツールである Gradle のプラグインとして実現する．実現にあたって，そのプロトタイプとして

JTDog を実装した．ビルドツールへの組み込みにより，高い可搬性を実現したうえで，テストの潜在的な問題を検出可能となる．GitHub 上の 150 のプロジェクトに対して行った適用実験の結果，JTDog の可搬性を確認することができた．また，実際に 55 のプロジェクトから 958 個の動的スメルを検出できた．
キーワード

ソフトウェアテスト，テストスメル，動的解析，ビルドツール，Gradle，プラグイン

1. は じ め に動的スメル）も存在する．例えば Rotten Green Test [5] は，成功したテストのうち，未実行のアサーションを含むテストのこと

ソフトウェアの品質保証のための開発工程にソフトウェアテ

であり，当該アサーションが行うべきであった動作確認を行っ

ストがある．テストはソフトウェア開発において重要な役割をていないにも関わらず，単に成功したテストとして報告される．

担っており，テスト駆動開発や継続的インテグレーションのよう

そのうえ，無意味なカバレッジの増加を引き起こし，開発者にな，テストを中心とした開発手法も広く用いられている [1] [2]．

テストが問題なく成功したという誤った認識を与えてしまう．

通常，開発者はテスト実施のために，プロダクトコードとは別

Rotten Green Test のように，動的スメルはテストの実行結果ににテストコードを記述する．

関する問題を引き起こし，テスト結果の誤解につながるため，

テストコードの可読性や保守性などに対する潜在的な問題を

静的スメルよりも深刻な問題につながりやすい．

表す概念として，テストスメルが知られている [3]．テストスメ

これまでに数多くのテストスメルに関する研究 [6] [7] [8] [9]ルは，テストの品質低下につながる問題の兆候であり，早期にが実施されてきたが，静的スメル，動的スメルといった分類を考検出しリファクタリングなどのコード改善によって排除される

慮した研究は存在しない．また，tsDetect [10] や TestHound [11]ことが望ましい．代表的なスメルとして，長すぎるコードや重など，テストスメル検出を目的としたツールが多く提案されて複したテストが知られている [4]．これらのスメルがプロダク

いるが，これらのツールが検出可能なスメルはすべて静的スメ

トコードでも共通する潜在的問題であるのに対し，テスト設計

ルに限定される．我々の知る限り，動的スメル検出を目的とし固有の考えに基づくスメルも存在する．例えば，テストコード

たツールは存在しない．

における制御文の使用は，テストの複雑化のみならず，テスト
コード自体のバグにつながる可能性がある [4]．

本研究の目的は，テスト実行結果に影響を与える動的スメルの早期検出の支援である．そのために，テストスメルを静的ス

これら一般的なテストスメルはテストコードの静的な側面に

メルと動的スメルに分類し，これらの性質を整理したうえで，着目しており，その悪影響の対象も保守性などの静的な観点に動的スメルを検出する仕組みをビルドツールである Gradle のプ

限定される．以降，本論文ではこれらのスメルを静的スメルとラグインとして実現する．実現にあたり，そのプロトタイプと呼ぶ．例えば先の例に挙げた，長すぎるテストコードは，理解して JTDog を実装した．

の困難さや保守コストの増大などにつながる問題ではあるもの

静的スメルがテストコードの静的解析のみによって検出可能の，テスト実行結果への影響はない．制御文を含むテストコー

であるのに対して，動的スメルの検出には動的解析を要し，テドも同様に，テストの複雑さやテスト自体のバグにつながる潜スト実行やテストコードのカバレッジ解析など様々な処理を行

在的な問題を示しており，テスト実行という側面での問題にはう必要がある．加えて，動的スメル検出ツールの利用者は，テならない．

スト実行に必要なすべての情報を入力として設定する必要があ

その一方で，テストの実行結果に影響を与えるスメル（以降，—1—

り，すぐに利用することは難しい．よって，静的スメルを検出
1する場合と比べると，動的スメル検出ツールの可搬性は低くなる傾向にある．しかし，ビルドツールへの組み込みにより，動的スメル検出のための動的解析による可搬性の低下を防いだう

2
3
4
5
6

URL data = getResource (" testData .xml"); // 誤 っ た テ ス ト デ ー タ
DataBase db = new DataBase (data);
List <User > users = db. getUsers (); // 実 際 は 空 の リ ス ト
for(User user : users){
assertNotNull (user. getName ()); // 実 行 さ れ な い}

えで，テストの潜在的な問題を検出可能となる．

JTDog の可搬性を確かめるため，GitHub 上の 150 のプロジェ

図 1 Rotten Green Test の例

クトに対して適用実験を行った．その結果，122 のプロジェク
トでプラグインが正常に動作し，そのうち 55 のプロジェクトにつながる．現状，Rotten Green Test [5]，Flaky Test [12]，Test

から合計 958 個の動的スメルを検出できた．

Dependency [13] の 3 種が存在する．

2. テストスメル
2. 1 概要2. 3. 1 Rotten Green Test
Rotten Green Test は，成功したテストのうち，未実行のアサー
ションを含むテストのことである．テストはプロダクトコード

テストコードの可読性や保守性の低下など，テスト品質に影の実行と動作確認という 2 つの要素で構成される．プロダクト

響する潜在的な問題を表す概念としてテストスメルがある．開コードの実行はプロダクトクラスやメソッドを呼び出す系列の発者にとっては，テストコードのリファクタリングの実施を促部分であり，動作確認はアサーションなどの命令を用いて実行す存在であり，どういった場合にどのような手法を用いてリ時の動作が期待通りであるかを確認する部分である．しかし，ファクタリングを行うべきかの判断基準となる [3]．テストスメ

Rotten Green Test は，未実行のアサーションによる動作確認がルに関しては多くの既存研究が存在しており [6] [7] [8] [9]，こ一切行われていないにも関わらず，常に成功したテストとしてれまでに様々な検出手法や検出ツールが提案されている．

報告される．例えば図 1 は，アサーションにより，リスト中の

本研究では，テストコードの静的な側面に基づくスメルを静各ユーザの名前が null でないかを確認するテストである．し

的スメル，テスト実行時の振る舞いに基づくスメルを動的スメ

かし，1 行目のテストデータが誤っており，3 行目で取得するリルと呼ぶ．本章ではこの 2 種類のスメルについて説明し，比較ストが空となるため，for 文内の処理が実行されず，5 行目のを行う．

アサーションは実行されない．また，Rotten Green Test は，本2. 2 静的スメル

質的でないテスト成功数の増加や無意味なカバレッジの増加と静的スメルは，テストコードの静的な側面に基づくテストス

いった問題も引き起こす．そのため，テストの実施が不十分でメルである．例えば Verbose Test [4] は，長すぎるテストコードあるにも関わらず，開発者にテストは問題なく成功したというのことであり，コードの可読性の低下を引き起こす．その結果，

誤った認識を与えてしまう．

テスト内容の理解を困難にする可能性があり，コードの保守性

2. 3. 2 Flaky Testに悪影響を与える．Verbose Test がプロダクトコードでも共通

Flaky Test は，同じコード，同じ実行環境であるにも関わらする潜在的問題である一方で，テスト設計固有の考えに基づいず，実行するたびにテストの成否が変化するテストである．通たスメルも存在する．例えば Conditional Test Logic [4] は，テ常，開発者はテスト結果が変化した原因をテストコードや実行

ストコードに制御文を含むべきではないという考えに基づいた

環境の変更によるものと考えるため，Flaky Test による変化であ

スメルである．制御文による条件分岐はテストコードの複雑化ることを特定するためだけに，多大な時間や労力を費やすことにつながり，テスト内容の理解を困難にするため，テストの保となる．また，Flaky Test による失敗が頻繁に発生する場合，開守性の低下につながる．さらに，条件分岐により実行されない

発者はその失敗を無視する傾向があるため，バグを見逃すきっ文が存在する場合，プロダクトのバグを検出できない可能性がかけともなる [12]．

ある．

2. 3. 3 Test Dependency

上記のように，静的スメルはテストに悪影響を及ぼすが，テTest Dependency は，テストの実行順序が変わるとテスト結果

ストコードの静的な側面に着目しているという性質ゆえ，影響が変わってしまうような，テスト間に存在する依存関係に基づの対象も保守性などの静的な観点に限定される．例えば先の例

くスメルである．このような実行結果が他のテストに依存するに挙げた Verbose Test は，理解の困難さや保守コストの増大なテストは Dependent Test と呼ばれる．

どにつながる問題ではあるものの，テスト実行結果への影響は

テスト順序の変更によりテストが失敗した場合，多くの場合ない．Conditional Test Logic も同様に，テストの複雑さやテスはテスト実行前の初期化処理の失敗が原因である．しかし，開ト自体のバグにつながる潜在的な問題を示しており，テスト実発者が Test Dependency の概念を知らない場合，原因の特定は行という側面での問題にはならない．

困難であり，開発者は Dependent Test のテスト対象のプロダク

2. 3 動的スメル

トコードがバグを含むと判断してしまう恐れがある．また，テ動的スメルは，テスト実行時の振る舞い，すなわち，テス

スト順序の変更によるテスト結果の変化は，通常の実行順序で

ト実行の経路，順序，結果に基づいたスメルである．テスト
結果に悪影響を及ぼし，多くの場合，テスト結果の誤解などは表面化しないバグを見逃すきっかけとなる [13]．

2. 4 静的スメルと動的スメルの比較
静的スメルと動的スメルを，危険性やスメル検出の観点から—2—

比較した結果を表 1 に示す．この比較結果から，静的スメルが可読性や保守性への影響に限定される一方で，動的スメルはテかを確認する．

3. 2. 2 Flaky Test の検出

スト結果の誤解などテストの実行結果に悪影響を及ぼす．よっFlaky Test の検出手法は近年数多く提案されている．最も単て，動的スメルは静的スメルよりも重大な問題を引き起こすた純な手法としては，複数回テスト実行を繰り返し，その成否がめ，早期に発見し，対策することが望ましい．しかし，tsDetect

安定するか調べるという手法が挙げられる [12]．その他，コーや TestHound などの既存のテストスメル検出ツールは静的スメ

ド変更によるカバレッジの変化を監視する方法や，機械学習に

ルしか検出できず，動的スメル検出を目的としたツールは存在より失敗したテストを Flaky Test やコード変更によるものなどしない．

に分類する方法がある [14] [15]．本研究では，テストに失敗しまた，静的スメルがテストコードの静的解析のみによって検出可能であるのに対し，動的スメルの検出には動的解析を要し，た場合に複数回再実行することで Flaky Test の検出を行う．

3. 2. 3 Dependent Test の検出

テスト実行やテストコードのカバレッジ解析など様々な処理がDependent Test は，1 度通常の順序でテストを実行した後，テ必要である．さらに，動的スメル検出ツールの利用者は，プロ

スト順序を，逆順にする，ランダムに入れ替えるなどして再実

ダクトコードやテストコードに加え，リソースファイルやクラ

行し，テスト結果が通常の順序の場合と異なるかを調べること

スファイル，外部ライブラリのパスなど，テスト実行に必要なで検出可能である [13]．本研究では，ランダムな順序で複数回すべての情報を入力として設定する必要があり，すぐに利用す

再実行することで Dependent Test の検出を行う．

ることは難しい．よって，静的スメルを検出する場合と比べる

3. 3 Gradle プラグインの実現と，動的スメル検出ツールの可搬性は低くなる傾向にある．

3. 3. 1 ビルドツール統合による可搬性の確保
動的スメルの検出を行う場合，プロダクトコードやテスト

3. 提 案 手 法
3. 1 概コードに加え，クラスファイルや外部ライブラリのパスなど

要

様々な情報が必要である．ビルドツールである Gradle はソース

本研究では，動的スメルを検出する仕組みをビルドツールでフォルダの管理や，依存関係の解決などを自動で行うことが可ある Gradle のプラグインとして実現することを提案する．ビル

能である．前述の動的スメル検出手法を Gradle へ組み込むこと

ドツールへの組み込みにより，高い可搬性を実現したうえで，で，実行に必要なすべての情報を Gradle から取得でき，また，

動的スメルを検出可能となる．

高い可搬性を実現することができる．

3. 2 動的スメルの検出

3. 3. 2 実装プラグイン：JTDog

提案手法では，以下の手順で動的スメルの検出を行う．各ス

提案手法を実現するためのプロトタイプとして JTDog を実装

メル検出手法の詳細は 3.2.1 項，3.2.2 項及び 3.2.3 項に示す．

した．JTDog とは，Java Test Dog の略称で，Gradle の Java プロ（ 1 ） テストコードを静的解析し，メソッド情報を収集する．

ジェクトに存在する動的スメルを検出するプラグインである．

（ 2 ） テストクラスのバイトコードにカバレッジ計測命令を

JUnit3/4/5 で記述されたテストに動的スメルが含まれるかを調埋め込む．

べ，その結果を JSON ファイルに出力する．JUnit のバージョ（ 3 ） 通常の順序で各改変済みテストを実行する．

ンは実行時に指定し，デフォルトでは JUnit3/4 のテストを検出（ 4 ） テストに成功した場合，Rotten Green Test であるかを対象とする．

調べる．失敗した場合，Flaky Test であるかを調べる．

JTDog は，動的スメルを検出する sniff という名称のタス（ 5 ） 通常の順序でのテスト実行終了後，順序を変更してテクを提供する．開発者は，gradle sniff のようなコマンドをスト実行を行い，Dependent Test を検出する．

実行するだけでプロジェクトに存在する動的スメルの検出が可

3. 2. 1 Rotten Green Test の検出能である．さらに，JTDog は，以下のように，ビルドファイル

本研究では，Delplanque ら [5] の手法に従って Rotten Green

である build.gradle 中の plugins ブロックに利用宣言文を 1

Test の検出を行う．まず，テストコードを静的解析し，各メ
ソッドが持つ要素（アサーションやメソッド呼び出しなど）を調べる．そして，各テストを実行し，成功した場合にカバレッ

行追加するだけで利用できる．
plugins {id ’com. github .m- tanigt .jtdog ’ version ’1.0.0 ’}

ジデータの解析を行い，テストが未実行のアサーションを含む

Gradle プロジェクトでは，クラスパスなどプロジェクト固有の
表1

静的スメル
問題の影響範囲

可読性や保守性

解析手法

静的解析

解析に必要な情報

テストコードのみ

検出ツール

各種ビルド情報は build.gradle ファイルに記載済みであるた

静的スメルと動的スメルの比較

tsDetect [10]，TestHound [11] など

動的スメル
テストの実行結果

め，JTDog の利用宣言以外に追記の必要はない．
動的スメルの検出は，Gradle API を利用して行う．図 2 に，

静的解析と動的解析

その処理概要を示す．Gradle の Java プロジェクトでは，Java

テスト実行に必要なのコンパイルやテストを行うために Java プラグインを適用し，情報すべて

ソースセットの概念をプロジェクトに導入する．ソースセット–とは，ソースおよびリソースファイルのコンパイルに関する情報を結びつける概念である．ソースセットを利用することで，—3—ソースファイル取得

クラスファイル・クラスパス取得

Gradle

テストクラス
改変

抽象構文木
生成・解析

静的解析器

動的解析器

メソッド情報収集

テスト実行

実行結果・カバレッジデータ
収集
実行結果出力動的スメル検出

JSON

JTDog
図 2 動的スメル検出処理の概要

ソースファイルや，クラスパス，クラスファイルなどを取得する

4. 3 実 験 方 法

ことができる．JTDog は，ソースセットからプロダクトコード

適用対象の各プロジェクトについて，3.3.2 項で示したようにとテストコードを取得し，テストコードの抽象構文木を生成お

JTDog の利用宣言文を build.gradle ファイルに追記する．そよび解析することでメソッドの情報を収集する．そして，ソーして，sniff タスクを実行し，実行結果の JSON ファイルの内

スセットからテストクラスファイルとクラスパスを取得し，テ容を確認する．

ストの改変と実行を行うことで実行結果やカバレッジデータを

4. 4 実 験 結 果

収集する．収集したこれらのデータを合わせることで動的スメ

4. 4. 1 可搬性の確認

ルを検出することができる．

適用対象として選択した 150 のプロジェクトに対して JTDog

4. 適 用 実 験を適用した結果，そのおよそ 81% である 122 のプロジェクトで正常に動作した．プラグイン利用のための一文を追加するの

4. 1 実験の目的

みで動作しており，JTDog は様々なプロジェクトに適用可能で

JTDog の可搬性及び，実際に動的スメルを検出可能かの確認あるといえる．

を目的として，GitHub 上の Gradle プロジェクトに対する適用実験を行う．

適用に失敗した 28 のプロジェクトの失敗原因を目視により確認した．その内訳を表 2 に示す．表 2 のうち，メモリ不足に

4. 2 適 用 対 象

よる失敗の理由を調べたところ，プロジェクトのメソッド数がGitHub 上のプロジェクトから，以下を満たすプロジェクトを膨大であることが原因であった．JTDog はメソッドの情報を収選択した．

集，保持して動的スメルの検出を行うため，メソッド数が多い

ビルドツールとして Gradle を使用している，あるいは，

ほど，情報保持のためにメモリを使用する．ゆえに，不必要にGradle の変換機能により問題なく Gradle プロジェクトに変換なった情報を適宜破棄するように処理を変更するなど，JTDog

可能な Maven プロジェクトであるのリファクタリングによりメモリ不足による失敗を防ぐことが••主要言語が Java であり，Gradle の Java プラグインを適用している可能であると考えられる．メモリ不足以外の原因については，
現状，その理由は把握しきれておらず，今後の詳細な分析が必•テストを 1 つ以上含む要である．しかし，ツールの実装に起因する問題は少ないと考•テストフレームワークに JUnit を用いている

えられ，JTDog は高い可搬性を有するといえる．

上記の条件に加えて，一定以上の人気があるプロジェクトに絞るため，Star が 100 以上であるプロジェクトに限定した．Starとは，GitHub におけるプロジェクトの人気を表す指標の一つで

表 2 JTDog 適用失敗の原因
適用失敗の原因

プロジェクト数

あり，Star の数が多いほど，多くの人が当該プロジェクトを利

メモリ不足

10

用していると言える．

タスク作成失敗

9

検出結果が不正6

ファイル読み込み失敗

3以上の条件に基づき，150 のプロジェクトを適用対象プロジェ
クトとして選択した．

—4—

4. 4. 2 動的スメルの検出結果

432

まず，JTDog が正常に動作した 122 のプロジェクトでの動的
スメル検出数とスメルを検出したプロジェクトの数を表 3 に示す．この結果から，122 のプロジェクトのうち 55 件でスメル

433
434
435
436

を検出したため，適用に成功したプロジェクトのおよそ 45%

437

は動的スメルを少なくとも 1 つ含んでいることがわかった．ま438

た，Rotten Green Test は Flaky Test や Dependent Test と比べ，ス

440

メル検出数，検出プロジェクト数のいずれにおいても多い結果442となった．これは，Rotten Green Test が ICSE2019 で発表された論文 [5] で紹介された新しいスメルであり，ほとんどの開発者が知らないためと考えられる．Delplanque ら [5] 曰く，テストの実施が不十分であるにも関わらず開発者にテストが問題なく成功したという誤った認識を与えるため，Rotten Green Test
はまったくテストをしないよりも悪質である．ゆえに，Rotten

Green Test の検出が可能なツールは重要である．
次に，プロジェクトごとの各スメルの傾向を調べる．表 4 に，それぞれのプロジェクトでの Rotten Green Test 検出数について，スメル検出数上位 5 件のプロジェクトを抜粋して示す．検出数の多いこれらのプロジェクトは，同じ原因のスメルを多く含んでいた．例えば検出数が最も多い traccar プロジェクトでは，224 個もの Rotten Green Test のほとんどは if 文内のアサーションが実行されないことによるものであった．JTDog を使用
すれば，開発者はどのようなコードが Rotten Green Test である
かを知ることができ，今後の開発に役立てることができるため，

439
441

@Test
public void c1c3IsDisposed () {toV3Completable (rx. Completable . complete ()). subscribe (new io. reactivex . rxjava3 .core.
CompletableObserver () {@Override
public void onSubscribe (io. reactivex . rxjava3 . disposables. Disposable d) {assertFalse (d. isDisposed ());
}
...
});
}

図 3 検出した Rotten Green Test の例 1

このようなテストは，同じ static 変数を使用するテストの追加などに影響を受け，テスト結果が変わる可能性がある．よって，Dependent Test は早期に検出し対策することが望ましく，

JTDog のような検出ツールは重要であるといえる．
4. 5 動的スメルの実例
本節では，JTDog が検出した各動的スメルの実例を紹介する．

4. 5. 1 Rotten Green Test
図 3 に示す RxJavaInterop プロジェクトのテストメソッド

c1c3IsDisposed() は，Rotten Green Test である．イベントリ
スナのアクションである onSubscribe() メソッド（437 行目）
は内部にアサーションを持つが，このメソッドは実際には実行されない．そのため，438 行目のアサーションによる動作確認が行われず，テストの実施は不十分である．しかし，JUnit は単に成功したテストとして報告するため，開発者がテストに問題

やはり検出ツールは重要であるといえる．
表 5 に，Flaky Test を検出した全 5 プロジェクトでの検出数を示す．http-request プロジェクトでの検出数が突出しているものの，それ以外のプロジェクトではほとんど検出されなかった．
これは，JTDog がテストの再実行という最も単純な検出手法を採用していることに加え，この検出手法を Jenkins [16] などのフレームワークがサポートしており，多くのプロジェクトがこがあると気づくことは困難である．

4. 5. 2 Flaky Test
図 4 に 示 す java-jwt プ ロ ジ ェ ク ト の テ ス ト メ ソ ッ ド

shouldPassHMAC256Verification() は，Flaky Test である．
アサーションを含む concurrentVerify() メソッド（90 行目）
実行時に，RejectedExecutionException という例外が発生
し，テストが失敗する場合がある．開発者は，この例外が発生のスメルに対処しているためと考えられる．
表 6 に，Dependent Test 検出数上位 5 件のプロジェクトにおけるスメル検出数を示す．いずれのプロジェクトにおいても，テスト間で static 変数を共有することが主な原因であった．
表3

動的スメル検出結果
検出数 プロジェクト数

Rotten Green Test

781

48

Flaky Test

66

5

Dependent Test

111

13

合計

958

55

表 5 Flaky Test 検出プロジェクト（全 5 件）
プロジェクト名

http-request

59

java-jwt

4

spring-statemachine1eureka1litiengine

1

表 6 Dependent Test 検出プロジェクト（上位 5 件抜粋）
プロジェクト名

表 4 Rotten Green Test 検出プロジェクト（上位 5 件抜粋）
プロジェクト名

検出数

traccar

224

elki

110

Apktool

58

nats.java

50

xodius

39

検出数

検出数

ehcache357

http-request

22

micrometer11

mybatis-plus

6

testcontainers-java

3

（注 1）
：https://github.com/akarnokd/RxJavaInterop/blob/3.x/src/test/

java/hu/akarnokd/rxjava3/interop/RxJavaInteropTest.java#L432

—5—

84
85
86
87
88

@Test
public void shouldPassHMAC256Verification () throws Exception{
Algorithm algorithm = Algorithm . HMAC256 (" secret ");JWTVerifier verifier = JWTVerifier .init( algorithm ).
withIssuer (" auth0 ").build ();String token = ...;

89

concurrentVerify (verifier , token);

90
91

}

5. お わ り に本研究では，テストスメルを静的スメルと動的スメルに大別
し，その性質を整理したうえで，動的スメル検出手法を実現するために Gradle プラグイン JTDog を実装した．適用実験として GitHub 上の 150 プロジェクトに対して JTDog を使用し，本プラグインの可搬性および検出機能の確認を行った．今後の課図 4 検出した Flaky Test の例 2

題として，JTDog に静的スメルの検出機能を追加し，広範にテストスメルを検出可能にすることや，フレームワークとして再

14
15
16
17

@Test
public void getCurrentUsername () {SecurityContext securityContext = SecurityContextHolder .
createEmptyContext ();securityContext . setAuthentication (newUsernamePasswordAuthenticationToken ("admin ", " admin "));SecurityContextHolder . setContext ( securityContext );編することによる拡張性の向上が考えられる．
謝辞

本研究の一部は，日本学術振興会科学研究費補助金基

盤研究（B）（課題番号：18H03222）の助成を得て行われた．
文

献[1] K. Beck, Test-Driven Development: By Example, Addison-Wesley
19
Professional, 2003.
20
Optional <String > username = SecurityUtils .
[2] M. Fowler, “Continuous Integration,” accessed 2021-02-05. https://
getCurrentUsername ();21
martinfowler.com/articles/continuousIntegration.html
22
assertThat ( username ). contains ("admin ");[3]
A.V. Deursen, L. Moonen, A. Bergh, and G. Kok, “Refactoring Test
23}
Code,” International Conference on Extreme Programming and Flex24
25@Test
ible Processes in Software Engineering, pp.92–95, 2001.
26
public void getCurrentUsernameForNoAuthenticationInContext ()[4]
G. Meszaros, xUnit test patterns: Refactoring test code, Pearson Ed{
ucation, 2007.
27
Optional <String > username = SecurityUtils .
getCurrentUsername ();[5] J. Delplanque, S. Ducasse, G. Polito, A.P. Black, and A. Etien, “Rot28
ten Green Tests,” International Conference on Software Engineering,29
assertThat ( username ). isEmpty ();pp.500–511, 2019.
30}[6] B. Van Rompaey, B. Du Bois, and S. Demeyer, “Characterizing theRelative Signiﬁcance of a Test Smell,” International Conference on
図 5 検出した Dependent Test の例 3
Software Maintenance, pp.391–400, 2006.
[7] G. Bavota, A. Qusef, R. Oliveto, A. De Lucia, and D. Binkley, “Anempirical analysis of the distribution of unit test smells and their imした原因が，プロダクトとテストのいずれにあるかを調べるた
pact on software maintenance,” International Conference on Software
めに時間を費やすこととなる．さらに，テスト結果が不安定な
Maintenance, pp.56–65, 2012.
だけと考え，失敗原因を特定しない場合，プロダクトのバグを[8] G. Bavota, A. Qusef, R. Oliveto, A. Lucia, and D. Binkley, “Are Test
Smells Really Harmful? An Empirical Study,” Empirical Software
見逃す可能性がある．
Engineering, vol.20, no.4, p.1052–1094, 2015.
4. 5. 3 Dependent Test
[9] A. Peruma, “What the Smell? An Empirical Investigation on theDistribution and Severity of Test Smells in Open Source Android Ap図 5 に jwt-spring-security-demo プロジェクトに含まれる Deplications,” Master’s thesis, Rochester Institute of Technology, 2018.
pendent Test である getCurrentUsernameForNoAuthenticatio[10] A. Peruma, K. Almalki, C.D. Newman, M.W. Mkaouer, A. Ouni, and-nInContext()（25 行 目 ）と ，こ の テ ス ト が 依 存 す る テ ス
F. Palomba, “tsDetect: An Open Source Test Smells Detection Tool,”p.1650–1654, Association for Computing Machinery, 2020.
トである getCurrentUsername()（14 行目）を示す．通常は[11] M. Greiler, A. van Deursen, and M. Storey, “Automated Detection
getCurrent...Context() が先に実行されるが，実行順を入れ替
of Test Fixture Strategies and Smells,” International Conference on
えると，getCurrentUsername() により static 変数 username
Software Testing, Veriﬁcation and Validation, pp.322–331, 2013.
[12] Q. Luo, F. Hariri, L. Eloussi, and D. Marinov, “An Empirical Analysisの値が"admin"に設定されるため，29 行目でアサーションエ
of Flaky Tests,” International Symposium on Foundations of Software
ラーが発生する． JUnit4 はデフォルトでは実行順序をテストメ
Engineering, pp.643–653, 2014.
[13] S. Zhang, D. Jalali, J. Wuttke, K. Muşlu, W. Lam, M.D. Ernst, andソッド名のハッシュ値に基づいて決定する 4 ．そのため，これD. Notkin, “Empirically Revisiting the Test Independence Assumpらのテストは偶然どちらも成功する順序で実行されているだけ
tion,” International Symposium on Software Testing and Analysis,
であり，メソッド名の変更やテストの追加などで実行順序が変p.385–396, 2014.
[14] J. Bell, O. Legunsen, M. Hilton, L. Eloussi, T. Yung, and D. Mariわると，getCurrent...Context() のテストは失敗する．しかnov, “DeFlaker: Automatically Detecting Flaky Tests,” International
し，開発者はすぐには実行順序の変更がテストの失敗とは考え
Conference on Software Engineering, pp.433–444, 2018.
ないため，原因の特定に時間を費やすこととなる．
[15] K. Herzig and N. Nagappan, “Empirically Detecting False Test
Alarms Using Association Rules,” International Conference on Software Engineering, p.39–48, 2015.
（注 2）：https://github.com/auth0/java-jwt/blob/master/lib/src/test/java/ [16] “Jenkins RandomFail annotation,” accessed 2021-02-05. https://github.com/jenkinsci/jenkins-test-harness/blob/master/src/main/java/
com/auth0/jwt/ConcurrentVerifyTest.java#L84
org/jvnet/hudson/test/RandomlyFails.java（注 3）：https://github.com/szerhusenBC/jwt-spring-security-demo/blob/18

master/src/test/java/org/zerhusen/security/SecurityUtilsTest.java#L25（注 4）：https://github.com/junit-team/junit4/wiki/Test-execution-order—6—