软件测试工具——Junit单元测试

什么是单元测试

  • 定义:单元测试是对软件中的最小可测试单元(通常是一个函数或方法)进行的验证性测试,旨在确保其按预期工作。
  • 目的:通过测试单元代码来发现并修复错误,提高代码的可靠性和维护性。

“单元”的大小或范围,并没有一个明确的标准,“单元”可以是一个函数、方法、类、功能模块或者子系统。单元测试一般是有开发人员或测试人员来做。单元测试通常和白盒测试联系到一起,如果单从概念上来讲两者是有区别的,不过我们通常所说的“单元测试”和“白盒测试”都认为是和代码有关系的,单元测试和白盒测试就是对开发人员所编写的代码进行测试。

测试工具

为什么需要测试工具?

我们就可以通过运行main()方法来运行测试代码。 不过,使用main()方法测试有很多缺点:

  • 只能有一个main()方法,不能把测试代码分离。
  • 没有打印出测试结果和期望结果。
  • 很难编写一组通用的测试代码。

因此,我们需要一种测试框架,帮助我们编写测试。

常用的单元测试工具有哪些?

  • Java:JUnit、TestNG
  • Python:UintTest、pyTest

JUnit

介绍

JUnit是一个开源的Java语言的单元测试框架,专门针对Java设计,使用最广泛。JUnit是事实上的单元测试的标准框架,任何Java开发者都应当学习并使用JUnit编写单元测试。

使用JUnit编写单元测试的好处在于,我们可以非常简单地组织测试代码,并随时运行它们,JUnit就会给出成功的测试和失败的测试,还可以生成测试报告,不仅包含测试的成功率,还可以统计测试的代码覆盖率,即被测试的代码本身有多少经过了测试。对于高质量的代码来说,测试覆盖率应该在80%以上。

此外,几乎所有的IDE工具都集成了JUnit,这样我们就可以直接在IDE中编写并运行JUnit测试。JUnit目前最新版本是5。

JUnit 4和JUnit 5的主要区别

  • 架构:JUnit 4将所有内容捆绑到单个jar文件中。 Junit 5由3个子项目组成,即JUnit Platform,JUnit Jupiter和JUnit Vintage。
  • 注释:

  • JDK支持:Junit4需要Java5+版本 ,Junit5需要Java8+版本
  • 断言标准:

如何使用Junit

要使用JUnit,首先需要将JUnit库添加到您的项目中。可以通过以下两种方式之一进行安装

    • 下载JUnit的JAR文件(通常是junit-platform-console-standalone.jar)。
    • 将下载的JAR文件添加到您的项目中的类路径中。
  • 方法二:使用构建工具(如Maven或Gradle)
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>RELEASE</version>
    <scope>test</scope>
</dependency>

 一旦您的项目配置好了JUnit,就可以开始编写测试用例了。JUnit使用注解来标识测试方法,以下是一个简单的示例:

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

public class MyMathTest {

    @Test
    public void testAdd() {
        MyMath math = new MyMath();
        int result = math.add(2, 3);
        assertEquals(5, result);
    }
}

常用的注解

  • @Test:用于标识测试方法。JUnit将执行所有带有@Test注解的方法,并报告测试结果。
  • @Before 和 @After:用于在测试方法之前和之后执行一些设置或清理工作。这对于准备测试环境和资源的初始化非常有用。
  • @BeforeEach 和 @AfterEach:与@Before和@After类似,但它们在每个测试方法之前和之后执行,而不是在测试类级别执行。
  • @BeforeAll 和 @AfterAll:@BeforeAll和@AfterAll注解用于在测试类中的所有测试方法之前和之后执行一次。通常用于执行全局初始化和清理工作。取代了JUnit 4的@BeforeClass
  • @Disabled:用于禁用测试方法。被标记为@Disabled的测试方法不会被执行。与JUnit 4的@Ignore类似。

其他注解

除了上面介绍的常用JUnit注解之外,JUnit 5还提供了一些其他有用的注解,可以用于测试和测试方法的各种配置和控制。

  • @Timeout注解用于指定测试方法的超时时间。如果测试方法执行时间超过指定的超时时间,测试将被标记为失败。
  • @RepeatedTest注解用于重复运行相同的测试方法多次。
  • @Tag注解用于为测试类或测试方法添加标签。标签可以用于组织和筛选测试,例如只运行特定标签的测试。
  • @DisplayName注解用于为测试类或测试方法指定自定义的显示名称,用于更清晰地描述测试的目的。
  • @ExtendWith注解用于指定扩展,扩展是JUnit 5中的插件机制,可以扩展测试框架的功能。常见的扩展包括参数解析、条件测试、测试拦截等。

常用断言

断言(Assertion)是测试代码中用于验证某个条件是否为真或某个结果是否符合预期的机制。在单元测试中,断言用于确保代码按预期运行,如果断言失败,测试将报告错误并指出问题所在。

JUnit 5 常断言

  • assertEquals(expected, actual):检查 expectedactual 是否相等。如果不相等,测试失败。

     

    assertEquals(5, calculator.add(2, 3));

  • assertNotEquals(expected, actual):检查 expectedactual 是否不相等。如果相等,测试失败。

     

    assertNotEquals(4, calculator.add(2, 3));

  • assertTrue(condition):检查 condition 是否为 true。如果为 false,测试失败。

     

    assertTrue(calculator.isPositive(5));

  • assertFalse(condition):检查 condition 是否为 false。如果为 true,测试失败。

     

    assertFalse(calculator.isNegative(5));

  • assertNull(object):检查 object 是否为 null。如果不是 null,测试失败。

     

    assertNull(calculator.getResult());

  • assertNotNull(object):检查 object 是否不为 null。如果为 null,测试失败。

     

    assertNotNull(calculator.getResult());

  • assertArrayEquals(expectedArray, actualArray):检查 expectedArrayactualArray 是否相等。如果不相等,测试失败。

     

    assertArrayEquals(new int[]{1, 2, 3}, calculator.getArray());

  • assertThrows(expectedType, executable):检查 executable 执行时是否抛出 expectedType 类型的异常。如果没有抛出或抛出不同类型的异常,测试失败。

     

    assertThrows(IllegalArgumentException.class, () -> calculator.divide(1, 0));

参数化测试

参数化测试(Parameterized Testing)是一种测试方法,它允许你用不同的输入值来执行相同的测试逻辑,以验证代码在不同输入条件下的行为。这样可以减少代码重复,增加测试覆盖面。

  • JUnit 4 使用@RunWith(Parameterized.class) 来实现参数化测试。
  • JUnit 5 使用 @ParameterizedTest 和不同的数据源注解(如 @ValueSource、@CsvSource、@MethodSource)来实现参数化测试。
@RunWith(Parameterized.class)

public class CalculatorTest {

    private int a; // 第一个数字
    private int b; // 第二个数字
    private int expectedSum; // 预期的结果

    // 构造函数,用于传入测试参数
    public CalculatorTest(int a, int b, int expectedSum) {
        this.a = a;
        this.b = b;
        this.expectedSum = expectedSum;
    }

    // 提供测试数据
    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
            {1, 1, 2},
            {2, 3, 5},
            {3, 5, 8},
            {4, 7, 11}
        });
    }

    // 测试方法
    @Test
    public void testAdd() {
        Calculator calculator = new Calculator();
        assertEquals(expectedSum, calculator.add(a, b)); // 验证计算结果是否正确
    }

}

@ParameterizedTest

@CsvSource({
    "1, 1, 2",
    "2, 3, 5",
    "3, 5, 8",
    "4, 7, 11"

})

public void testAdd(int a, int b, int expectedSum) {
    Calculator calculator = new Calculator();
    assertEquals(expectedSum, calculator.add(a, b)); // 验证计算结果是否正确

}

两个重点

  • 声明参数化测试
  • 声明参数化测试数据源

测试套件

概念

测试套件(Test Suite)是一个组织和管理测试用例的集合。它将多个测试用例组合在一起,以便一次性执行和管理。这是一种方便的方式来组织和运行测试,特别是在面对大量测试用例时。

优点或者作用

  • 集中管理:通过将相关的测试用例组织到一个测试套件中,可以方便地集中管理这些测试用例。这使得测试的维护和更新变得更为高效。
  • 统一执行:测试套件允许你一次性执行一组相关的测试用例,而不是逐个运行。这对于验证某个特定功能模块的完整性特别有用。
  • 提高效率:通过将测试用例分组到测试套件中,可以减少运行测试的时间。测试套件可以在不同的阶段(如开发、集成或回归测试)中重复使用。
  • 组织结构清晰:测试套件可以帮助建立清晰的测试结构,使得测试结果更容易理解和分析。它可以根据功能模块、测试类型等进行组织。
  • 支持回归测试:在软件开发过程中,测试套件可以用于回归测试,确保新代码的引入不会破坏现有功能

Junit4和5中如何创建测试套件
 

//Juint4
@RunWith(Suite.class)
@Suite.SuiteClasses({
    TestClass1.class,
    TestClass2.class
})
public class TestSuite {
    // 这个类没有代码,作为测试套件的标识
}

//Juint4
@Suite
@SelectClasses({
    TestClass1.class,
    TestClass2.class
})
public class TestSuite {
    // 这个类没有代码,作为测试套件的标识
}

 

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值