Java接口--Unit test and main function

50 阅读5分钟

一、模块化编程

以往的思维方式:

  1. 编写功能函数(方法)
  2. 进行本地测试
  3. main()方法中调用函数
  4. 看输出,程序员肉眼通过控制台打印输出,查看结果是否符合预期
  5. 预期结果是通过人工计算的

而在企业项目中,这种方式显然是不合理的,转变思维:

规定main方法中不应出现逻辑性的代码

逻辑性代码应当被抽离到单个的实现方法中

包括打印字符串也不应该出现在main()中

main是程序的入口点,main中只做方法调用



二、JUnit单元测试

当我们要脱离main测试时可以使用JUnit框架

(JUnit是为Java语言服务的单元测试框架)


什么是单元测试呢?了解单元测试的含义:

计算机编程中,单元测试(英语:Unit Testing)又称为模块测试 [来源请求] ,是针对程序模块软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

通常来说,程序员每修改一次程序就会进行最少一次单元测试,在编写程序的过程中前后很可能要进行多次单元测试,以证实程序达到软件规格书要求的工作目标,没有程序错误;虽然单元测试不是必须的,但也不坏,这牵涉到项目管理的政策决定。

每个理想的测试案例独立于其它案例;为测试时隔离模块,经常使用stubs、mock[1]或fake等测试马甲程序。单元测试通常由软件开发人员编写,用于确保他们所写的代码符合软件需求和遵循开发目标。它的实施方式可以是非常手动的(透过纸笔),或者是做成构建自动化的一部分。



三、获取JUnit.jar

JAR包是其他开发者编写的某些程序,通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便分发Java平台应用软件


可以在JUnit 5官网下载JUnit JAR包

也可以在Maven Repository下载JAR包



四、使用JUnit

用Maven构建工具可以直接进行jar包的配置

  1. 创建一个lib文件夹,将JUnit.jar放入其中
  2. 右键JUnit.jar,Add as Library...

JUnit.jar可以展开后引入jar包成功


现实项目资源目录中通常会创建一个test文件夹

开发者将测试程序放入test目录下进行单例测试

(此处我们为了快速学习单例测试思想并未做这样的操作)


创建如下目录: 请添加图片描述

新建一个Cale类:

package com.google;

public class Cale {
    public static int sum(int numberA, int numberB) {
        return numberA + numberB;
    }
}

新建一个CaleTest类:

package com.google;

import org.junit.Test;

public class CaleTest {
    // 注解 (框架)
    @Test
    public void sum() {
        int sum = Cale.sum(1,2);
        System.out.println(sum);
    }
}

运行项目:请添加图片描述 (若运行出现问题可能是依赖导致的,需要下载相关依赖进行引入)



五、Assert断言

到此为止我们依旧没有解决以往思维中 预期结果是通过人工计算的这么一个问题

那么如何解决这么一个问题? 可以使用JUnit中的断言方法:

更新CaleTest类:

package com.google;

import org.junit.Assert;
import org.junit.Test;

public class CaleTest {
    // 注解 (框架)
    @Test
    public void sum() {
        int sum = Cale.sum(1,2);
        System.out.println(sum);
        
        // 断言
        Assert.assertEquals(3,sum);
        // Assert.assertEquals(4,sum);
    }
}

运行测试:[预期结果是3时的输出] 请添加图片描述 运行测试:[预期结果是4时的输出] 请添加图片描述



六、随机测试

同样的,我们还希望测试过程是批量随机的

此时可以使用Random方法生成随机数进行测试


更新Cale类,这是我们程序的功能实现类:

package com.google;

public class Cale {
    
    public static int sum(int numberA, int numberB) {
        return numberA + numberB;
    }
    
    public static int subtraction(int numberA, int numberB) {
        return numberA - numberB;
    }
    
}


更新CaleTest类,我们使用此类对Cale功能实现类进行模块化测试:

package com.google;

import org.junit.Assert;
import org.junit.Test;

import java.util.concurrent.ThreadLocalRandom;

public class CaleTest {
    // 注解 (框架)
    @Test
    public void sum() {
        int numberA = ThreadLocalRandom.current().nextInt(-999,999);
        int numberB = ThreadLocalRandom.current().nextInt(-999,999);
        int sumResult = Cale.sum(numberA , numberB);

        Assert.assertEquals(numberA + numberB,sumResult);
    }

    @Test
    public void subtraction() {
        int numberA = ThreadLocalRandom.current().nextInt(-999,999);
        int numberB = ThreadLocalRandom.current().nextInt(-999,999);
        int subResult = Cale.subtraction(numberA , numberB);

        Assert.assertEquals(numberA - numberB,subResult);
    }

}


新建一个Main类,经过(Test)类测试后的模块就可以在Main中直接正常使用了:

package com.google;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        run();
    }

    public static void run(){
        System.out.println("========计算器========");
        Scanner scanA = new Scanner(System.in);
        Scanner scanB = new Scanner(System.in);
        Scanner scanC = new Scanner(System.in);
        Scanner scanD = new Scanner(System.in);

        System.out.println("进行加法运算,请输入两个值:");
        int intA = scanA.nextInt();
        int intB = scanB.nextInt();
        int sum = Cale.sum(intA,intB);
        System.out.println(sum);
        System.out.println("进行减法运算,请输入两个值:");
        int intC = scanC.nextInt();
        int intD = scanD.nextInt();
        int sub = Cale.subtraction(intC,intD);
        System.out.println(sub);
    }
}

此时项目中我们脱离了Main方法进行各功能模块的测试,

在大型分工项目中显然是更为合理的,且过程更加清爽便捷