一、待测功能及要求
待测功能为解一元二次方程,输入a,b,c三个参数,输出方程并输出结果
输出方程要求:
- 输出形为ax²+bx+c=0的方程格式;
如果某项系数为0,则不输出该项;
如果x²或x前系数为1,则不显示;
如果系数为负,则将加号改为减号。
输出结果要求:
- 如果有两个实数根,则输出“方程有两个实数根:x1= ,x2= ”、
- 如果有一个实数根,则输出“方程有一个实数根:x1=x2= ”
- 如果没有实数根,则输出“方程没有实数根”
二、待测代码
SolveEquation.java
package WhiteBoxTesting;
import java.util.Scanner;
/**
* 一元二次方程求解
*/
public class SolveEquation {
private static String format(double d) {
String s = Double.toString(d);
s = s.replaceAll("0+?$", ""); //去除多余0
s = s.replaceAll("[.]$", ""); //小数点后全0去掉小数点
return s;
}
public static StringBuffer printEquation(double a, double b, double c) {
StringBuffer equation = new StringBuffer();
if (a != 0) {
if (Math.abs(a) != 1) {
equation.append(format(a));
equation.append("x²");
} else {
if (a < 0) {
equation.append("-");
}
equation.append("x²");
}
}
if (b != 0) {
if (Math.abs(b) != 1) {
equation.append(format(b));
equation.append("x");
} else {
if (b > 0) {
equation.append("+");
} else {
equation.append("-");
}
equation.append("x");
}
}
if (c != 0) {
if (c > 0) {
equation.append("+");
}
equation.append(format(c));
}
equation.append("=0");
// System.out.println(equation);
/** ax²+bx+c=0 */
return equation;
}
public static String solveEquation(double a, double b, double c) {
String solution;
double delta = b*b - 4*a*c;
double x1, x2;
if (delta >= 0) {
if (delta == 0) {
x1 = -b/(2*a);
// System.out.println("方程有一个实数根:x1=x2=" + format(x1));
solution = "方程有一个实数根:x1=x2=" + format(x1);
} else {
x1 = (-b+Math.sqrt(delta))/(2*a);
x2 = (-b-Math.sqrt(delta))/(2*a);
// System.out.println("方程有两个实数根:x1=" + format(x1) + ", x2=" + format(x2));
solution = "方程有两个实数根:x1=" + format(x1) + ", x2=" + format(x2);
}
} else {
// System.out.println("方程没有实数根");
solution = "方程没有实数根";
}
return solution;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double a, b, c;
System.out.println("请输入一元二次方程的参数");
System.out.print("a=");
a = scan.nextInt();
System.out.print("b=");
b = scan.nextInt();
System.out.print("c=");
c = scan.nextInt(); //ax+bx+c=0
// 输出方程
System.out.println(printEquation(a, b, c));
// 求解方程
System.out.println(solveEquation(a, b, c));
}
}
三、测试用例
采用判定-条件覆盖进行测试
printEquation方法测试:
①a=0,b=0,c=0,“=0”
②a=1,b=1,c=1,“x²+x+1=0”
③a=-1,b=-1,c=-1,“-x²-x-1=0”
④a=4,b=-4,c=1,“4x²-4x+1=0”solveEquation方法测试:
①a=1,b=-4,c=4,“方程有一个实数根:x1=x2=2”
②a=1,b=-5,c=6,“方程有两个实数根:x1=3, x2=2”
③a=1,b=1,c=1,“方程没有实数根”四、测试代码
在IDEA安装JUnit和JUnitGenerator V2.0插件
导入JUnit4依赖包
在待测代码中按Alt+Insert,选择JUnit Test生成Test文件
分别为printEquation和solveEquation方法创建测试类,谈价参数化测试方法
创建TestRunner类以便方便地对两个方法进行测试
PrintEquationTest.java
package test;
import WhiteBoxTesting.SolveEquation;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
/**
* SolveEquation.printEquation Tester.
*
* @author shaomingshan
* @since 五月 20, 2018
* @version 1.0
*/
/*
@BeforeClass 全局只会执行一次,而且是第一个运行
@Before 在测试方法运行之前运行
@Test 测试方法
@After 在测试方法运行之后允许
@AfterClass 全局只会执行一次,而且是最后一个运行
@Ignore 忽略此方法
*/
@RunWith(Parameterized.class)
public class PrintEquationTest {
private double a;
private double b;
private double c;
private String expected;
public PrintEquationTest(double a, double b, double c, String expected) {
this.a = a;
this.b = b;
this.c = c;
this.expected = expected;
}
@Parameterized.Parameters
public static Collection parameter() {
return Arrays.asList(new Object[][]{
{0, 0, 0, "=0"},
{1, 1, 1, "x²+x+1=0"},
{-1, -1, -1, "-x²-x-1=0"},
{4, -4, 1, "4x²-4x+1=0"}
});
}
/**
* Method: printEquation(double a, double b, double c)
*/
@Test
public void testPrintEquation() throws Exception {
System.out.println("a=" + a + ", b=" + b + ", c=" + c + ", expected:" + expected);
StringBuffer result;
result = SolveEquation.printEquation(a, b, c);
Assert.assertEquals(expected, result.toString());
}
}
SolveEquationTest.java
package test;
import WhiteBoxTesting.SolveEquation;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
/**
* SolveEquation.solveEquation Tester.
*
* @author shaomingshan
* @since 五月 20, 2018
* @version 1.0
*/
/*
@BeforeClass 全局只会执行一次,而且是第一个运行
@Before 在测试方法运行之前运行
@Test 测试方法
@After 在测试方法运行之后允许
@AfterClass 全局只会执行一次,而且是最后一个运行
@Ignore 忽略此方法
*/
@RunWith(Parameterized.class)
public class SolveEquationTest {
private double a;
private double b;
private double c;
private String expected;
public SolveEquationTest(double a, double b, double c, String expected) {
this.a = a;
this.b = b;
this.c = c;
this.expected = expected;
}
@Parameterized.Parameters
public static Collection parameter() {
return Arrays.asList(new Object[][]{
{1, -4, 4, "方程没有实数根"},
{1, -5, 6, "方程没有实数根"},
{1, 1, 1, "方程没有实数根"}
});
}
/**
* Method: solveEquation(double a, double b, double c)
*/
@Test
public void testSolveEquation() throws Exception {
System.out.println("a=" + a + ", b=" + b + ", c=" + c + ", expected:" + expected);
String result;
result = SolveEquation.solveEquation(a, b, c);
Assert.assertEquals(expected, result);
}
}
TestRunner.java
package test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
System.out.println("PrintEquationTest");
Result result2 = JUnitCore.runClasses(PrintEquationTest.class);
for (Failure failure : result2.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result2.wasSuccessful());
System.out.println("SolveEquationTest");
Result result1 = JUnitCore.runClasses(SolveEquationTest.class);
for (Failure failure : result1.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result1.wasSuccessful());
}
}
五、测试结果
运行TestRunner结果:
分别运行两个测试类:
将某个测试期望修改为错误值的结果: