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接口的使用
二、测试过程
2.1 测试getArea()方法——返回矩形面积
public int getArea() {
return length*width;
}
-
测试分析
根据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 -
测试代码
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); } }
-
测试结果
用例编号 测试用例(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;
}
-
测试分析
同理于测试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 -
测试代码
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);
}
}
-
测试结果
用例编号 测试用例(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;
}
}
}
-
测试分析
需要参数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 -
测试代码
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); } }
-
测试结果
| 用例编号 | 测试用例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;
}
}
}
-
测试分析
同理于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 -
测试代码
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); } }
-
测试结果
用例编号 测试用例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 {
}
测试结果:

程序执行结果:

四、参考文献
本文作者:Joey-Wang
本文链接:https://www.cnblogs.com/joey-wang/p/16057556.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步