为 Java 程序编写测试用例,该程序在迭代中接受用户输入以获得最终值
Writing a test case for a Java program which takes user input in iterations to get to a final value
下面是 java 程序,用于猜测汤姆有多少个苹果。如果汤姆的苹果数量比猜测的数量多,他会打得更高,如果比猜得少,他会打得更低。当猜对数字时,他会回复none。我的任务是为这个程序编写一个 JUnit 测试用例。由于基于用户输入,猜测的数字会递减或递增,直到我们达到实际值为止,这让我很困惑如何为这个程序编写 JUnit 测试用例
public static void main(String args[]){
System.out.println("Guess the number of Apples Tom has");
Scanner sc= new Scanner(System.in);
int number=sc.nextInt();
System.out.println("Tom, is it higher or lower?");
String higherOrLower=sc.nextLine();
while(true){
number= getValue(higherOrLower,number);
System.out.println("Tom, is it higher or lower?");
higherOrLower=sc.nextLine();
if(higherOrLower.equalsIgnoreCase("none")) {
break;
}
}
}
public static int getValue(String i,int j){
if(i.equalsIgnoreCase("lower")) {
j--;
return j;
} else if(i.equalsIgnoreCase("higher")) {
j++;
return j;
} else {
return j;
}
}
好的,让我们在这里详细介绍一下...
好的单元测试的基础是好的代码。这就解释了为什么编写单元测试不仅可以使代码工作更可靠,还可以使编码人员编写更好的代码(因为糟糕的代码通常很难测试)。
在您的示例中,您有两种方法(我假设您还没有深入了解面向对象编程 (OOP) 的细节,所以我不会讨论如何使用额外的 类).
一种方法进行实际的数字运算(好的,一点点运算),另一种方法进行输入。不幸的是,您的输入法也是您的主要方法,因此您可以做得更好一些,因为主要方法不太适合测试。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // We'll ignore finer problems with scanners, etc. here
playGame(scanner);
}
public static void playGame(Scanner scanner) {
System.out.println("Guess the number of Apples Tom has");
Scanner sc= new Scanner(System.in);
int number=sc.nextInt();
System.out.println("Tom, is it higher or lower?");
String higherOrLower=sc.nextLine();
while(true){
number= getValue(higherOrLower,number);
System.out.println("Tom, is it higher or lower?");
higherOrLower=sc.nextLine();
if(higherOrLower.equalsIgnoreCase("none")) {
break;
}
}
}
这一小改动将使您的代码更易于测试。让我们从简单的部分开始,即 getValue
方法:
@测试
public无效lower_should_return_number_minus_1(){
int result = getValue("lower", 10);
Assert.assertEquals(9, 结果); // 简单断言
}
@Test
public void higher_should_return_number_plus_1() {
int result = getValue("higher", 10);
Assert.assertEquals(11, result); // simple assertions
}
@Test
public void garbage_should_return_same_number() {
int result = getValue("Hello, Polly!", 10);
Assert.assertEquals(10, result); // simple assertions
}
这将测试您的大部分可能性。如果您为字符串输入 null,最好也测试一下会发生什么,只是为了确定 ;-)
测试另一种方法会有点困难,因为它涉及一些小技巧...
@Test(timeout=1000)
public void game_should_work_on_input() {
final ByteArrayInputStream stream = new ByteArrayInputStream(String.format("5%nlower%nlower%nnone%n").getBytes());
final Scanner scanner = new Scanner(stream);
playGame(scanner);
}
这里我们简单地创建一个"fake"输入,它由“5”、"lower"、"lower"和"none"组成(老实说,5之间有一个空行和第一个较低的)。 String.format
将为每个 %n
添加正确的新行字符。如果您的测试成功,则意味着游戏已经进行到最后。如果没有,超时将发生在 1000 毫秒之前(这意味着您的游戏没有正确结束,这是应该的)。老实说,没有测试过,但我敢肯定,你可以从那里开始。 ;-)
下面是 java 程序,用于猜测汤姆有多少个苹果。如果汤姆的苹果数量比猜测的数量多,他会打得更高,如果比猜得少,他会打得更低。当猜对数字时,他会回复none。我的任务是为这个程序编写一个 JUnit 测试用例。由于基于用户输入,猜测的数字会递减或递增,直到我们达到实际值为止,这让我很困惑如何为这个程序编写 JUnit 测试用例
public static void main(String args[]){
System.out.println("Guess the number of Apples Tom has");
Scanner sc= new Scanner(System.in);
int number=sc.nextInt();
System.out.println("Tom, is it higher or lower?");
String higherOrLower=sc.nextLine();
while(true){
number= getValue(higherOrLower,number);
System.out.println("Tom, is it higher or lower?");
higherOrLower=sc.nextLine();
if(higherOrLower.equalsIgnoreCase("none")) {
break;
}
}
}
public static int getValue(String i,int j){
if(i.equalsIgnoreCase("lower")) {
j--;
return j;
} else if(i.equalsIgnoreCase("higher")) {
j++;
return j;
} else {
return j;
}
}
好的,让我们在这里详细介绍一下...
好的单元测试的基础是好的代码。这就解释了为什么编写单元测试不仅可以使代码工作更可靠,还可以使编码人员编写更好的代码(因为糟糕的代码通常很难测试)。
在您的示例中,您有两种方法(我假设您还没有深入了解面向对象编程 (OOP) 的细节,所以我不会讨论如何使用额外的 类).
一种方法进行实际的数字运算(好的,一点点运算),另一种方法进行输入。不幸的是,您的输入法也是您的主要方法,因此您可以做得更好一些,因为主要方法不太适合测试。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // We'll ignore finer problems with scanners, etc. here
playGame(scanner);
}
public static void playGame(Scanner scanner) {
System.out.println("Guess the number of Apples Tom has");
Scanner sc= new Scanner(System.in);
int number=sc.nextInt();
System.out.println("Tom, is it higher or lower?");
String higherOrLower=sc.nextLine();
while(true){
number= getValue(higherOrLower,number);
System.out.println("Tom, is it higher or lower?");
higherOrLower=sc.nextLine();
if(higherOrLower.equalsIgnoreCase("none")) {
break;
}
}
}
这一小改动将使您的代码更易于测试。让我们从简单的部分开始,即 getValue
方法:
@测试
public无效lower_should_return_number_minus_1(){
int result = getValue("lower", 10);
Assert.assertEquals(9, 结果); // 简单断言
}
@Test
public void higher_should_return_number_plus_1() {
int result = getValue("higher", 10);
Assert.assertEquals(11, result); // simple assertions
}
@Test
public void garbage_should_return_same_number() {
int result = getValue("Hello, Polly!", 10);
Assert.assertEquals(10, result); // simple assertions
}
这将测试您的大部分可能性。如果您为字符串输入 null,最好也测试一下会发生什么,只是为了确定 ;-)
测试另一种方法会有点困难,因为它涉及一些小技巧...
@Test(timeout=1000)
public void game_should_work_on_input() {
final ByteArrayInputStream stream = new ByteArrayInputStream(String.format("5%nlower%nlower%nnone%n").getBytes());
final Scanner scanner = new Scanner(stream);
playGame(scanner);
}
这里我们简单地创建一个"fake"输入,它由“5”、"lower"、"lower"和"none"组成(老实说,5之间有一个空行和第一个较低的)。 String.format
将为每个 %n
添加正确的新行字符。如果您的测试成功,则意味着游戏已经进行到最后。如果没有,超时将发生在 1000 毫秒之前(这意味着您的游戏没有正确结束,这是应该的)。老实说,没有测试过,但我敢肯定,你可以从那里开始。 ;-)