1.编写测试

本节课主要是教我们自己编写一些测试代码,不过度依赖于autograder
假设编写一个method:sort(),作用是将数组排序,例如:

{"i", "have", "an", "egg"}

排序后应该是:

{"an", "egg", "have", "i"}

因此我们可以检查输入的原始数组的每一项与输出结果的每一项是否相等来判断sort()是否正确:

        String[] input = {"i", "have", "an", "egg"};
        String[] expected = {"an", "egg", "have", "i"};
        Sort.sort(input);
        for (int i = 0; i < input.length; i += 1) {
            if (!input[i].equals(expected[i])) {
                System.out.println("Mismatch in position " + i + ", expected: " + expected + ", but got: " + input[i] + ".");
                break;
            }


但是使用循环和.equals()方法逐项比对非常繁琐,org.junit library可以帮助我们更好地完成此项评测工作,只需一行,即可代替循环的整段,使用的是

 org.junit.Assert.assertArrayEquals(expected, input)

结果如下:

    String[] input = {"i", "have", "an", "egg"};
    String[] expected = {"an", "egg", "have", "i"};
    Sort.sort(input);
    org.junit.Assert.assertArrayEquals(expected, input);

2.选择排序

本例使用递归实现选择排序,我们把选择排序拆分成3种方法:

  • findMinium():找到当前数组中的数值最小项
  • Swap():把最小项与数组第一项交换
  • Sort():调用前两个函数,例如第一次找到了数组中最小的元素并将其调换到第一项的位置,之后从第二项开始(也就是不必再对第一项排序),重复步骤:递归+贪心

最终如下:

public class SelectionSort{

    public static int findMinium(String[] x,int start){
        int minIndex = start;
        for(int i = start;i < x.length;i ++){
            int cmp = x[i].compareTo(x[minIndex]);
            if(cmp < 0){
                minIndex = i;
            }
        }
        return minIndex;
    }

    public static void Swap(String[] x,int a,int b){
        String temp = x[a];
        x[a] = x[b];
        x[b] = temp;
    }

    public static void Sort(String[] x,int start){
        if(start == x.length){
            return;
        }
        int min = findMinium(x,start);
        Swap(x,start,min);
        Sort(x,start+1);
    }
}

3.编写测试方法

对每一种方法编写测试:
1.testFindminium():

        public static void testfindMinium(){
            String[] input = {"i","have","an","egg"};
            int expected = 2;
            int actual = SelectionSort.findMinium(input,0);
            org.junit.Assert.assertEquals(expected,actual);
        }

2.testSwap():

        public static void testSwap(){
            String[] input = {"i","have","an","egg"};
            String[] expected = {"an","have","i","egg"};
            int a = 0;
            int b = 2;
            SelectionSort.Swap(input,a,b);
            org.junit.Assert.assertArrayEquals(expected,input);
        }

3.testSort():

        public static void testSort(){
            String[] input = {"i","have","an","egg"};
            String[] expected = {"an","egg","have","i"};
            SelectionSort.Sort(input,0);
            org.junit.Assert.assertArrayEquals(expected,input);
        }

编写完毕后,我们需要测试哪一个函数,就在main()中调用该测试方法:

        public static void main(String[] args){
            testSort();
            testfindMinium();
            testSwap();
        }

注意:
最好不要把多个测试方法同时运行,因为它们其中任何一个运行失败将会导致程序终止,从而在它之后的测试都将不会再运行,也就是说需要每次去手动注释掉一些方法,每次只能运行一个
可见此方法是很繁琐的,下面有优化策略


4.优化 : 使用org.junit.Test

  1. 在每一个测试方法前面加上注释:

    @org.junit.Test
  2. 然后,删除主方法public static void main()
  3. 将所有test()改为non-static,也就是去掉static关键字
  4. 点击上方Tab栏:run-->选择左右对称红绿三角的run,之后可以看到每个测试方法均被运行
    image.png
    同时,也可以选择点击左侧竖直标号栏的绿色播放按钮,对你想运行的测试方法单个运行,由此摆脱了每次人工注释掉某个不需要运行的方法的烦恼

5.使用org.junit库

每次使用junit来测试debug都要写很多前缀org.junit.Assert....,所以为了减少工作量,我们引入junit的包,在Intellij IDEA下,点击
File--->Project Structure
image.png

点击library,点击+

image.png

找到Intellij IDEA的安装路径,在安装路径下选择lib文件,找到junit4.java,选择OK,完成导入

PS:后来才发现cs61b的library-sp18里面有junit.jar包 QAQ

HQYVBA8}2code%C3[T@C9HL~/codeR.png

导入之后,可以直接在java程序中import

import org.junit.Test;
import static org.junit.Assert.*;

之后可以将

org.junit.Test 替换为 Test
org.junit.Assert 去掉

更加方便可读:

import org.junit.Test;
import static org.junit.Assert.*;

public class TestSort{
    @Test
        public void testSort(){
            String[] input = {"i","have","an","egg"};
            String[] expected = {"an","egg","have","i"};
            SelectionSort.Sort(input,0);
            assertArrayEquals(expected,input);
        }
    @Test
        public void testfindMinium(){
            String[] input = {"i","have","an","egg"};
            int expected = 2;
            int actual = SelectionSort.findMinium(input,0);
            org.junit.Assert.assertEquals(expected,actual);
        }
    @Test
        public void testSwap(){
            String[] input = {"i","have","an","egg"};
            String[] expected = {"an","have","i","egg"};
            int a = 0;
            int b = 2;
            SelectionSort.Swap(input,a,b);
            assertArrayEquals(expected,input);
        }

}

更多junit库的Assert类的方法请参考:
Assert(JUnit API)


Fallenpetals
4 声望9 粉丝