【实际开发01】- 单元测试 ( 追求正确性 )

这篇具有很好参考价值的文章主要介绍了【实际开发01】- 单元测试 ( 追求正确性 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

0. 单元测试 概念 / 解析

1. 为什么要进行单元测试

1. JUnit ~ @Test

2. IDEA 中使用 junit 单元测试 , 不能使用 Scanner 的解决方法

3. Junit 测试 Tutorial

1. daiding

4. @Test 修饰的方法必须 public

1. validatePublicVoidNoArgMethods(Test.class, false, errors);

2. public static void main(String[] args) {} ~ 程序入口

1. main 概念 / 解析

1. 为什么 main 方法是静态的(static)

2. 为什么main 方法是公有的 ( public )

3. 为什么 main 方法没有返回值 ( void )

2. 使用 main() 方法来测试有很多坏处

3. String[] 字符串数组

3. Junit 单元测试 和 main 函数区别 ( 踩坑 )

1. Junit 单元测试 不支持 多线程

1. Junit

2. main 函数

3. 解决方案

2. 结论 : 尽量不要在 @test 开启新线程


0. 单元测试 概念 / 解析

单元测试 , 就是针对最小的功能单元编写测试代码

在 Java 中 , 最小的功能单元就是方法 , 因此 , 对 Java 程序员进行单元测试实际上就是对 Java 方法的测试。

单元测试 : 任何一个小模块、小功能;模块式测试

 1、可以减少出错、缩小调试影响面
 ​
 2、一步步测 , 才是最快的方法;
 ​
 3、完成一部分测试一部分 , 防止自己懵逼!

写完一节 , 就进行单元测试 ;避免追求一气呵成的错误集中情况! (单元测试包 , 需保证唯一)


1. 为什么要进行单元测试

因为单元测试可以确保你编写的代码是符合软件需求和遵循开发规范的。

单元测试是所有测试中最底层的一类测试 , 是第一个环节 , 也是最重要的一个环节 , 是唯一一次能够达到代码覆盖率 100% 的测试 , 是整个软件测试过程的基础和前提。

可以这么说 , 单元测试的性价比是最好的。

微软公司之前有这样一个统计:

bug 在单元测试阶段被发现的平均耗时是 3.25 小时 , 如果遗漏到系统测试则需要 11.5 个小时。

【实际开发01】- 单元测试 ( 追求正确性 )

经我这么一说 , 你应该已经很清楚单元测试的重要性了。

那在你最初编写测试代码的时候 , 是不是经常这么做?就像下面这样。


1. JUnit ~ @Test

IDEA 会自动在当前类所在的包下生成一个类名带 Test ( 惯例 ) 的测试类


2. IDEA 中使用 junit 单元测试 , 不能使用 Scanner 的解决方法

参考:

解决IDEA中使用junit单元测试不能使用Scanner的方法_花開彼岸天丶的博客-CSDN博客_junit不能接收sacanner 解决IDEA中使用junit单元测试不能使用Scanner的方法

编程时在 IDEA 中引入单元测试 , 并在里面用了 Scanner 时 , 运行时会出一直在跑的问题 :

方案1 : 将测试类的代码放入 main 函数运行

方案2 : 在 IDEA 中点击 help -> Edit Custom Vm Options… , 进入 , 在最后一行加入:-Deditable.java.test.console=true

【实际开发01】- 单元测试 ( 追求正确性 )

最后 : 在 eclipse 中则不会出现这个问题;


3. Junit 测试 Tutorial


1. daiding


4. @Test 修饰的方法必须 public


1. validatePublicVoidNoArgMethods(Test.class, false, errors);

查阅 Junit 源码 :

     protected void validateInstanceMethods(List<Throwable> errors) {
         
         validatePublicVoidNoArgMethods(After.class, false, errors);
         validatePublicVoidNoArgMethods(Before.class, false, errors);
         
         validateTestMethods(errors);
         if (computeTestMethods().size() == 0)
             errors.add(new Exception(" No runnable methods "));
     }
 ​
     protected void validateTestMethods(List<Throwable> errors) {
         validatePublicVoidNoArgMethods(Test.class, false, errors);
     }

这表明 @Before、@After、@Test 注解的方法必须是 : public,void,非静态,不带参数。

【实际开发01】- 单元测试 ( 追求正确性 )


2. public static void main(String[] args) {} ~ 程序入口

Main 方法是 Java 程序的入口

记住,我们这里不会讨论 Servlet、MIDlet 和其他任何容器管理的 java 程序,在 java 核心编程中,JVM 会查找类中的 public static void main(String[]args),如果找不到该方法就抛出错误 NoSuchMethodError:main 程序终止。

Main 方法必须严格遵循它的语法规则,方法签名必须是 public static void,参数是字符串数组类型,如果是 Java1.5 及以后的版本还可以使用可变参数:

public static void main(String... args)

今天终于搞懂了:为什么 Java 的 main 方法必须是 public static void?

Public:访问权限最大。

static:不需要对象,直接类名即可。

void:主函数没有返回值。

Main:主函数特定的名称。

(String[] args):主函数的参数,是一个字符串数组类型的参数,jvm 调用 main() 方法时,传递的实际参数是 new String[0]。

 jvm 默认传递的是长度为0的字符串数组,
 我们在运行该类时,也可以指定具体的参数进行传递。
 可以在控制台,运行该类时,在后面加入参数。参数之间通过空格隔开。jvm会自动将这些字符串参数作为args数组中的元素,进行存储。

1. main 概念 / 解析

如果需要用 java 命令直接运行一个 Java 类 , 这个 Java 类必须包含 main 方法 ,

这个 main 方法必须使用 public 和 static 来修饰 , 必须使用 void 声明该方法的返回值 ,

而且该方法的参数类型只能是一个字符串数组 , 而不能是其他形式的参数。

对于这个 main 方法而言 , 前面的 public 和 static 修饰符的位置可以互换 , 但其他部分则是固定的。

定义 main 方法时 , 不要写成 Main 方法 , 如果不小心把方法名的首字母写成了大写 , 编译时不会出现任何问题 , 但运行该程序时将给出如图 2 的错误提示:

【实际开发01】- 单元测试 ( 追求正确性 )

这个错误提示找不到 main 方法 , 因为 Java 虚拟机只会选择从 main 方法开始执行。

对于 Main 方法 , Java 虚拟机会把该方法当成一个普通方法 , 而不是程序的入口。

main 方法里可以放置程序员需要执行的可执行性语句 , 例如 System.out.println("Hello Java!") ,

这行语句是 Java 里的输出语句 , 用于向控制台输岀“Hello Java!”这个字符串内容 , 输出结束后还输出一个换行符。

在 Java 程序里执行输岀有两种简单的方式:

System.out.print(需要输出的内容) 和 System.out.println (需要输出的内容) , 其中前者在输出结束后不会换行 , 而后者在输出结束后会换行。

总结:

1、main 方法必须声明为 public、static、void,否则 JVM 没法运行程序 。

2、如果 JVM 找不到 main 方法就抛出 NoSuchMethodError:main 异常,

 例如:如果你运行命令:java HelloWrold,JVM 就会在 HelloWorld.class 文件中搜索 public static void main (String[] args) 方法。

3、main 方式是程序的入口,程序执行的开始处。

4、main 方法被一个特定的线程 ”main” 运行,程序会一直运行直到 main 线程结束或者 non-daemon 线程终止。

5、当你看到 “Exception in Thread main” 如:Excpetion in Thread main:Java.lang.NullPointedException,意味着异常来自于 main 线程。

6、你可以声明 main 方法使用 java1.5 的可变参数的方式 ; 如:publicstaticvoid main(String... args)。

7、除了 static、void、和 public,你可以使用 final,synchronized、和 strictfp 修饰符在 main 方法的签名中,如:public strict fp final synchronized static void main(String[] args)

8、main 方法在 Java 可以像其他方法一样被重载,但是 JVM 只会调用上面这种签名规范的 main 方法。

9、你可以使用 throws 子句在方法签名中,可以抛出任何 checked 和 unchecked 异常。

10、静态初始化块在 JVM 调用 main 方法前被执行,它们在类被 JVM 加载到内存的时候就被执行了。


1. 为什么 main 方法是静态的(static)

1、正因为 main 方法是静态的,JVM 调用这个方法就不需要创建任何包含这个 main 方法的实例。

2、因为 C 和 C++ 同样有类似的 main 方法作为程序执行的入口。

3、如果 main 方法不声明为静态的,JVM 就必须创建 main 类的实例,因为构造器可以被重载,JVM 就没法确定调用哪个 main 方法。

4、静态方法和静态数据加载到内存就可以直接调用 , 而不需要像实例方法一样创建实例后才能调用,如果 main 方法是静态的,那么它就会被加载到 JVM 上下文中成为可执行的方法。


2. 为什么main 方法是公有的 ( public )

Java 指定了一些可访问的修饰符 ;如:private、protected、public,任何方法或变量都可以声明为 public,Java 可以从该类之外的地方访问。

因为 main 方法是公共的,JVM 就可以轻松的访问执行它。


3. 为什么 main 方法没有返回值 ( void )

因为 main 返回任何值对程序都没任何意义,所以设计成 void,意味着 main 不会有任何值返回。


2. 使用 main() 方法来测试有很多坏处

1、测试代码没有和源代码分开。

2、不够灵活 , 很难编写一组通用的测试代码。

3、无法自动打印出预期和实际的结果 , 没办法比对。

JUnit 的话 , 就不会再有这种困扰了。

我可以非常简单地组织测试代码 , 并随时运行它们 , 还能给出准确的测试报告 , 让你在最短的时间内发现自己编写的代码到底哪里出了问题。

【实际开发01】- 单元测试 ( 追求正确性 )

【实际开发01】- 单元测试 ( 追求正确性 )


3. String[] 字符串数组


3. Junit 单元测试 和 main 函数区别 ( 踩坑 )


1. Junit 单元测试 不支持 多线程

当 Thread 了新的线程后 , Junit 单元测试 在主线程运行结束后就关闭了 , 而不会等子线程运行结束。

而 main 函数就不存在这个问题了...

测试对比如下:


1. Junit

书写一个定时任务 , 每500ms执行一次:

【实际开发01】- 单元测试 ( 追求正确性 )

运行结果:

可以看出 , 当主线程执行结束后 , 就关闭了 , 不会等 子线程运行

【实际开发01】- 单元测试 ( 追求正确性 )


2. main 函数

同上 , 书写一个定时任务 , 每 500ms 执行一次:

【实际开发01】- 单元测试 ( 追求正确性 )

运行结果如下:  

【实际开发01】- 单元测试 ( 追求正确性 )


3. 解决方案

如果想使用Junit 进行多线程测试 , 可以先睡眠主线程 , 例如:

    @Test
    public void test(){
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+ ": ==========Junit 定时任务 =========");
            }
        } ,  new Date() ,  500);

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName()+ "==========Junit 主线程任务=========");
    }

2. 结论 : 尽量不要在 @test 开启新线程

@Test 单测方法和 main 方法文章来源地址https://www.toymoban.com/news/detail-456691.html

 在做一个多线程测试的时候发现的一个比较好玩的问题 , 
     在@Test的单测方法中开启了两个线程 , 本来应该在B()方法中的打印 , 没打出来 , 
     看了一下单测方法的线程是Thread[main , 5 , main] , 这方法开启的是main线程。
 ​
 网上一些人的观点是单测方法结束的时候会把里面的资源释放了 , 导致里面线程提前结束。
public class 多线程测试01 {
    int a ;
    boolean flag ;


    public static void main(String[] agrs) {
        多线程测试01 shen = new 多线程测试01();
        new Thread(new Runnable() {
            @Override
            public void run() {
                shen.A();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                    shen.B();
            }
        }).start();
    }

    // @Test 单测方法有一个问题 , 当单测方法结束的时候里面的线程也要结束 , 不管是不是执行完成
    // 结论不要在@Test开启线程
    @Test
    public void play() {
        多线程测试01 shen = new 多线程测试01();
        new Thread(new Runnable() {
            @Override
            public void run() {
                shen.A();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                shen.B();
            }
        }).start();

        System.out.println(Thread.currentThread());

    }


    public void A() {
//        try {
//            Thread.sleep(100);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        a = 1;
        flag = true;
    }


    public void B()  {
        if (flag) {
            System.out.println("flag = true  " + a);
        } else if(!flag){
            System.out.println("falg = false  " + a);
        }
    }
}

到了这里,关于【实际开发01】- 单元测试 ( 追求正确性 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 7 Series FPGAs Transceivers Wizard(3.6) ip核接收数据正确性判断

    对于GTX/GTH Transceivers IP核接收端数据准确性可以通过rxstatus的状态来确定,当rxstatus的小于4时,rxdata数据为正确值,大于4时,rxdata往往是有错。详见7 Series FPGAs Transceivers Wizard(3.6)  datasheet P321.

    2024年01月23日
    浏览(43)
  • 使用Win10自带的PowerShell命令校验文件和镜像文件的Hash值(MD5、SHA1/256等)正确性

    通常为了保证我们从网上下载的文件的完整性和可靠性,我们把文件下载下来以后都会校验一下MD5值或SHA1值(例如验证下载的Win10 ISO镜像是否为原始文件),这一般都需要借助专门的MD5检验工具来完成。但其实使用Windows系统自带的Windows PowerShell运行命令即可进行文件MD5、S

    2024年02月16日
    浏览(42)
  • Java用正确的姿势写单元测试以及mock

    对于一些简单的功能或业务,我们也许可以通过前端调试、postman等接口工具、main函数调用进行测试。但这每次改动代码都要人力测试,耗费大量的人力资源且不高效,真正的项目中单元测试是必不可少的。 单元测试的三步走: 1、组装方法入参 2、执行方法 3、对方法的执行

    2024年02月13日
    浏览(37)
  • 如何让chatgpt十分正确的帮咱们编写代码文档和单元测试

      有多少次你专注于编程而忘记了写函数、方法、类的非常简单的代码文档?我不是在问单元测试. 直到我发现ChatGPT可以做到这一点: 除了代码文档,它在编写单元测试方面也做得很好。此外,在最后,我可以要求他为其他想使用我的代码的贡献者生成一个用户友好的文档。

    2024年02月15日
    浏览(46)
  • test-01-java 单元测试框架 junit 入门介绍

    JUnit 是一个用于编写可重复测试的简单框架。 它是 xUnit 架构的一种实例,专门用于单元测试框架。 What to test? Need Desc Right 结果是否正确 B 边界条件是否满足 I 能反向关联吗 C 有其他手段交叉检查吗 E 是否可以强制异常发生 P 性能问题 CalculatorTest 类包含了一个测试方法 test

    2024年02月04日
    浏览(42)
  • java_day01_单元测试_配置文件

    一、软件的生命周期 **软件的可行性分析:**分析该软件是否值的研发,会消耗多少成本,能带来多少的利益等分析 **需求分析:**分析该软件具体该具备有那些功能,产品经理与客户一起讨论 **软件设计:**该软件应该使用什么样的架构,用什么样的数据库,每个模块的具体功能 **程序

    2024年02月06日
    浏览(32)
  • 后端开发_单元测试

    1. 本地依赖引入方式 Junit4.jar包 2. maven方式引入jar

    2024年01月24日
    浏览(40)
  • Web开发4:单元测试

    在Web开发中,单元测试是一种重要的开发实践,它可以帮助我们确保代码的质量和可靠性。通过编写和运行单元测试,我们可以验证代码的正确性,减少错误和缺陷,并提高代码的可维护性。本文将介绍单元测试的概念、好处以及如何在Web开发项目中进行单元测试。 单元测试

    2024年01月25日
    浏览(80)
  • 【go语言开发】编写单元测试

    本文主要介绍使用go语言编写单元测试用例,首先介绍如何编写单元测试,然后介绍基本命令的使用,最后给出demo示例 在go语言中编写单元测试时,使用说明 测试文件命名 :在 Go 语言中,测试文件的命名应与被测试的源代码文件相同,但以 “_test” 结尾。例如,如果你的源

    2024年02月04日
    浏览(45)
  • C# 软件开发之单元测试

    在日常开发中,一般通过启动调试或运行程序来查看功能是否符合预期,如果不符合预期,则需要优化程序,再次运行,如此反复,直到程序的输出符合预期需求为止。随着程序的不断复杂化,某些功能的测试也变得越来越复杂,可能为了验证一个很小的改动项,就需要操作

    2024年02月03日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包