一、测试准则

  1. 必须遵守AIR原则

    • A(自动化):单元测试应该是全自动执行的,并且非交互。单元测试中不准使用System.out来进行人工验证,必须使用assert来验证。
    • I (独立性):单元测试用例之间决不能互相调用,也不能依赖执行的先后次序。
      **反例:**method2需要依赖method1的执行,将执行结果作为method2的输入。
    • R(可重复):单元测试是可以重复执行的,不能受到外界环境的影响。
  2. 保证测试粒度足够小,有助于精确定位问题。单测粒度至多是类级别,一般是方法级别。

  3. 核心业务、核心应用、核心模块的增量代码必须确保单元测试通过。
    说明:新增代码及时补充单元测试,如果新增代码影响了原有单元测试,请及时修正。

  4. 单元测试的基本目标:语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都要达到100%。
    **说明:**在工程规约的应用分层中提到的DAO层,Manager层,可重用度高的Service,都应该进行单元测试。

  5. 对于数据库相关的查询,更新,删除等操作,不能假设数据库里的数据是存在的,或者直接操作数据库把数据插入进去,请使用程序插入或者导入数据的方式来准备数据。
    **反例:**删除某一行数据的单元测试,在数据库中,先直接手动增加一行作为删除目标,但是这一行新增数据并不符合业务插入规则,导致测试结果异常。

  6. 确保测试与时间无关,尽可能避免使用可能过期的数据;此类数据应手动或以编程方式刷新。

  7. 在设计评审阶段,开发人员需要和测试人员一起确定单元测试范围,单元测试最好覆盖所有测试用例。

  8. 单元测试作为一种质量保障手段,不建议项目发布后补充单元测试用例,建议在项目提测前完成单元测试。

  9. 不要在单元测试中打印任何内容。

  10. 不要在单元测试类的构造函数中初始化;使用@Before方法代替。

  11. 在测试类中,不要声明方法抛出任何特定类型的异常

    说明:声明它们抛出一种特定类型的异常的测试方法非常脆弱,因为每当被测试的方法发生变化时,都必须对其进行更改。

  12. 不要在单元测试中使用Thread.sleep

  13. 不要对单元测试存在如下误解:

    • 那是测试同学干的事情。
    • 单元测试代码是多余的。
    • 单元测试代码不需要维护。一年半载后,那么单元测试几乎处于废弃状态。
    • 单元测试与线上故障没有辩证关系。好的单元测试能够最大限度地规避线上故障。

二、结构规范

  1. 单元测试代码必须写在如下工程目录:src/test/java,不允许写在业务代码目录下。
    **说明:**源码构建时会跳过此目录,而单元测试框架默认是扫描此目录。

  2. 测试类命名规范:被测试的业务+Test、被测试的接口+Test、被测试的类+Test

    正例:例如当前的测试类为MessageLog该类的测试用例应为MessageLogTest。

  3. 测试用例命名规范:测试用例命名应做到简洁全面,可描述。避免使用test1、test2没有含义的名称。其次需要有必要的函数方法注释。

    推荐的命名法:MethodName_StateUnderTest_ExpectedBehavior

    • MethodName 被测试的方法、一组方法或者一组类。
    • StateUnderTest 测试进行的条件以及状态。
    • ExpectedBehavior 在测试场景指定的条件下,你对被测试方法行为的预期。

    正例:sum_simpleValues_calculated

    这种方式可以在不用看方法细节的情况明白方法要做的事情。同时,还建议在MethodName前加test,这样方便在ide中快速搜索到你要找的代码

  4. 测试开发包,测试包保持和被测包一致。

三、编码原则

  1. 编写单元测试代码遵守BCDE原则,以保证被测试模块的交付质量。

    • B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
    • C:Correct,正确的输入,并得到预期的结果。
    • D:Design,与设计文档相结合,来编写单元测试。
    • E:Error,强制错误信息输入(如:非法数据、异常流程、非业务允许输入等),并得到预期的结果。
  2. 和数据库相关的单元测试,可以设定自动回滚机制,不给数据库造成脏数据。或者对单元测试产生的数据有明确的前后缀标识。
    正例:在RDC内部单元测试中,使用RDCUNIT_TEST的前缀标识数据。

  3. 对于不可测的代码建议做必要的重构,使代码变得可测,避免为了达到测试要求而书写不规范测试代码。

  4. 为了更方便地进行单元测试,业务代码应避免以下情况:

    • 构造方法中做的事情过多。
    • 存在过多的全局变量和静态方法。
    • 存在过多的外部依赖。
    • 存在过多的条件语句。

    说明:多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。

  5. 编写测试时考虑语言环境,例如:

    对于下面的日期测试。

    Date date = DateFormat.getInstance ().parse ("dd/mm/yyyy");
    

    但是该代码不能在使用不同语言环境的机器上工作。因此,下面代码将会好很多

    Calendar cal = Calendar.getInstance ();
    Cal.set (yyyy, mm-1, dd);
    Date date = Calendar.getTime ();
    
  6. 利用JUnit的assert / fail方法和异常处理获得干净的测试代码

    反例

    public void exampleTest () {try {// do some test} catch (SomeApplicationException e) {fail ("Caught SomeApplicationException exception");}
    }
    

    正例

    public void exampleTest () throws SomeApplicationException {// do some test
    }
    

    说明:JUnit自动捕获异常。它认为未捕获的异常是错误

  7. 使用各种断言方法以一种更简单的方式表达你的意图。

    反例

    assert (creds == 3);
    

    正例

    assertEquals ("The number of credentials should be 3", 3, creds);
    

    说明:上面的示例对代码阅读器有用得多。如果断言失败,它将为测试人员提供更多信息。使用assertSame()测试两个引用指向同一个对象。使用assertEquals()测试两个对象是相等的。

  8. 不要假设测试用例中测试的运行顺序,不应该假定将以任何特定顺序调用测试。

    考虑以下代码段:

    public class SomeTestCase extends TestCase {public SomeTestCase (String testName) {super (testName);
    }
    public void testDoThisFirst () {...
    }
    public void testDoThisSecond () {}
    }
    

    说明:在此示例中,不确定使用反射时JUnit将以任何特定顺序运行这些测试。因此,除非将测试设计为按任何顺序运行,否则在不同的平台和Java VM上运行测试可能会产生不同的结果。避免时间耦合将使测试用例更加健壮,因为顺序的更改不会影响其他测试。如果测试是耦合的,则可能很难发现由次要更新导致的错误。

  9. 不要使用测试用例构造函数来设置测试用例。
    反例:

    public class SomeTest extends TestCasepublic SomeTest (String testName) {super (testName);// Perform test set-up}
    }
    
  10. 不要从文件系统上的硬编码位置加载数据

    反例

    public void setUp () {FileInputStream inp ("C:\\TestData\\dataSet1.dat");
    }
    

    说明:上面的代码依赖于C:\ TestData路径中的数据集。考虑在两种情况下是不正确的:1.测试人员没有空间将测试数据存储在C:上而是将其存储在另一个磁盘上;2.这些测试可能是在其他平台(例如Unix)上运行的。

    常见的方法将测试放在与源代码相同的位置。如:

    public void setUp () {FileInputStream inp ("dataSet1.dat");
    }
    
  11. 使用最合适的断言方法

    JUnit的断言方法有许多,应该了解最新版本的JUnit中的断言,并使用最合适的断言来获得最具可读性的测试代码。例如:

    • 使用assertTrue(classUnderTest.methodUnderTest())而不是assertEquals(true, classUnderTest.methodUnderTest())
    • 使用assertEquals(expectedReturnValue, classUnderTest.methodUnderTest())而不是assertTrue(classUnderTest.methodUnderTest().equals(expectedReturnValue))
    • 使用assertEquals(expectedCollection, classUnderTest.getCollection())而不是声明集合的大小和集合的每个成员。

四、如何测试dao层

  1. 对于dao的测试,我们应根据实际需要在测试类中继承 AbstractTransactionalJUnit4SpringContextTests 和AbstractJUnit4SpringContextTests中 的一个类。

    • AbstractTransactionalJUnit4SpringContextTests提供了数据库自动回滚,也就是说测试前和测试后数据库是一样的。
    • AbstractJUnit4SpringContextTests不提供数据库自动回滚,测试会破坏数据库。
  2. 如果你觉得每个测试用例都要配置spring环境很麻烦的话,可以先建立一个父类:BasicTest,然后继承该类即可。

  3. 如果你使用的是springboot + junit,那么测试环境可以这样配置

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = DemoApplication.class)
    public class BasicTest {}
    
    • RunWith中如果要使用SpringRunner你的junit版本需要在4.12以上,若在4.12以下,您应该这样写:@RunWith(SpringJUnit4ClassRunner.class),更多参数可自行百度。
    • SpringBootTest中classes的值为springboot的启动项,这里也可以省略。
  4. 理想情况下,测试应使用与应用程序相同的配置。是可能会有一些仅针对单元测试的更改。要解决此问题,您应该创建另一个特定于测试的配置文件,并添加/覆盖特定于测试的配置更改。

    例如在主应用程序中,如果是配置文件application-context.xml,则应创建另一个文件application-context-test.xml,并将原始配置导入到该文件的顶部。然后覆盖您可能需要的bean定义。

    application-context-test.xml

    <beans ····><import resource="application-context.xml"/><bean>要覆盖的bean</bean>
    </beans>
    

五、如何测试controller层

  1. .验证HTTP请求匹配

    我们应测试控制器应响应某些URL,HTTP方法和内容类型,即对控制器的请求方式,请求路径,参数类型等进行验证,保证控制器能准确的拦截非法数据。

  2. 输入验证

    假如实体类用了@NotNUll来拒绝null值,像这样

    public class UserResource {@NotNullprivate final String name;@NotNullprivate final String email;}
    

    此时就需要对控制器中的参数进行校验,同时如果控制器对参数添加了一些注解,如@Valid,也需要进行测试。

  3. 业务逻辑测试

    即我们需要测试方法是否按预期方式调用了业务逻辑。

  4. 验证输出序列化

    调用业务逻辑后我们希望控制器将结果映射到JSON字符串并将其包含在HTTP响应中,即判断返回的数据是否为我们期望的数据。

  5. 异常验证测试

    通常,如果发生异常,则控制器应返回某个HTTP状态。400,如果请求有问题,500,如果出现异常,依此类推。

junit 单元测试 规范相关推荐

  1. junit单元测试断言_简而言之,JUnit:单元测试断言

    junit单元测试断言 简而言之,本章涵盖了各种单元测试声明技术. 它详细说明了内置机制, Hamcrest匹配器和AssertJ断言的优缺点 . 正在进行的示例扩大了主题,并说明了如何创建和使用自定 ...

  2. 黑马就业班(01.JavaSE Java语言基础-11.Java基础加强)——基础加强:Junit单元测试、反射、注解

       1.Junit单元测试 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. Junit使用:白盒测试 步骤: ...

  3. JUnit单元测试、网络编程

    JUnit单元测试.网络编程 今日内容 JUnit单元测试 网络编程 第一章 JUnit单元测试 1.简介 Junit是什么 * Junit是Java语言编写的第三方单元测试框架(工具类) * 类库 ...

  4. java单元测试规范_Java单元测试编码规范

    包结构规范 单元测试包结构和源码结构必须保持一致,如下图所示: 文件命名规范 单元测试文件名字是由"被测试文件名 + Test"组成,如下图所示 代码编写规范 基础单元测试类 被各 ...

  5. idea package自动生成_Idea 自动生成Junit单元测试插件JunitGenerator

    JunitGenerator Idea中提供了可以自动生成Junit单元测试的插件,JunitGenerator.本篇文章将介绍如何在idea中安装.配置及使用JunitGenerator,以方便大家 ...

  6. JUnit单元测试依赖包构建路径错误解决办法

    JUnit单元测试依赖包构建路径错误解决办法: 选中报错的项目文件夹→右击选择属性(ALT+Enter)→java构建路径→库→添加库→JUnit→选择合适的Junit库版本.

  7. Junit单元测试需要知道的一些知识点

    Junit单元测试框架-基于java语言对的主流单元测试框架 @beforeClass-位于数据准备前期或者其他前期准备(测试类调用前) --用于提取代码中的共用部分减少冗余,只能声明注解一次 --必 ...

  8. java中JUnit单元测试的使用方法

    package com.atguigu.java2;import java.sql.Date;import org.junit.Test;/** java中的JUnit单元测试* 步骤:(可以直接写@ ...

  9. JUnit单元测试中的setUpBeforeClass()、tearDownAfterClass()、setUp()、tearDown()方法小结

    编写JUnit单元测试的时候,会用到 setUpBeforeClass().tearDownAfterClass().setUp().tearDown()这四个方法,例如用 eclipse新建一个ju ...

最新文章

  1. Go modules基础精进,六大核心概念全解析(上)
  2. 论坛报名 | 数理基础:人工智能的重大理论挑战和最新成果
  3. Java堆栈功能_【ThinkingInJava】35、用java实现堆栈功能
  4. 明天是我的生日,写给24岁的自己
  5. windows live writer 插件 VSPaste 中文乱码和去空白链接方案
  6. 在xcode上把你的app多语言国际化(NSLocalizedString)
  7. python Json的一点收获,自定义序列化方法
  8. json介绍及简单示例
  9. 干货干货:px和毫米之间的转换
  10. java 符_java运算符
  11. 女朋友也能看懂的Zookeeper分布式锁原理
  12. Writing a good ISMAR paper
  13. 四阶龙格库塔算法及matlab代码
  14. Gantt - attachEvent事件监听 - (必须)拥有返回值事件
  15. cad迷你画图2020中文版
  16. 梁宁《产品思维》之26三级火箭
  17. 洛谷 - P1014 [NOIP1999 普及组] Cantor 表 [Java版]
  18. 街道字符识别赛题理解
  19. 【C++代码】约瑟夫环问题:0,1,……,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
  20. WLAN 无线局域网

热门文章

  1. 扎克伯格成功的六大因素
  2. vue项目使用html2canvas 元素生成图片
  3. Python实现贝叶斯优化器(Bayes_opt)优化BP神经网络回归模型(BP神经网络回归算法)项目实战
  4. Airpods左右耳音量不一样
  5. 非世而恶利,自讬於无为,此非士之情也。
  6. html5清新文艺,清新文艺范的句子
  7. ALB+EC2+MySQL
  8. 算法训练Day11 | LeetCode232. 用栈实现队列(模拟);225.用队列实现栈(模拟);20. 有效的括号(栈应用);1047. 删除字符串中的所有相邻重复项(栈应用)
  9. csv乱码 ftp_php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
  10. 腾讯面试题目(大家围观下,看你会不会)