po3a  

实验项目名称:实验         

一、 实验目的

1、掌握单元测试的基本理论和作用。

2、掌握典型单元测试工具 JUnit 的使用。

 

二、 实验内容

实验任务 1

请按以下操作步骤完成一个基本的 JUnit 测试实例。

以下是在IntelliJ IDEA环境下使用JUnitCalculator类进行单元测试的详细步骤:

步骤1:创建Java项目

1. 打开IntelliJ IDEA → 新建项目 选择"Java" → 设置项目名称和路径 创建

 步骤2:创建Calculator

public class Calculator {

    // 加法

    public int add(int a, int b) {

        return a + b;

    }

    // 减法

    public int subtract(int a, int b) {

        return a - b;

    }

    // 乘法

    public int multiply(int a, int b) {

        return a * b;

    }

    // 除法

    public double divide(int a, int b) {

        if(b == 0) throw new ArithmeticException("Cannot divide by zero");

        return (double) a / b;

    }

}

步骤3:添加JUnit依赖

  1. 右键项目 → Open Module Settings
  2. 选择"Libraries" → "+" → From Maven

 

  1. 输入org.junit.jupiter:junit-jupiter-api:5.8.2 → 确定

 

4. 重复添加:

   - org.junit.jupiter:junit-jupiter-engine:5.8.2

   - org.junit.jupiter:junit-jupiter-params:5.8.2

 步骤4:创建测试类

1. src/test/java目录右键 → New → Java Class → 命名为CalculatorTest

2. 添加测试类注解:

import org.junit.jupiter.api.BeforeEach;

import org.junit.jupiter.api.Test;

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

 

class CalculatorTest {

    private Calculator calculator;

 

    @BeforeEach

    void setUp() {

        calculator = new Calculator();

    }

 

    @Test

    void testAdd() {

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

        assertEquals(-1, calculator.add(2, -3));

    }

 

    @Test

    void testSubtract() {

        assertEquals(1, calculator.subtract(4, 3));

        assertEquals(7, calculator.subtract(10, 3));

    }

 

    @Test

    void testMultiply() {

        assertEquals(6, calculator.multiply(2, 3));

        assertEquals(-6, calculator.multiply(2, -3));

    }

 

    @Test

    void testDivide() {

        assertEquals(2.0, calculator.divide(6, 3));

        assertEquals(3.333, calculator.divide(10, 3), 0.001);

    }

 

    @Test

    void testDivideByZero() {

        assertThrows(ArithmeticException.class, () -> calculator.divide(5, 0));

    }

}

 

步骤5:运行测试

1. 点击测试类左侧的绿色箭头图标 ▶️

2. 选择"Run 'CalculatorTest'"

3. 查看结果:

   - 绿色进度条:所有测试通过

   - 红色进度条:存在失败的测试

 

 步骤6:查看测试覆盖率(可选)

1. 右键测试类 → Run 'CalculatorTest' with Coverage

2. 查看覆盖率报告,确认是否覆盖所有代码分支

 

以下是使用JUnit 5进行参数化测试的详细操作步骤:

步骤1:创建参数化测试方法

在CalculatorTest类中添加以下代码:

java

import org.junit.jupiter.params.ParameterizedTest;

import org.junit.jupiter.params.provider.CsvSource;

import org.junit.jupiter.params.provider.ValueSource;

 

class CalculatorTest {

    // ... 其他已有代码 ...

    // 参数化加法测试(使用CSV数据)

    @ParameterizedTest(name = "[{index}] {0} + {1} = {2}") // 定义测试名称模板

    @CsvSource({

        "2, 3, 5",      // 正常情况

        "-5, 5, 0",     // 负数加法

        "0, 0, 0",      // 零值测试

        "2147483647, 1, -2147483648" // 整数溢出边界

    })

    void parameterizedAddTest(int a, int b, int expected) {

        assertEquals(expected, calculator.add(a, b));

    }

    // 参数化除法测试(使用CSV带浮点)

    @ParameterizedTest

    @CsvSource({

        "6, 3, 2.0",

        "10, 3, 3.333",

        "1, 2, 0.5"

    })

    void parameterizedDivideTest(int a, int b, double expected) {

        assertEquals(expected, calculator.divide(a, b), 0.001);

    }

    // 参数化异常测试(使用ValueSource

    @ParameterizedTest

    @ValueSource(ints = {0, -0, 100}) // 测试多个除数为零的情况

    void parameterizedDivideByZeroTest(int divisor) {

        assertThrows(ArithmeticException.class, () -> calculator.divide(10, divisor));

    }

}

 

步骤3:数据源类型详解

1. @CsvSource

- 使用CSV格式直接嵌入测试数据

- 适用场景:需要多参数组合的测试

- 语法示例:

  java

  @CsvSource({

      "参数1a, 参数2a, 预期结果a",

      "参数1b, 参数2b, 预期结果b"

  })

  

2. @ValueSource

- 提供单个参数的简单值

- 适用场景:单一参数测试

- 支持类型:基本类型、StringClass

  java

  @ValueSource(ints = {1, 2, 3})

 

3. @MethodSource

- 通过方法提供复杂参数

- 在测试类中添加静态方法:

  java

  static Stream<Arguments> provideMultiplyData() {

      return Stream.of(

          Arguments.of(2, 3, 6),

          Arguments.of(-4, 5, -20),

          Arguments.of(0, 100, 0)

      );

  }

  @ParameterizedTest

  @MethodSource("provideMultiplyData")

  void parameterizedMultiplyTest(int a, int b, int expected) {

      assertEquals(expected, calculator.multiply(a, b));

  }

  

步骤4:运行参数化测试

1. 在测试类中:

   - 点击类名旁的绿色箭头 ▶️ 运行所有测试

   - 点击单个参数化测试方法旁的箭头 运行单个测试

2. 查看结果时:

   - 每个参数组合会显示为独立测试项

   - 测试名称会显示参数值(通过name属性自定义)

 

步骤5:验证测试报告

执行后会显示详细结果:

✓ parameterizedAddTest(int, int, int)[1] 2 + 3 = 5

✓ parameterizedAddTest(int, int, int)[2] -5 + 5 = 0

✓ parameterizedAddTest(int, int, int)[3] 0 + 0 = 0

✓ parameterizedAddTest(int, int, int)[4] 2147483647 + 1 = -2147483648

 

 

参数化测试注意事项

1. 浮点数精度处理:

   java

   assertEquals(3.333, calculator.divide(10, 3), 0.001); // 第三个参数是允许的误差范围

2. 异常测试特殊处理:

   java

   @CsvSource({"5, 0", "10, 0"})

   void testDivideByZero(int a, int b) {

       assertThrows(ArithmeticException.class, () -> calculator.divide(a, b));

   }

 

 

 

 

实验任务 2 编写程序判断闰年,设计测试⽤例并⽤Junit⾏测

import org.junit.jupiter.api.Test;

 

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

 

public class runnian {

 

    // 判断是否为闰年的方法

    public static boolean isLeapYear(int year) {

        if (year % 400 == 0) {

            return true;

        } else if (year % 100 == 0) {

            return false;

        } else return year % 4 == 0;

    }

 

    // 测试能被 400 整除的年份是闰年

    @Test

    public void testDivisibleBy400() {

        assertTrue(isLeapYear(2000));

    }

 

    // 测试能被 100 整除但不能被 400 整除的年份不是闰年

    @Test

    public void testDivisibleBy100ButNotBy400() {

        assertFalse(isLeapYear(2100));

    }

 

    // 测试能被 4 整除但不能被 100 整除的年份是闰年

    @Test

    public void testDivisibleBy4ButNotBy100() {

        assertTrue(isLeapYear(2020));

    }

 

    // 测试不能被 4 整除的年份不是闰年

    @Test

    public void testNotDivisibleBy4() {

        assertFalse(isLeapYear(2021));

    }

 

}

这里我进行了 4 个测试用例来覆盖不同的年份情况,最终都通过。

 

 

 

实验任务3编写程序判断非三角形等腰三角形等边三角形,直角三角形,钝角三角形,锐角三角形,设计测试用例并用JUnit进行测试

//TriangleJudgment.java

package org.example.test4;

 

public class TriangleJudgment {

 

    public static String judgeTriangle(double a, double b, double c) {

        // 检查是否能构成三角形

        if (a + b <= c || a + c <= b || b + c <= a || a <= 0 || b <= 0 || c <= 0) {

            return "非三角形";

        }

        // 检查是否为等边三角形

        if (a == b && b == c) {

            return "等边三角形";

        }

        // 检查是否为等腰三角形

        if (a == b || a == c || b == c) {

            return "等腰三角形";

        }

        // 检查是否为直角三角形

        double[] sides = {a, b, c};

        java.util.Arrays.sort(sides);

        if (Math.abs(sides[0] * sides[0] + sides[1] * sides[1] - sides[2] * sides[2]) < 1e-9) {

            return "直角三角形";

        }

        // 检查是否为钝角三角形

        if (sides[0] * sides[0] + sides[1] * sides[1] < sides[2] * sides[2]) {

            return "钝角三角形";

        }

        // 剩下的情况为锐角三角形

        return "锐角三角形";

    }

}

 

 

//TriangleJudgmentTest.java

import org.example.test4.TriangleJudgment;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class TriangleJudgmentTest {

    @Test
    public void testNonTriangle() {
        assertEquals("非三角形", TriangleJudgment.judgeTriangle(1, 2, 4));
    }

    @Test
    public void testEquilateralTriangle() {
        assertEquals("等边三角形", TriangleJudgment.judgeTriangle(3, 3, 3));
    }

    @Test
    public void testIsoscelesTriangle() {
        assertEquals("等腰三角形", TriangleJudgment.judgeTriangle(3, 3, 4));
    }

    @Test
    public void testRightTriangle() {
        assertEquals("直角三角形", TriangleJudgment.judgeTriangle(3, 4, 5));
    }

    @Test
    public void testObtuseTriangle() {
        assertEquals("钝角三角形", TriangleJudgment.judgeTriangle(2, 3, 4));
    }

    @Test
    public void testAcuteTriangle() {
        assertEquals("锐角三角形", TriangleJudgment.judgeTriangle(4, 5, 6));
    }
}

包含 6 个测试用例,分别针对非三角形、等边三角形、等腰三角形、直角三角形、钝角三角形和锐角三角形进行测试。

 

 

 

 

 

 

三、 实验总结

  JUnit 框架的使用让我体会到单元测试对程序质量保障的重要性。通过精心设计的测试用例,从不同角度对程序功能进行验证,能够快速定位和修正程序中的逻辑错误,确保程序在各种输入情况下都能稳定运行。这让我明白,完整的软件开发过程中,测试与开发同等重要,良好的测试习惯有助于提高代码的可靠性和可维护性。

posted on 2025-04-29 09:24  po3a  阅读(10)  评论(0)    收藏  举报