06-19 Junit5测试框架实战(一)

课堂PPT

PPT地址

Junit5学习路线

JUnit学习路线.xmind.zip (141.3 KB)

测试用例设计

计算器测试用例.xlsx (22.5 KB)

mirror加载

    <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>*</mirrorOf>
      <name>阿里云公共仓库</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
    <mirror>
      <id>CN</id>
      <name>Aliyun Nexus</name>
      <url>https://maven.aliyun.com/nexus/content/groups/public</url>
      <mirrorOf>*</mirrorOf>
    </mirror>

pom依赖

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>11</java.version>
        <!-- 使用 Java 11 语言特性 ( -source 11 ) 并且还希望编译后的类与 JVM 11 ( -target 11 )兼容,您可以添加以下两个属性,它们是默认属性插件参数的名称-->
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <!-- 对应junit Jupiter的版本号;放在这里就不需要在每个依赖里面写版本号,导致对应版本号会冲突-->
        <junit.jupiter.version>5.8.2</junit.jupiter.version>
        <!-- plugins -->
        <maven.compiler.version>3.8.1</maven.compiler.version>
        <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
        <poi.version>5.2.2</poi.version>
        <!-- 断言-->
        <hamcrest.version>2.2</hamcrest.version>
        <slf4j.version>2.0.0-alpha7</slf4j.version>
        <logback.version>1.3.0-alpha16</logback.version>
    </properties>

    <!--    物料清单 (BOM)-->
    <dependencyManagement>
        <dependencies>
            <!--当使用 Gradle 或 Maven 引用多个 JUnit 工件时,此物料清单 POM 可用于简化依赖项管理。不再需要在添加依赖时设置版本-->
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>${junit.jupiter.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>



    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <!--            对应添加的依赖的作用范围-->
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest</artifactId>
            <version>${hamcrest.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>

                    <!--                    <includes>-->
                    <!--                        <include>top/testeru/group/*_Test.class</include>-->
                    <!--                    </includes>-->
                    <!--                    <excludes>-->
                    <!--                        <exclude>com/testeru/suites/cases2/*Test.class</exclude>-->
                    <!--                        <exclude>*Suite*Test</exclude>-->
                    <!--                    </excludes>-->
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>${junit.jupiter.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                        <version>${junit.jupiter.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                
                    <!-- 设置jre版本为 11 -->
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <!-- 设置编码为 UTF-8 -->
                    <encoding>${maven.compiler.encoding}</encoding>
                </configuration>
            </plugin>

        </plugins>
    </build>

日志 logback.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- name指定<appender>的名称    class指定<appender>的全限定名  ConsoleAppender的作用是将日志输出到控制台-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--   写入的文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建     -->
<!--        <file>123.log</file>-->
<!--  append 为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
<!--        <append>true</append>-->
<!--        encoder表示对输出格式进行格式化  FileAppender的作用是将日志写到文件中-->
        <encoder>
<!--            输出时间格式-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36}.%M\(%line\) -- %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.ceshiren" level="DEBUG" />
    <logger name="com" level="WARN" />
    <logger name="ceshiren" level="WARN" />
    <logger name="org" level="WARN" />

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>

</configuration>

业务代码


import org.slf4j.Logger;


import java.util.Arrays;
import java.util.UUID;
import java.util.stream.IntStream;

import static java.lang.invoke.MethodHandles.lookup;
import static org.slf4j.LoggerFactory.getLogger;
public class Calculator {
    //获得具有所需名称的记录器
    static final Logger logger = getLogger(lookup().lookupClass());

    public static int result = 0;

    //用例名
    String name;
    //唯一ID标识
    String id;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Calculator(String name) {
        this.name = name;
        logger.info("创建 {} ", name);
    }


    public void initId(){
        id = UUID.randomUUID().toString();
        logger.info("生成ID:{} 并绑定", id);

    }
    public void destroyId() {
        if (id == null) {
            throw new IllegalArgumentException(name + " 没有初始化对应ID");
        }
        logger.info("ID: {} 释放", id);
        id = null;
    }


    public void close() {
        logger.info("关闭 {} ", name);
    }


    //连续添加
    public int sum(int... numbers) {
         if(Arrays.stream(numbers).anyMatch(u -> u == 100)){
            logger.warn("integer is 100!");
            throw new NumberFormatException("integer is 100!");
        }else if(Arrays.stream(numbers).anyMatch(u -> u > 99) | Arrays.stream(numbers).anyMatch(u -> u < -99)){
            logger.warn("请输入范围内的整数");
            throw new IllegalArgumentException("请输入范围内的整数!");

        }else {
            return IntStream.of(numbers).sum();
        }

    }


    //从100进行减法
    public int subtract(int... numbers) {
        if(Arrays.stream(numbers).allMatch(u -> u > 99) | Arrays.stream(numbers).allMatch(u -> u < -99)){
            logger.warn("请输入范围内的整数");
            throw new IllegalArgumentException("请输入范围内的整数!");
        }else {
            return IntStream.of(numbers).reduce(100, (a, b) -> a-b);
        }
    }

    public int subtract(int x,int y) {
        if(x>99 | x<-99 | y>99 | y<-99){
            logger.warn("请输入范围内的整数");
            return 0;
        }else {
            return x-y;

        }
    }


    //平均值 average
    public double average(int... numbers) {
        if(Arrays.stream(numbers).allMatch(u -> u > 99) | Arrays.stream(numbers).allMatch(u -> u < -99)){
            logger.warn("请输入范围内的整数");
            return 0;
        }else {
            return IntStream.of(numbers).average().getAsDouble();
        }
    }


    //连续拼接
    public String concatStr(String... words) {
        return String.join(" ", words);

    }

}

练习一

  • 根据需求编写对应的测试用例:加法,减法,string拼接
  • 第一步:打开计算器
  • 在每个测试方法之前生成运行的唯一ID标识
  • 在每个测试方法之前log打印:开始进行计算
  • 在测试方法得到结果后log打印:计算结果:result
  • 在每个测试方法之后进行销毁ID操作
  • 在调用完所有测试用例后执行关闭计算器app操作
  • 注意:warning:
    • 每个测试用例都要添加断言,验证结果
    • 灵活使用测试装置
    • 边界值要进行验证

注意:warning:

    1. @BeforeAll ,@AfterAll ,@AfterEach,@BeforeEach
      这四个注解部需要跟@Test注解放在一个方法上。
    1. @BeforeAll ,@AfterAll 只运行一次,使用static关键字修饰。
    1. @AfterEach,@BeforeEach 有几个测试方法「@Test注解修饰的方法」就运行几次。

课堂代码地址

maven 官网查找依赖版本号

https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin

课后调查表

https://jinshuju.net/f/uWTfSX

demo
package com.ceshiren;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.function.Executable;
import org.slf4j.Logger;

import static java.lang.invoke.MethodHandles.lookup;
import static org.junit.jupiter.api.Assertions.*;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * 练习一
 * 根据需求编写对应的测试用例:加法,减法,string拼接
 * 第一步:打开计算器
 * 在每个测试方法之前生成运行的唯一ID标识
 * 在每个测试方法之前log打印:开始进行计算
 * 在测试方法得到结果后log打印:计算结果:result
 * 在每个测试方法之后进行销毁ID操作
 * 在调用完所有测试用例后执行关闭计算器app操作
 * 注意:warning::
 * 每个测试用例都要添加断言,验证结果
 * 灵活使用测试装置
 * 边界值要进行验证
 */
class CalculatorTest {
    static final Logger logger = getLogger(lookup().lookupClass());
    static Calculator ca;

    @BeforeAll
    static void setup(){
        ca = new Calculator("新型计算器");
    }

    @BeforeEach
    void beforeEach(){
        ca.initId();
        logger.info("开始进行计算");
    }

    @AfterEach
    void afterEach(){
        ca.destroyId();
    }

    @AfterAll
    static void afterAll(){
        ca.close();
    }

    @Test
    void ca_add_001() {
        int result = ca.sum(1, 1);
        logger.info("计算结果:{}", result);
        Assertions.assertEquals(2, result);
    }

    @Test
    void ca_sub_016() {
//        int result = ca.subtract(100, -110, -200);
//        logger.info("计算结果:{}", result);

        assertThrows(IllegalArgumentException.class, ()->ca.subtract(100, -1, -110));
    }

    @Test
    void ca_concatStr_019() {
        String result = ca.concatStr("Hello", "Junit5");
        logger.info("计算结果:{}", result);
        Assertions.assertEquals("Hello Junit5", result);
    }
}

“”"
package com.hogwarts.junit5Basics.ceshiren;

import com.hogwarts.ceshiren.Calculator;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;

import static java.lang.invoke.MethodHandles.lookup;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.slf4j.LoggerFactory.getLogger;

public class CalculatorTest {
static final Logger logger = getLogger(lookup().lookupClass());

@Test
@DisplayName("整数相加")
void Ca_add_001(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(1, 1);
    logger.info("计算结果为:"+ result);
    assertEquals(2, result);

}

@Test
@DisplayName("三个整数相加")
void Ca_add_002(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(1, 1, 9);
    logger.info("计算结果为:"+ result);
    assertEquals(11, result);
}

@Test
@DisplayName("有效边界值相加,99+99")
void Ca_add_003(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(99, 99);
    logger.info("计算结果为:"+ result);
    assertEquals(198, result);
}

@Test
@DisplayName("有效边界值相加,-99+99")
void Ca_add_004(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(-99, 99);
    logger.info("计算结果为:"+ result);
    assertEquals(0, result);
}

@Test
@DisplayName("有效边界值相加,-99+(-99)")
void Ca_add_005(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(-99, -99);
    logger.info("计算结果为:"+ result);
    assertEquals(-198, result);
}

@Test
@DisplayName("无效边界值相加,100+0")
void Ca_add_006(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(100, 0);
}

@Test
@DisplayName("无效边界值相加,-100+(-1)")
void Ca_add_007(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(-100, -0);
}

@Test
@DisplayName("无效边界值相加,2+100")
void Ca_add_008(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(100, 2);
}

@Test
@DisplayName("无效边界值相加,1+(-100)")
void Ca_add_009(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.sum(1, -100);
}

@Test
@DisplayName("2个整数相减")
void Ca_add_010(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(10, 10);
    assertEquals(0, result);
}

@Test
@DisplayName("有效边界值相减 99-99")
void Ca_add_011(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(99, 99);
    assertEquals(0, result);
}

@Test
@DisplayName("有效边界值相减 -99-99")
void Ca_add_012(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(-99, 99);
    assertEquals(-198, result);
}

@Test
@DisplayName("有效边界值相减 99-(-99)")
void Ca_add_013(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(99, -99);
    assertEquals(198, result);
}

@Test
@DisplayName("有效边界值相减 -99-(-99)")
void Ca_add_014(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(-99, -99);
    assertEquals(0, result);
}

@Test
@DisplayName("无效边界值 100-0")
void Ca_add_015(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(100, 0);
}

@Test
@DisplayName("无效边界值 -100-(-1)")
void Ca_add_016(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(-100, -1);
}

@Test
@DisplayName("无效边界值 2-100")
void Ca_add_017(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(2, 100);
}

@Test
@DisplayName("无效边界值 1-(-100)")
void Ca_add_018(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    int result = calculator.subtract(1, -100);
}

@Test
@DisplayName("字符串拼接")
void Ca_add_019(){
    Calculator calculator = new Calculator("计算器");
    calculator.initId();
    logger.info("开始计算");
    String result = calculator.concatStr("Hello", "Junit5");
}

}

“”"


import org.junit.Test;
import org.slf4j.Logger;

import static java.lang.invoke.MethodHandles.lookup;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.slf4j.LoggerFactory.getLogger;

public class CalculatorTest {
    static final Logger logger = getLogger(lookup().lookupClass());
//    Calculator calculator = new Calculator("张三");
    @AfterAll
    static void af(){
        System.out.println("af()");
    }

    @BeforeAll
    static void bf(){
        System.out.println("be()");
    }

    @AfterEach
    void ae(){
        System.out.println("ae()");
    }

    @BeforeEach
    void be(){
        System.out.println("be()");
    }

    @Test
    public void sumTest() {
        Calculator calculator = new Calculator("张三");
        calculator.initId();
        logger.info("开始进行计算");
        int result = calculator.sum(1, 1);
        logger.info("计算结果:{}", result);
        assertEquals(2, result);
        calculator.destroyId();
        calculator.close();

    }
}
package com.ceshiren;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.slf4j.Logger;

import static java.lang.invoke.MethodHandles.lookup;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.slf4j.LoggerFactory.getLogger;

@DisplayName("计算器的加减,字符串拼接的功能测试")
public class CalculatorTest {

    public static Calculator calculator = null;

    //日志记录
    public static final Logger logger = getLogger(lookup().lookupClass());

    @BeforeAll
    public static void beforeAll(){
        calculator = new Calculator("计算器");
    }

    @AfterAll
    public static void afterAll(){
        calculator.close();
    }

    @BeforeEach
    public void beforeEach(){
       calculator.initId();
       logger.info("开始进行计算");
    }

    @AfterEach
    public void afterEach(){
        calculator.destroyId();
    }

    @ParameterizedTest
    @DisplayName("【正向】整数相加,结果计算正确")
    @CsvSource({"1,1,0,2","1,1,9,11"})
    public void Ca_add_001(Integer num1,Integer num2,Integer num3,Integer expectResult){
        int actualResult = calculator.sum(num1, num2, num3);
        logger.info("计算结果:{}",actualResult);
        assertEquals(expectResult,actualResult,"【正向】整数相加,结果计算错误");
    }

    @ParameterizedTest
    @DisplayName("【边界】有效边界值相加,结果计算正确")
    @CsvSource({"99,99,198","99,-99,0","-99,99,0","-99,-99,-198"})
    public void Ca_add_002(Integer num1,Integer num2,Integer expectResult){
        int actualResult = calculator.sum(num1, num2);
        logger.info("计算结果:{}",actualResult);
        assertEquals(expectResult,actualResult,"【边界】有效边界值相加,结果错误");
    }

    @ParameterizedTest
    @DisplayName("【边界】无效边界值相加,给出对应的错误提示")
    @CsvSource({"100,0,","-100,-1","2,100","1,-100"})
    public void Ca_add_003(Integer num1,Integer num2){
        assertThrows(IllegalArgumentException.class,() -> calculator.sum(num1, num2));
    }

    @ParameterizedTest
    @DisplayName("【正向】2个整数相减,结果计算正确")
    @CsvSource({"10,10,0"})
    public void Ca_subtract_001(Integer num1,Integer num2,Integer expectResult){
        int actualResult = calculator.subtract(num1, num2);
        logger.info("计算结果:{}",actualResult);
        assertEquals(expectResult,actualResult,"【正向】2个整数相减,结果计算错误");
    }

    @ParameterizedTest
    @DisplayName("【边界】有效边界值相减,结果计算正确")
    @CsvSource({"99,99,0","-99,99,-198","99,-99,198","-99,-99,0"})
    public void Ca_subtract_002(Integer num1,Integer num2,Integer expectResult){
        int actualResult = calculator.subtract(num1, num2);
        logger.info("计算结果:{}",actualResult);
        assertEquals(expectResult,actualResult,"【边界】有效边界值相减,结果计算错误");
    }

    @ParameterizedTest
    @DisplayName("【边界】无效边界值相减,给出提示信息")
    @CsvSource({"100,0,0","-100,-1,0","2,100,0","1,-100,0"})
    public void Ca_subtract_003(Integer num1,Integer num2,Integer expectResult){
            int actualResult = calculator.subtract(num1,num2);
            logger.info("计算结果:{}", actualResult);
            assertEquals(expectResult,actualResult,"【边界】无效边界值相减,结果计算错误");
    }


    @ParameterizedTest
    @DisplayName("【正向】字符串相拼接,结果拼接正确")
    @CsvSource({"Hello,World,Hello World","你好,世界,你好 世界"})
    public void Ca_concatStr_001(String str1,String str2,String expectResult){
        String actualResult = calculator.concatStr(str1,str2);
        logger.info("字符串拼接结果:{}", actualResult);
        assertEquals(expectResult,actualResult,"【边界】无效边界值相减,结果计算错误");
    }

}

package hogwarts;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.slf4j.Logger;

import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.slf4j.LoggerFactory.getLogger;

class CalculatorTest {
static final Logger logger = getLogger(CalculatorTest.class);
static Calculator c;

@BeforeAll
static void before() {
    c = new Calculator("计算机");
}
@BeforeEach
void open() {
    c.initId();
    logger.info("开始进行计算");
}

@ParameterizedTest
@MethodSource("numberProvider")
void add(NumberData numberData) {
    int result = c.sum(numberData.numbers);
    assertThat(result, equalTo(numberData.result));
    System.out.println("计算结果:" + result);
}
static Stream<NumberData> numberProvider() {
    return Stream.of(
            new NumberData(new int[]{1, 1}, 2, null, null),
            new NumberData(new int[]{1, 1, 9}, 11, null, null),
            new NumberData(new int[]{99, 99}, 198, null, null),
            new NumberData(new int[]{-99, 99}, 0, null, null),
            new NumberData(new int[]{99, -99}, 0, null, null),
            new NumberData(new int[]{-99, -99}, -198, null, null));
}

@ParameterizedTest
@MethodSource("addExceptionProiver")
void addException(NumberData numberData) {
    assertThrows(numberData.exceptionClass.getClass(), () -> c.sum(numberData.numbers), numberData.exceptionMessage);
}
static Stream<NumberData> addExceptionProiver() {
    return Stream.of(
            new NumberData(new int[]{100, 0}, 0, new NumberFormatException(), "integer is 100!"),
            new NumberData(new int[]{-100, -1}, 0, new IllegalArgumentException(), "请输入范围内的整数"),
            new NumberData(new int[]{2, 100}, 0, new NumberFormatException(), "integer is 100!"),
            new NumberData(new int[]{1, -100}, 0, new IllegalArgumentException(), "请输入范围内的整数")
    );
}

@ParameterizedTest
@MethodSource("subtractProvider")
void subtract(NumberData numberData) {
    int result = c.subtract(numberData.numbers);
    assertThat(result, equalTo(numberData.result));
    System.out.println("计算结果:" + result);
}
static Stream<NumberData> subtractProvider() {
    return Stream.of(
      new NumberData(new int[]{10, 10}, 0, null, null),
      new NumberData(new int[]{99, 99}, 0, null, null),
      new NumberData(new int[]{-99, 99}, -198, null, null),
      new NumberData(new int[]{99, -99}, 198, null, null),
      new NumberData(new int[]{-99, -99}, 0, null, null)
    );
}

@ParameterizedTest
@MethodSource("subtractExceptionProvider")
void subtractException(NumberData numberData) {
    assertThrows(numberData.exceptionClass.getClass(), () -> c.subtract(numberData.numbers), numberData.exceptionMessage);
}

static Stream< NumberData> subtractExceptionProvider() {
    return Stream.of(
            new NumberData(new int[]{100, 0},0 , new NumberFormatException(), "integer is 100!"),
            new NumberData(new int[]{-100, -1}, 0, new IllegalArgumentException(), "请输入范围内的整数!"),
            new NumberData(new int[]{2, 100}, 0, new NumberFormatException(), "integer is 100!"),
            new NumberData(new int[]{1, -100}, 0, new IllegalArgumentException(), "请输入范围内的整数!")
    );
}

@AfterEach
void close() {
    c.destroyId();
}

@AfterAll
static void after() {
    c.close();
}

private static class NumberData {
    int[] numbers;
    int result;
    Exception exceptionClass;
    String exceptionMessage;
    public NumberData(int[] numbers, int result, Exception exceptionClass, String exceptionMessage) {
        this.numbers = numbers;
        this.result = result;
        this.exceptionClass = exceptionClass;
        this.exceptionMessage = exceptionMessage;
    }
}

}