1

我是单元测试的新手,因此想做一些实践练习来熟悉 jUnit 框架。

我创建了一个实现字符串乘法器的程序

public String multiply(String number1, String number2)

为了测试乘法器方法,我创建了一个包含以下测试用例的测试套件(以及所有需要的整数解析等)

public class MultiplierTest {
    @Test
    public void testMultiply() {
      Multiplier multiplier = new Multiplier();
      // Test for 2 positive integers
      assertEquals("Result", 5, multiplier.multiply("5", "1"));

      // Test for 1 positive integer and 0
      assertEquals("Result", 0, multiplier.multiply("5", "0"));

      // Test for 1 positive and 1 negative integer
      assertEquals("Result", -1, multiplier.multiply("-1", "1"));

      // Test for 2 negative integers
      assertEquals("Result", 10, multiplier.multiply("-5", "-2"));

      // Test for 1 positive integer and 1 non number
      assertEquals("Result", , multiplier.multiply("x", "1"));

      // Test for 1 positive integer and 1 empty field
      assertEquals("Result", , multiplier.multiply("5", ""));

      // Test for 2 empty fields
      assertEquals("Result", , multiplier.multiply("", ""));
    } 
}

以类似的方式,我可以创建涉及边界情况(考虑数字是 int 值)甚至虚值的测试用例。

1) 但是,上面最后 3 个测试用例的预期值应该是多少?(表示错误的特殊数字?)

2)我错过了哪些额外的测试用例?

3) assertEquals() 方法是否足以测试乘法器方法,或者我是否需要其他方法,如 assertTrue()、assertFalse()、assertSame() 等

4)这是开发测试用例的正确方法吗?我如何“确切地”从这个练习中受益?

5)测试乘数法的理想方法应该是什么?

我在这里很无知。如果有人可以帮助回答这些问题,我将不胜感激。谢谢你。

4

4 回答 4

4

首先,您的代码有误,因为您有一个类但没有函数。我假设所有这些测试都在一个功能中?如果是这样,我建议不要这样做。通常,您希望通过一项测试来测试一件事,因此:

public class MultiplierTests {
  @Test
  public void testSimpleMultiple() {
    assertEquals(...);
  }

  ...
}

其次,你在这里传递一个 int 作为结果:

assertEquals("Result", 5, multiplier.multiply("5", "1"));

Multiplier.multiply()返回一个String

所以你如何测试这个取决于结果是什么。如果传入一个空字符串,它会抛出异常吗?如果是这样,您可以定义您的@Test注释以说它期望抛出异常:

@Test(expected = IllegalArgumentException.class)
public void test() {
  multiplier.multiply("", "5");
}
于 2010-04-24T01:48:03.497 回答
3

1) 但是,上面最后 3 个测试用例的预期值应该是多少?(表示错误的特殊数字?)

正如其他回答者所解释的,这取决于乘数的接口合同。您应该考虑您(或其客户,一般来说)应该如何使用它,在特定错误或极端情况下应该发生什么,等等。在 Java 中,约定是在这种情况下抛出异常。

2)我错过了哪些额外的测试用例?

我想到了几个案例:

// test commutativity
assertEquals("0", multiplier.multiply("0", "5"));
assertEquals("-1", multiplier.multiply("1", "-1"));
assertEquals("149645", multiplier.multiply("173", "865"));
assertEquals("149645", multiplier.multiply("865", "173"));

// test some more unusual cases of multiplying with 0
assertEquals("0", multiplier.multiply("-5", "0"));
assertEquals("0", multiplier.multiply("0", "-0"));
// test with numbers starting with '+'
assertEquals("368", multiplier.multiply("+23", "+16"));
assertEquals("-368", multiplier.multiply("-23", "+16"));

// test multiplying huge values without overflow
assertEquals("18446744073709551616", multiplier.multiply("4294967296", "4294967296"));
assertEquals("18446744073709551616", multiplier.multiply("-4294967296", "-4294967296"));

3) assertEquals() 方法是否足以测试乘法器方法,或者我是否需要其他方法,如 assertTrue()、assertFalse()、assertSame() 等

在这种情况下,您只需要比较两个值是否相等。在其他测试中,您可能需要不同类型的断言。

4)这是开发测试用例的正确方法吗?我如何“确切地”从这个练习中受益?

单元测试没有单一的“正确”方法。最接近的可能是测试驱动开发,如果您从头开始编写代码,许多人(包括我自己)都会推荐这种方法。

您从这个练习中得到的好处可能是您熟悉了 JUnit 并尝试了一段时间的“测试员帽子”。

5)测试乘数法的理想方法应该是什么?

这个问题与上一个问题有何不同?

于 2010-04-24T22:35:31.200 回答
2

您应该考虑使用 @Expected 注释添加测试用例来验证您的异常是否正常工作。基本上,编写一个您知道应该生成异常的案例,然后查看测试是否通过。

确定您是否遗漏了复杂方法中的任何案例的一个好方法是通过代码覆盖工具运行它们。运行所有测试,然后查看代码覆盖率结果。如果您的测试用例没有访问您的代码的某些部分,那么您可能会遗漏一些。

你可以在这里找到一个很好的指南。

于 2010-04-24T01:49:34.337 回答
1

如果您真的在测试边缘条件,并且您期望数字的字符串表示,也许您可​​以测试将字符串传递给被测函数方法

@Test(expected= NumberFormatException.class)
public void test() {
   multiplier.multiply("a", "b");
}

我不同意 cletus 关于他的实现,因为他的测试用例需要一个包罗万象的 IllegalArgumentException,我认为测试特定的子类比使用父异常更好。

于 2010-04-24T02:00:33.133 回答