2

関数テストを作成するために、eclipseでjunitを使用しています。

個々のテストを実行すると、クラス内で設定した順序で実行されます。

例えば。

testCreateUser
testJoinUserToRoom
testVerify
testDeleteUser

ただし、このテストをスイートの一部として (パッケージ内で) 実行すると、順序はランダムになります。

たとえば、検証を実行してから、ユーザーを削除してから、userToRoom に参加してから、Createuser を実行します。

スイート内のテストは相互に依存していません。ただし、テスト内の個々のテストは、正しい順序で実行されることに依存しています。

これを達成する方法はありますか?

ありがとう。

4

2 に答える 2

6

JUnitでのテストメソッドの実行順序は保証できません。

スイート内のテストクラスの実行順序保証されますが ( Suiteを使用している場合)、テスト クラスがリフレクションによって検出された場合の実行順序は保証されません (たとえば、Eclipse でパッケージを実行している場合)。 、またはmavenまたはantからの一連のテスト)。これは ant または maven で定義できる場合がありますが、JUnit では定義されていません。

一般に、JUnit はソース ファイルで定義されている順序でテスト メソッドを実行しますが、すべての JVM がこれを保証するわけではありません (特に JVM 7 の場合)。一部のメソッドが抽象基本テスト クラスから継承されている場合、これも当てはまらない場合があります。(これはあなたのケースのように聞こえますが、あなたの説明からはわかりません)。

詳細については、Has JUnit4 がテストの注文のサポートを開始しましたか?に対する私の回答を参照してください。意図的なものですか?.

では、問題を解決するために何ができますか? 解決策は 2 つあります。

元の例では、実際には 1 つのテスト (verify) しかありませんが、2 つのセットアップ (createUser、joinUserToRoom) と 1 つのティアダウン (deleteUser) の 4 つのメソッドがあります。したがって、最初のオプションは、TestRule、特にExternalResourceを使用して、テスト ケースをより適切に定義することです。ExternalResourceと同様に、テストの前後の動作を定義できます@Before/@After。ただし、の利点は、ExternalResourceこれをテストから除外できることです。

したがって、外部リソースでユーザーを作成/削除します。

public class UsesExternalResource {
     @Rule
     public ExternalResource resource= new ExternalResource() {
         @Override
         protected void before() throws Throwable {
            // create user
         };

         @Override
         protected void after() {
            // destroy user
         };
     };

     @Test
     public void testJoinUserToRoom() {
        // join user to room
        // verify all ok
     }
}

私にとって、これはよりシンプルで理解しやすく、独立したテストを取得できることは良いことです. これは私がすることですが、テストを少しリファクタリングする必要があります。RuleChainを使用して、これらのルールを積み重ねることもできます。

テスト メソッド間に依存関係を本当に導入したい場合の 2 番目のオプションは、あるテストから別のテストへの依存関係を定義できるTestNGを調べることです。

于 2011-12-15T12:18:16.700 に答える
0

それらが「正しい」順序である場合、それらは複数のテストではなく、複数の独立したテストであると誤って注釈を付けた単一のテストです。

ベスト プラクティスは、必要な一般的なセットアップを行う @Before または @BeforeClass メソッドによってサポートされる、承認された junit スタイル (セットアップ - アクション - 検証) でそれらを書き直すことです。

簡単な回避策は、他のテスト メソッドを順番に呼び出す単一の @Test アノテーション付きメソッドを用意することです。Junit を使用して厳密な単体テストを行うのではなく、シナリオ駆動型システム テストのようなものを使用している場合、これは好ましい代替手段のようなものになります。このような用途には必ずしも最適なツールではありませんが、場合によっては完全に機能します。

次に、これまでのところ、単一のテストがあります。

@Test public void testUserNominalLifeCycle(...

あなたが高潔だと感じているなら、次のような追加の新しいテストで補うことができます

@Test public void testUserWhoNeverJoinsARoom(...
于 2011-12-15T10:18:49.767 に答える