Java教程

JUnit测试实例

本文主要是介绍JUnit测试实例,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JUnit 测试实例

一、 实验要求

对Rectangle程序进行测试:根据已经学习的测试思想,对函数getArea()、getPerimeter()和findMax()进行测试。

import java.util.Comparator;
public class Rect {   
    private int length;
    private int width;    
    public Rect(int length, int width) {
        this.length = length;
        this.width = width;
    }   
    public int getLength() {return length;}
    public void setLength(int length) {this.length = length;}
    public int getWidth() {return width;}
    public void setWidth(int width) {this.width = width;} 
    public int getArea() {return length*width;}
    public int getPerimeter() {return 2*length + width;}   
    public String getObject() {
        return "("+length+","+width+")";
    }
  
    public static <AnyType>
    AnyType findMax(AnyType[] arr, Comparator<? super AnyType> cmp) {     
        int maxIndex = 0;
        for(int i = 1; i < arr.length; i++)
            if(cmp.compare(arr[i], arr[maxIndex]) > 0)
                maxIndex = i;
        return arr[maxIndex];
    }
    
    public static class areaCompare implements Comparator<Rect> {
        @Override
        public int compare(Rect o1, Rect o2) {
            // TODO Auto-generated method stub
            if(o1.getArea() < o2.getArea()) {
                return 1;
            }else if(o1.getArea() == o2.getArea()) {
                return 0;
            }else{
                return -1;
            }
        }
    }
    
    public static class perimeterCompare implements Comparator<Rect> {
        @Override
        public int compare(Rect o1, Rect o2) {
            // TODO Auto-generated method stub
            if(o1.getPerimeter() > o2.getPerimeter()) {
                return 1;
            }else if(o1.getPerimeter() == o2.getPerimeter()) {
                return 0;
            }else{
                return -1;
            }
        }
    }
    
    public static void main(String[] args) {
        Rect[] arr = new Rect[] {
                new Rect(10, 20), new Rect(2, 65),
                new Rect(3, 10), new Rect(6, 20)
                };
        System.out.println("面积最大:"+findMax(arr, new areaCompare()).getObject());
        System.out.println("周长最长:"+findMax(arr, new perimeterCompare()).getObject());
    }
}

{% note primary %}
若对代码中实现比较器的写法不理解,请看“四、参考文献” Comparator接口的使用
{% endnote %}

二、测试过程

2.1 测试getArea()方法——返回矩形面积

public int getArea() {
    return length*width;
}
  1. 测试分析

    根据Rect类可得成员变量length、width为int型,含义为矩形的长宽,故合法输入为正数,负数和0位非法输入。

    此处假设非法输入返回值为-1。

    设计测试用例如下:

    用例编号 测试用例(length,width) 预期结果(返回值)
    1 (3,4) 12
    2 (-3,4) -1
    3 (4,-3) -1
    4 (-5,-6) -1
    5 (3,0) -1
    6 (0,4) -1
    7 (0,0) -1
  2. 测试代码

    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    import java.util.Arrays;
    
    @RunWith(Parameterized.class)
    public class TestRectArea extends TestCase {
        private int length;
        private int width;
        private int expected;
        
        public TestRectArea(int length, int width, int expected){
            this.length=length;
            this.width=width;
            this.expected=expected;
        }
    
        //假设要测试的getArea方法遇到非法输入时返回-1
        @Parameterized.Parameters(name="{index}:{0}*{1}={2}")
        public static Iterable<Object []> data(){
            return Arrays.asList(new Object[][]{
                    {3,4,12},
                    {-3,4,-1},
                    {4,-3,-1},
                    {-5,-6,-1},
                    {3,0,-1},
                    {0,4,-1},
                    {0,0,-1}
            });
        }
    
        @Test
        public void testGetArea(){
            assertEquals(new Rect(length,width).getArea(),expected);
        }
    }
    
  3. 测试结果

    image-20220326054436064
    用例编号 测试用例(length,width) 预期结果(返回值) 实际结果
    1 (3,4) 12 12
    2 (-3,4) -1 -12
    3 (4,-3) -1 -12
    4 (-5,-6) -1 30
    5 (3,0) -1 0
    6 (0,4) -1 0

|7|(0,0)|-1|0|

由此可见,此方法代码并没有考虑输入为0和负数的非法情况。


2.2 测试getPerimeter()方法——返回矩形周长

public int getPerimeter() {
    return 2*length + width;
}
  1. 测试分析

    同理于测试getArea(),此处需要的参数只有length、width,所以考虑负数和0的非法输入。

    设计测试用例如下:

    用例编号 测试用例(length,width) 预期结果(返回值)
    1 (5,6) 22
    2 (-3,4) -1
    3 (3,-4) -1
    4 (-3,-4) -1
    5 (3,0) -1
    6 (0,4) -1
    7 (0,0) -1
  2. 测试代码

import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;

@RunWith(Parameterized.class)
public class TestRectPerimeter extends TestCase {
    private int length;
    private int width;
    private int expected;

    public TestRectPerimeter(int length,int width,int expected){
        this.length=length;
        this.width=width;
        this.expected=expected;
    }

    //假设要测试的getPerimeter方法遇到非法输入时返回-1
    @Parameterized.Parameters(name="{index}:({0}+{1})*2={2}")
    public static Iterable<Object []> data(){
        return Arrays.asList(new Object[][]{
                {5,6,22},
                {-3,4,-1},
                {3,-4,-1},
                {-3,-4,-1},
                {3,0,-1},
                {0,4,-1},
                {0,0,-1}
        });
    }

    @Test
    public void testGetPerimeter(){
        assertEquals(new Rect(length,width).getPerimeter(),expected);
    }
}
  1. 测试结果

    image-20220326054520412
    用例编号 测试用例(length,width) 预期结果(返回值) 实际结果
    1 (5,6) 22 16
    2 (-3,4) -1 -2
    3 (3,-4) -1 2
    4 (-3,-4) -1 -10
    5 (3,0) -1 6
    6 (0,4) -1 4

| 7 | (0,0) | -1 |0|

可见,方法代码并没有考虑输入为0和负数的非法情况,且计算过程存在问题,返回去看代码发现没有加括号,应

return 2*(length+width);	

2.3 测试findMax()方法——返回矩形数组中面积or周长最大的矩形对象

AnyType findMax(AnyType[] arr, Comparator<? super AnyType> cmp) {
    int maxIndex = 0;
    for(int i = 1; i < arr.length; i++)
        if(cmp.compare(arr[i], arr[maxIndex]) > 0)
            maxIndex = i;
    return arr[maxIndex];
}

2.3.1 比较器areaCompare——比较面积

public static class areaCompare implements Comparator<Rect> {
    @Override
    public int compare(Rect o1, Rect o2) {
        // TODO Auto-generated method stub
        if(o1.getArea() < o2.getArea()) {
            return 1;
        }else if(o1.getArea() == o2.getArea()) {
            return 0;
        }else{
            return -1;
        }
    }
}
  1. 测试分析

    需要参数length、width,所以考虑负数和0的非法输入。

    需注意⚠️:若比较面积时输入的矩形数组都为非法输入(矩形长宽都存在0或负数),getArea()因为非法输入都return -1,则areaCompare比较器中比较函数compare都会return 0,则findMax中return arr[0],返回一个非法矩形,显然错误。故此处findMax也要有一个对应非法输入时的输出,假设为null。

    设计测试用例如下:

    用例编号 测试用例Rect[] 预期结果
    1 (10,20),(2,65),(3,10),(6,20) (10,20)
    2 (-4,3),(5,-6),(-10,-10),(1,1) (1,1)
    3 (0,3),(6,0),(0,0),(1,1) (1,1)
    4 (0,3),(6,0),(0,0),(-1,-1) null
  2. 测试代码

    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    
    import java.util.Arrays;
    
    @RunWith(Parameterized.class)
    public class TestRectFindMaxArea extends TestCase {
        private Rect[] arr;
        private Rect expected;
    
        public TestRectFindMaxArea(Rect[] arr,Rect expected){
            this.arr=arr;
            this.expected=expected;
        }
    
        @Parameterized.Parameters
        public static Iterable<Object[]> data(){
            return Arrays.asList(new Object[][]{
                    {new Rect[] {
                            new Rect(10, 20), new Rect(2, 65),
                            new Rect(3, 10), new Rect(6, 20)
                    },new Rect(10,20)},
                    {new Rect[] {
                            new Rect(-4, 3), new Rect(5, -6),
                            new Rect(-10, -10), new Rect(1, 1)
                    },new Rect(1,1)},
                    {new Rect[] {
                            new Rect(0, 3), new Rect(6, 0),
                            new Rect(0, 0), new Rect(1, 1)
                    },new Rect(1,1)},
                    {new Rect[] {
                            new Rect(0, 3), new Rect(6, 0),
                            new Rect(0, 0), new Rect(-1, -1)
                    },null}
            });
        }
    
        @Test
        public void testFindMax(){
            Rect temp=Rect.findMax(arr, new Rect.areaCompare());
            String stemp,sexpected;
            if(temp!=null) stemp=temp.getObject();
            else stemp="null";
            if(expected!=null) sexpected=expected.getObject();
            else sexpected="null";
            assertEquals(stemp,sexpected);
        }
    }
    
  3. 测试结果

    image-20220326054608135 | 用例编号 | 测试用例Rect[] | 预期结果 |实际结果| | :------: | :---------------------------: | :------: | :------: | | 1 | (10,20),(2,65),(3,10),(6,20) | (10,20) |(3,10)| | 2 | (-4,3),(5,-6),(-10,-10),(1,1) | (1,1) |(5,-6)| | 3 | (0,3),(6,0),(0,0),(1,1) | (1,1) |(0,3)| | 4 | (0,3),(6,0),(0,0),(-1,-1) | null |(0,3)|

    可见,代码没有考虑输入矩形数组存在矩形长宽非法or全部矩形长宽均非法的情况,且通过第一个测试用例可知,计算过程存在问题,返回去看代码发现areaCompare比较器中比较函数compare存在逻辑错误,应返回最大矩形对象,却返回最小矩形对象,应

    public int compare(Rect o1, Rect o2) {
        if(o1.getArea() > o2.getArea()) {
            return 1;
        }else if(o1.getArea() == o2.getArea()) {
            return 0;
        }else{
            return -1;
        }
    }
    

2.3.2 比较器perimeterCompare——比较周长

public static class perimeterCompare implements Comparator<Rect> {
    @Override
    public int compare(Rect o1, Rect o2) {
        // TODO Auto-generated method stub
        if(o1.getPerimeter() > o2.getPerimeter()) {
            return 1;
        }else if(o1.getPerimeter() == o2.getPerimeter()) {
            return 0;
        }else{
            return -1;
        }
    }
}
  1. 测试分析

    同理于areaCompare,需要参数length、width,所以考虑负数和0的非法输入;设置null为全非法输入的返回值。
    设计测试用例

    用例编号 测试用例Rect[] 预期结果
    1 (10,20),(2,65),(3,10),(6,20) (2,65)
    2 (-4,3),(5,-6),(-10,-10),(1,1) (1,1)
    3 (0,3),(6,0),(0,0),(1,1) (1,1)
    4 (0,3),(6,0),(0,0),(-1,-1) null
  2. 测试代码

    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    
    import java.util.Arrays;
    
    @RunWith(Parameterized.class)
    public class TestRectFindMaxPerimeter extends TestCase {
        private Rect[] arr;
        private Rect expected;
    
        public TestRectFindMaxPerimeter(Rect[] arr,Rect expected){
            this.arr=arr;
            this.expected=expected;
        }
    
        @Parameterized.Parameters
        public static Iterable<Object[]> data(){
            return Arrays.asList(new Object[][]{
                    {new Rect[] {
                            new Rect(10, 20), new Rect(2, 65),
                            new Rect(3, 10), new Rect(6, 20)
                    },new Rect(2,65)},
                    {new Rect[] {
                            new Rect(-4, 3), new Rect(5, -6),
                            new Rect(-10, -10), new Rect(1, 1)
                    },new Rect(1,1)},
                    {new Rect[] {
                            new Rect(0, 3), new Rect(6, 0),
                            new Rect(0, 0), new Rect(1, 1)
                    },new Rect(1,1)},
                    {new Rect[] {
                            new Rect(0, 3), new Rect(6, 0),
                            new Rect(0, 0), new Rect(-1, -1)
                    },null}
            });
        }
    
        @Test
        public void testFindMax(){
            Rect temp=Rect.findMax(arr, new Rect.perimeterCompare());
            String stemp,sexpected;
            if(temp!=null) stemp=temp.getObject();
            else stemp="null";
            if(expected!=null) sexpected=expected.getObject();
            else sexpected="null";
            assertEquals(stemp,sexpected);
        }
    }
    
  3. 测试结果

    image-20220326054650337
    用例编号 测试用例Rect[] 预期结果 实际结果
    1 (10,20),(2,65),(3,10),(6,20) (2,65) (2,65)
    2 (-4,3),(5,-6),(-10,-10),(1,1) (1,1) (5,-6)
    3 (0,3),(6,0),(0,0),(1,1) (1,1) (6,0)
    4 (0,3),(6,0),(0,0),(-1,-1) null (6,0)

    可见代码同样没有考虑输入矩形数组存在矩形长宽非法or全部矩形长宽均非法的情况。


三、修改代码

import java.util.Comparator;
public class Rect {
    private int length;
    private int width;
    public Rect(int length, int width) {
        this.length = length;
        this.width = width;
    }
    public int getLength() {return length;}
    public void setLength(int length) {this.length = length;}
    public int getWidth() {return width;}
    public void setWidth(int width) {this.width = width;}
    public int getArea(){
        if(length>0 && width >0) return length*width;
        else return -1;
    }
    public int getPerimeter() {
        if(length >0 && width >0) return 2*(length + width);
        else return -1;
    }
    public String getObject() {
        return "("+length+","+width+")";
    }

    public static <AnyType>
    AnyType findMax(AnyType[] arr, Comparator<? super AnyType> cmp){
        int maxIndex = 0;
        for(int i = 1; i < arr.length; i++)
            if(cmp.compare(arr[i], arr[maxIndex]) > 0){
                maxIndex = i;
            }
        if(((Rect)arr[maxIndex]).getLength()<=0 || ((Rect)arr[maxIndex]).getWidth()<=0) return null;
        else return arr[maxIndex];
    }

    public static class areaCompare implements Comparator<Rect> {
        @Override
        public int compare(Rect o1, Rect o2){
             // TODO Auto-generated method stub
            if(o1.getArea() > o2.getArea()) {
                return 1;
            }else if(o1.getArea() == o2.getArea()) {
                return 0;
            }else{
                return -1;
            }
        }
    }

    public static class perimeterCompare implements Comparator<Rect> {
        @Override
        public int compare(Rect o1, Rect o2) {
            // TODO Auto-generated method stub
            if(o1.getPerimeter() > o2.getPerimeter()) {
                return 1;
            }else if(o1.getPerimeter() == o2.getPerimeter()) {
                return 0;
            }else{
                return -1;
            }
        }
    }

    public static void main(String[] args) {
        Rect[] arr = new Rect[] {
                new Rect(10, 20), new Rect(2, 65),
                new Rect(3, 10), new Rect(6, 20)
        };
        Rect rect1=findMax(arr, new areaCompare());
        Rect rect2=findMax(arr, new perimeterCompare());
        if(rect1 == null) System.out.println("输入的矩形数组中所有矩形长宽均非法!");
        else System.out.println("面积最大:"+rect1.getObject());
        if(rect2 == null) System.out.println("输入的矩形数组中所有矩形长宽均非法!");
        else System.out.println("周长最长:"+rect2.getObject());
    }
}

为方便测试,使用测试套件Suite,代码如下:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({TestRectArea.class,TestRectPerimeter.class,TestRectFindMaxArea.class,TestRectFindMaxPerimeter.class})
public class TestRectSuite {
}

测试结果:

image-20220326053947193

程序执行结果:

image-20200331140852779

四、参考文献

Comparator接口的使用

这篇关于JUnit测试实例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!