简体   繁体   English

JUnit测试创建相同的数组而不是随机数组

[英]JUnit test creating the same array instead of random one

I am creating a JUnit which is supposed to make each time an array of random size with random integers in it. 我正在创建一个JUnit,它应该每次使一个包含随机整数的随机大小的数组。 Afterwards a copy of the array is made and the original array is inputed as a parameter in my mergesort array and gets sorted while the copy of the array gets sorted with the Arrays.sort() method. 之后,制作数组的副本,并在我的mergesort数组中将原始数组作为参数输入并进行排序,同时使用Arrays.sort()方法对数组的副本进行排序。 Then the two arrays are compared to see if they are the same. 然后比较两个数组以查看它们是否相同。

Here is the code: 这是代码:

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);
        }
    }
}

I could clearly see from the println 's I inserted that only one array was created and the test was running constantly checking that one array but I thought it would create each time a random one which is clearly not the case. 我从println的插入中可以清楚地看到,仅创建了一个数组,并且测试正在不断检查该数组,但是我认为每次都会创建一个随机数组,但事实并非如此。

So my question is why is only one array created which I guessed each time the assertArrayEquals(toSort, sorted) run it would the start over again. 所以我的问题是,为什么只创建一个数组,而我每次运行assertArrayEquals(toSort, sorted)时都会猜测它会重新开始。

I believe it has something to do with the global variables but I'm not quite sure... 我相信这与全局变量有关,但我不确定...

You're looping inside your test method . 您正在内部循环测试方法 The setup method will be called once before your test method, but it's not going to automatically be run at the start of each loop iteration. setup方法将测试方法之前被调用一次,但不会在每次循环迭代开始时自动运行。 How would you expect it to be? 您希望它如何?

It should be creating a different random array each time you run the tests from scratch, but the 20000 iterations within that test run will all be dealing with the same array, as there's nothing to recreate it. 应该建立在每次运行从头开始测试的时间不同的随机排列,但试运行的20000次迭代都将被处理同一阵列,因为没有什么可以重新创建它。 If you want something to happen within your test method, you need to write that yourself. 如果您希望测试方法中发生某些事情,则需要自己编写。

The toSort Array is populated only once. toSort数组仅填充一次。 In the setUp() method which is executed only once before the itWorksRepeatably method. 在setUp()方法中,该方法仅在itWorksRepeatably方法之前执行一次。 Hence the itWorksRepeatably method uses the same array "tests" ie 20000 times. 因此,itWorksRepeatably方法使用相同的数组“测试”,即20000次。

You will need to move the logic that generates the array ( ie the code in the setUp method inside the for loop in the itWorksRepeatably method for you to see different arrays each time. 您将需要移动生成数组的逻辑(即,itWorksRepeatably方法中for循环内setUp方法中的代码,以便您每次都能看到不同的数组。

If you want this code to function the way you anticipate take the code in your setup function and make it into a new private method that is invoked at the start of each loop like so: 如果您希望此代码以预期的方式发挥作用,请将代码放入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);
        }

}

Followed by: 其次是:

@Test
    public void itWorksRepeatably() {
        for (int i = 0; i < tests; i++) {
           magic();  
           //rest of code  
}
}

Not entirely sure I understand... but in JUnit, the @Before methods are executed once before each @Test method. 不能完全确定我理解...但是在JUnit中,@Before方法在每个@Test方法之前执行一次 If you are looping within a @Test method, @Before isn't called. 如果在@Test方法中循环,则不会调用@Before。 Since the @Before method is where you are re-initializing the array with random values, that's created only once per test. 由于@Before方法是您使用随机值重新初始化数组的位置,因此每个测试仅创建一次。

Also, you cannot determine array creation by Arrays.toString(), simply because two arrays which have the same elements will display the same, even if they are two separate arrays. 同样,您不能通过Arrays.toString()确定数组的创建,仅因为具有相同元素的两个数组将显示相同的内容,即使它们是两个单独的数组也是如此。

You are creating a random array in your setUp method with @before annotation, this setup method will be called only once per test method. 您正在使用@before注释在setUp方法中创建一个随机数组,每个测试方法将仅调用一次此设置方法。 As you only have a single testmethod only one array is created and reused every time. 由于只有一个测试方法,因此每次只能创建一个阵列并重新使用。 Move the code to create random array from setup to for-loop inside your test method. 将代码移动到测试方法中,可从设置创建随机数组到for循环。 Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM