一、题目选择
题目(1):最大连续子数组和(最大子段和)
问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n
例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。
引用自《百度百科》
二、代码
程序代码:JunitDemo
参考博客:五种求解最大连续子数组的算法
package site.yuanrui.demo;
import java.util.Arrays;
/**
* 数据类
* @author YUANRUI
* version 1.0
*
*/
public class MaxArray
{
private int[] array;
public MaxArray(int[] array)
{
this.array = array;
}
/**
* 求字段和的最大值
* @return
*/
public int maxSubArray()
{
int n = this.array.length;
int result = 0;
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += this.array[i];
if (sum > result)
{
result = sum;
}
if (sum < 0)
{
//子串和为负数,丢掉
sum = 0;
}
}
return result;
}
/**
* 返回对象的字符串形式
*/
public String toString()
{
return "MaxArray [array=" + Arrays.toString(array) + "]";
}
}
三、选择覆盖标准并设计测试用例
1.5种逻辑覆盖测试方法对比
逻辑覆盖测试方法 | 说明 |
---|---|
语句覆盖 | 每条语句至少执行一次 |
判定覆盖 | 判定的每个分支至少执行一次 |
条件覆盖 | 判定的每个条件应取到各种可能的值 |
判定-条件覆盖 | 同时满足判定覆盖和条件覆盖 |
条件组合覆盖 | 判定中各种条件的每一种组合至少出现一次 |
2.画出上述程序段的流程图如下:
3.在这里我选择条件组合覆盖,根据条件组合覆盖的定义,每个判定包含一个条件,共有4种可能的组合,即该满足以下覆盖情况:
1.sum>result,sum<0
2.sum>result,sum>=0
3.sum<=result,sum<0
4.sum<=result,sum>=0
注:通过分析源码和流程图可知,第1种组合永远也不能满足,所以测试用例只需要覆盖后3个组合。
4.这里设计了个测试用例,用以覆盖上述4中条件组合,如下表所示:
测试用例 | array[] | 覆盖组合号 | 执行路径 | 覆盖条件 |
---|---|---|---|---|
测试用例1 | {-1,-2,-3,-4} | 3 | abe | sum<=result,sum<0 |
测试用例2 | {1,2,3,4} | 2 | acd | sum>result,sum>=0 |
测试用例3 | {-1,2,-2,4} | 4 | abd | sum<=result,sum>=0 |
四、利用自动测试工具对程序进行测试
package site.yuanrui.test;
import static org.junit.Assert.*;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import site.yuanrui.demo.MaxArray;
/**
* MaxArray测试类
* @author YUANRUI
*
*/
@RunWith(Parameterized.class)
public class MaxArrayTest
{
private int excepted;
private int[] array;
public MaxArrayTest(int excepted,int[] array)
{
this.excepted = excepted;
this.array = array;
}
@Parameters
public static Collection words()
{
return Arrays.asList(new Object[][]{
{20,new int[]{-2,11,-4,13,-5,-2}},//题目中测试用例
{0,new int[]{-1,-2,-3,-4}},//测试用例1
{10,new int[]{1,2,3,4}},//测试用例2
{4,new int[]{-1,2,-2,4}}//测试用例3
});
}
@Test
public void testMaxSubArray()
{
MaxArray ma = new MaxArray(this.array);
int num = ma.maxSubArray();
assertEquals(this.excepted, ma.maxSubArray());
}
}
五、程序运行和自动测试分析结果
由图可知,测试进度条为绿色,errors 0个,Failures 0个,4个测试全部通过。
六、总结
这次单元测试我选择的覆盖标准是条件组合覆盖,条件组合覆盖是最严密的白盒覆盖方法,有利也有弊,它带来的弊端就是过于复杂且产生的用例数过多,成本太高;正所谓鱼与熊掌不能兼得,必须在成本和覆盖率之间根据实际情况找个平衡点。 之前就接触过单元测试,当时单纯地认为单元测试就是测试一个函数是否按照规定要求实现了全部功能;学了软件工程这门课之后才知道还有覆盖标准、覆盖率等这些专业术语。 未来未至,仍需前行!!!