0

ランダムな整数を含むランダムなサイズの配列を毎回作成することになっているJUnitを作成しています。その後、配列のコピーが作成され、元の配列がパラメーターとしてマージソート配列に入力され、配列のコピーがArrays.sort()メソッドでソートされている間にソートされます。次に、2 つの配列を比較して、それらが同じかどうかを確認します。

コードは次のとおりです。

import java.util.Arrays;
import java.util.Random;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Before;
import org.junit.Test;

public class Mergesort_3wayTest {

    private int[] toSort;
    private static int SIZE;
    private static int MAX;
    private static int tests = 20000;

    @Before
    public void setUp() throws Exception {
        Random generator = new Random();
        SIZE = generator.nextInt(30) + 1;
        MAX = generator.nextInt(30) + 1;
        toSort = new int[SIZE];
        for (int i = 0; i < toSort.length; i++) {
            toSort[i] = generator.nextInt(MAX);
        }
    }

    @Test
    public void itWorksRepeatably() {
        for (int i = 0; i < tests; i++) {
            System.out.println("1 - " + Arrays.toString(toSort));
            int[] sorted = new int[toSort.length];
            System.arraycopy(toSort, 0, sorted, 0, toSort.length);
            Arrays.sort(sorted);

            Mergesort_3way.mergesort(toSort);

            System.out.println("2 - " + Arrays.toString(toSort));

            assertArrayEquals(toSort, sorted);
        }
    }
}

挿入した から、println1 つの配列のみが作成され、その 1 つの配列を常にチェックするテストが実行されていることがはっきりとわかりましたが、明らかにそうではないランダムな配列が毎回作成されると思いました。

だから私の質問は、実行するたびassertArrayEquals(toSort, sorted)に最初からやり直すと推測した配列が1つだけ作成されるのはなぜですか。

グローバル変数と関係があると思いますが、よくわかりません...

4

5 に答える 5

2

テストメソッド内でループしています。セットアップメソッドはテストメソッドの前に1回呼び出されますが、各ループの反復の開始時に自動的に実行されることはありません。どのように期待しますか?

テストを最初から実行するたびに異なるランダム配列を作成する必要がありますが、再作成するものがないため、そのテスト実行の20000回の反復はすべて同じ配列を処理します。テストメソッド内で何かを起こさせたい場合は、それを自分で書く必要があります。

于 2012-05-24T15:48:24.197 に答える
1

toSort Array は 1 回だけ読み込まれます。itWorksRepeatably メソッドの前に一度だけ実行される setUp() メソッド内。したがって、itWorksRepeatably メソッドは同じ配列「テスト」、つまり 20000 回を使用します。

毎回異なる配列を表示するには、配列を生成するロジック (つまり、itWorksRepeatably メソッドの for ループ内の setUp メソッドのコード) を移動する必要があります。

于 2012-05-24T15:51:15.647 に答える
1

このコードを期待どおりに機能させたい場合は、関数内のコードを取得して、setup次のように各ループの開始時に呼び出される新しいプライベート メソッドにします。

private void magic()
{
Random generator = new Random();
        SIZE = generator.nextInt(30) + 1;
        MAX = generator.nextInt(30) + 1;
        toSort = new int[SIZE];
        for (int i = 0; i < toSort.length; i++) {
            toSort[i] = generator.nextInt(MAX);
        }

}

に続く:

@Test
    public void itWorksRepeatably() {
        for (int i = 0; i < tests; i++) {
           magic();  
           //rest of code  
}
}
于 2012-05-24T15:52:12.507 に答える
0

完全には理解できませんが、JUnit では、@Before メソッドは各 @Test メソッドの前に1 回実行されます。@Test メソッド内でループしている場合、@Before は呼び出されません。@Before メソッドは、ランダムな値で配列を再初期化する場所であるため、テストごとに 1 回だけ作成されます。

また、Arrays.toString() によって配列の作成を判断することはできません。これは、同じ要素を持つ 2 つの配列は、たとえそれらが 2 つの別個の配列であっても同じように表示されるためです。

于 2012-05-24T15:50:36.047 に答える
0

@before アノテーションを使用して setUp メソッドでランダムな配列を作成しています。この setup メソッドは、テスト メソッドごとに 1 回だけ呼び出されます。testmethod は 1 つしかないため、毎回 1 つの配列のみが作成されて再利用されます。乱数配列を作成するコードをセットアップからテスト メソッド内の for ループに移動します。お役に立てれば

于 2012-05-24T15:52:50.847 に答える