如何编写单元测试?

我有一个 Java 类。我怎样才能 单元测试它?


在我的例子中,我让类做一个二进制求和。它接受两个 byte[]数组,对它们求和,并返回一个新的二进制数组。

381998 次浏览
  1. 定义正常情况下的预期和期望输出,并提供正确的输入。

  2. 现在,通过声明一个类来实现测试,将它命名为任何东西(通常是类似 TestAddingModule 的东西) ,并将 testAdd 方法添加到它中(例如下面的方法) :

    • 编写一个方法,在它上面添加@Test 注释。
    • 在该方法中,运行二进制和和和 assertEquals(expectedVal,calculatedVal)
    • 通过运行方法来测试您的方法(在 Eclipse 中,右击,选择 Run as → JUnit Test)。

      //for normal addition
      @Test
      public void testAdd1Plus1()
      {
      int x  = 1 ; int y = 1;
      assertEquals(2, myClass.add(x,y));
      }
      
  3. Add other cases as desired.

    • Test that your binary sum does not throw a unexpected exception if there is an integer overflow.
    • Test that your method handles Null inputs gracefully (example below).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1()
      {
      int y = 1;
      assertEquals(0, myClass.add(null,y));
      }
      

这是一个非常普遍的问题,有很多方法可以回答。

如果你想使用 JUnit 来创建测试,你需要创建你的 testcase 类,然后创建单独的测试方法来测试你的类/模块在测试中的特定功能(单个的 testcase 类通常与被测试的单个“生产”类相关联) ,在这些方法中执行各种操作,并将结果与正确的结果进行比较。特别重要的是尽可能多地尝试和覆盖角落案例。

例如,在您的具体示例中,您可以测试以下内容:

  1. 两个正数之间的简单加法。将它们相加,然后验证结果是否符合预期。
  2. 正数和负数之间的加法(它返回带有第一个参数符号的结果)。
  3. 正数和负数之间的加法(它返回带有第二个参数符号的结果)。
  4. 两个负数之间的加法。
  5. 导致溢出的附加项。

要验证结果,可以使用 org.junit 中的各种 assertXXX 方法。断言类(为方便起见,您可以做‘ import static org.junit。坚持。*').这些方法测试特定的条件,如果测试不进行验证(可以选择使用特定的消息) ,则测试失败。

在您的案例中的示例 testcase 类(没有定义方法内容) :

import static org.junit.Assert.*;


public class AdditionTests {
@Test
public void testSimpleAddition() { ... }




@Test
public void testPositiveNegativeAddition() { ... }




@Test
public void testNegativePositiveAddition() { ... }




@Test
public void testNegativeAddition() { ... }




@Test
public void testOverflow() { ... }
}

如果你不习惯编写单元测试,而是通过编写特别的测试来测试你的代码,然后“可视化地”验证(例如,你编写一个简单的 main 方法,接受使用键盘输入的参数,然后打印出结果——然后你继续输入值并验证结果是否正确) ,那么你可以开始用上面的格式编写这样的测试,并用正确的 assertXXX 方法验证结果,而不是手动进行。通过这种方式,您可以更轻松地重新运行测试,而不必进行手动测试。

就像@CoolBeans 提到的,看看 JUnit。这里有一个简短的 教程,可以帮助您开始使用 jUnit4。X

最后,如果你真的想了解更多关于测试和测试驱动开发(tDD)的知识,我建议你看看 Kent Beck 的下面这本书:。

我为 情报日食都提供了这篇文章。

日食:

要为您的项目进行单元测试,请遵循以下步骤(我使用 Eclipse 来编写此测试) :

1-点击 New-> Java Project。

Create Project

写下你的项目名称,点击完成。

Create Project

右键单击项目,然后单击 New-> Class。

Create Class

写下你的班名,点击完成。

Create Class

然后,像这样完成课程:

public class Math {
int a, b;
Math(int a, int b) {
this.a = a;
this.b = b;
}
public int add() {
return a + b;
}
}

5-点击文件-> 新建-> JUnit 测试用例。

Create JUnite Test

选中 setUp ()并单击 Finish。 SetUp ()将是您初始化测试的位置。

Check SetUp()

点击确定。

Add JUnit

这里,我简单地加上7和10。所以,我希望答案是17。像这样完成你的测试课程:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
Math math;
@Before
public void setUp() throws Exception {
math = new Math(7, 10);
}
@Test
public void testAdd() {
Assert.assertEquals(17, math.add());
}
}

9-写单击您的测试类在包资源管理器中,然后单击 Run as-> JUnit Test。

Run JUnit Test

这是测试的结果。

Result of The Test

情报: 注意,我在截图中使用了 IntelliJ IDEA 社区2020.1。另外,在执行这些步骤之前,您需要设置 jre。我使用的是 JDK 11.0.4。

1-右键单击项目的主文件夹-> new-> 目录。 enter image description here 右键单击测试文件夹并创建正确的包。我建议创建与原始类相同的包名称。然后,右键单击 test 目录-> 将目录标记为-> test source root。 enter image description here 3-在 test 目录的右边包中,您需要创建一个 Java 类(我建议使用 Test.Java)。 enter image description here 在创建的类中,输入“@Test”,然后,在 IntelliJ 提供的选项中,选择 Add‘ JUnitx’to classspath。 enter image description here enter image description here 5-在测试类中编写测试方法。方法签名如下:

@Test
public void test<name of original method>(){
...
}

你可以这样断言:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

这些是我添加的进口商品:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

enter image description here

这是我写的测试: enter image description here

你可以检查你的方法如下:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

要运行单元测试,右键单击测试,然后单击 Run。 enter image description here

如果你的测试通过,结果如下: enter image description here

希望能有所帮助。

其他答案向您展示了如何使用 JUnit 设置测试类。JUnit 不是唯一的 Java 测试框架。然而,专注于使用框架的技术细节会偏离应该指导您行动的最重要的概念,因此我将讨论这些概念。

  • 测试(针对所有类型的事物)比较某些事物(被测系统,SUT)的 真的行为和它的 意料之中行为。

  • 自动化测试可以用计算机程序来完成。因为这种比较是由一个不灵活和不智能的计算机程序完成的,所以预期的行为必须精确和明确地知道。

  • 程序或程序的一部分(类或方法)应该做的是它的 规格。因此,测试软件要求您具有 SUT 的规范。这可能是一个显式的描述,或者是您头脑中对于所期望的内容的隐式规范。

  • 因此,自动化单元测试需要对您正在测试的类或方法进行精确和明确的规范。

  • 但是在开始编写代码时,您需要该规范。因此,测试的一部分实际上在您编写 SUT 的哪怕一行之前就已经开始了。测试驱动开发(Test Driven Development,TDD)的测试技术将这种想法发挥到了极致,并且在编写要测试的代码之前,您必须先创建单元测试代码。

  • 单元测试框架使用 断言测试 SUT。断言是一个逻辑表达式(具有 boolean结果类型的表达式; 断言) ,如果 SUT 运行正确,则该表达式必须是 true。因此,规范必须以断言的形式表示(或重新表示)。

  • 将规范表示为断言的一种有用技术是 合同设计。这些规范是根据 后置条件编写的。后置条件是关于从方法或构造函数返回后 SUT 的公开可见状态的断言。有些方法有后置条件 是 不变量,它们是在方法执行之前和之后为 true 的谓词。也可以说 同学们具有不变量,这些不变量是类的每个构造函数和方法的后置条件,因此 一直都是应该为 true。后置条件(和不变量)仅用公开可见状态来表示: publicprotected字段,由 publicprotected方法返回的值(例如 getter) ,以及通过引用传递给方法的对象的公开可见状态。


许多初学者在这里发布问题,询问他们如何能够测试一些代码,展示代码,但没有说明该代码的规范。正如这次讨论所表明的那样,任何人不可能对这样的问题给出一个好的答案,因为最好的情况下,潜在的答案必须是 猜猜看规范,而且这样做可能是不正确的。这个问题的 Asker显然不理解规范的重要性,因此是一个新手,需要理解我在这里描述的 之前试图编写一些测试代码的基本原理。