测试驱动开发(Test Driver Development)

1.使用main()方法测试的缺点:

  • 只能有1个main()方法,不能把测试代码分离
  • 没有打印出测试结果和期望结果,例如expected:3628800,but actual:362880
  • 因此,需要一种测试框架,帮助我们编写测试
public class Fact {
public static void main(String[] args) {
if(fact(10)==3628800){
System.out.println("pass");
}else {
System.out.println("fail");
}
}
public static long fact(long n){
long r = 1;
for(long i=1;i<n;i++){
r = r * i;
}
return r;
}
}

2.单元测试概念:

  • 单元测试是针对最小的功能单元编写测试代码
  • Java程序最小的功能单元是方法
  • 单元测试就是针对单个Java方法的测试

2.1单元测试的好处:

  • 确保单个方法运行正常
  • 如果修改了方法代码,只需确保其对应的单元测试通过
  • 测试代码本身就可以作为示例代码
  • 可以自动化运行所有测试并获得报告,报告包含成功和失败的用例,以及代码的覆盖率(一般要求70%以上)

2.2JUnit是一个开源的Java语言的单元测试框架

  • 专门针对Java语言设计,使用最广泛
  • JUnit是事实上的标准单元测试框架

JUnit特点:

  • 使用断言Assertion测试期望结果
  • 可以方便地组织和运行测试
  • 可以方便地查看测试结果
  • 常用IDE(例如Eclipse)都继承了JUnit
  • 可以方便的集成到Maven

JUnit的设计:

  • TestCase:一个Testcase表示一个测试
  • TestSuite:一个TestSuite包含一组TestCase,表示一组测试
  • TestFixture:一个TestFixture表示一个测试环境
  • TestResult:用于收集测试结果
  • TestRunner:用于运行测试
  • TestListener:用于监听测试过程,收集测试数据
  • Assert:用于断言测试结果是否正确

使用Assert断言:import static org.junit.Assert.*

  • 断言相等:assertEquals(100,x)
  • 断言数组相等:assertArrayEquals({1,2,3},x)
  • 断言浮点数相等:assertEquals(3.1415,x,0.0001) 最后为误差范围
  • 断言为null:assertNull(x)
  • 断言为true/false:assertTrue(x>0) assertFalse(x<0)
  • 其他:assertNotEquals/assertNotNull

3.代码示例

带测试方法类Main.java

import java.util.Arrays;

public class Main {
public long fact(long n){
long r = 1;
for(long i=1;i<=n;i++){
r = r * i;
}
return r;
}
public int calculate(String expression){
String[] ss = expression.split("\\+");
System.out.println(expression+"=>"+ Arrays.toString(ss));
int sum=0;
for(String s:ss){
sum = sum + Integer.parseInt(s);
}
return sum;
}
}

3.1IDEA创建单元测试

  • 3.1.1根目录下新建test目录,右键->Mark Direcotory as -> Test Sources Root
  • 3.1.2打开待测试类Func.java,右键->Go to->Test->Create new Test,或者ctrl+shift+t
  • 3.1.3勾选测试的方法即可,生成类名默认加上Test的后缀

3.2.Eclipse创建单元测试

  • 3.2.1根目录右键new->Source Folder,创建test目录,希望将所有的单元测试都放在test目录下
  • 3.2.2选择待测试类,new->Junit Test Case(如果没有,new-other-java-JUnit-Junit Test Case),选择New Junit4 test,Source Folder选择刚才创建的test目录->选择测试的方法->finsh,注意 Add Junit4 library to the build path,点击OK,创建完成
//MainTest.java
package com.testList; import static org.junit.Assert.*;
import com.testList.Main;
public class MainTest { @org.junit.Test
public void fact() {
assertEquals(6,new Main().fact(3));
assertEquals(24,new Main().fact(4));
assertEquals(720,new Main().fact(6));
} @org.junit.Test
public void calculate() {
assertEquals(3,new Main().calculate("1+2"));
assertEquals(6,new Main().calculate("1+2+3"));
assertEquals(35,new Main().calculate("12+23"));
}
}


测试中发现的问题:如果传入的表达式中包含空格,如" 1 + 2"会提示java.lang.NumberFormatException,直接打印字符,发现字符包含空格,因此在转换为int时报错。修改代码,使用trim去除首尾的空格
```#java
public void calculateWithSpace(){
String expre = " 1 + 2";
String[] ss = expre.split("\\+");
// assertEquals(0,new Main().calculate(" 1 + 2"));
for(String s:ss){
System.out.println('a'+s+'a');//结果图1
//System.out.println('a'+s.trim()+'a');//结果图2
}
}
```


修复之后,测试完成
```#java
//Main.java
public int calculate(String expression){
String[] ss = expression.split("\\+");
System.out.println(expression+"=>"+ Arrays.toString(ss));
int sum=0;
for(String s:ss){
sum = sum + Integer.parseInt(s.trim());
}
return sum;
}
//MainTest.java
@Test
public void calculateWithSpace(){
assertEquals(3,new Main().calculate(" 1 + 2"));
}
```

4.总结:

  • 一个TestCase包含一组相关的测试方法
  • 使用Assert断言测试结果(注意浮点数assertEquals要制定误差范围delta)
  • 每个测试方法必须完全独立
  • 测试代码必须非常简单
  • 不能为测试代码再编写测试
  • 测试需要覆盖各种输入条件,特别是边界条件

廖雪峰Java8JUnit单元测试-1JUnit简介-1JUnit测试的更多相关文章

  1. 廖雪峰Java8JUnit单元测试-2使用JUnit-4超时测试

    1.超时测试 可以为JUnit的单个测试设置超时: 超时设置1秒:@Test(timeout=1000),单位为毫秒 2.示例 Leibniz定理:PI/4= 1 - 1/3 + 1/5 - 1/7 ...

  2. 廖雪峰Java8JUnit单元测试-2使用JUnit-3参数化测试

    参数化测试: 可以把测试数据组织起来 用不同的测试数据调用相同的测试方法

  3. 廖雪峰Java8JUnit单元测试-2使用JUnit-2异常测试

    1.异常测试 对可能抛出的异常进行测试: 异常本身是方法签名的一部分: * public static int parseInt(String s) throws NumberFormatExcept ...

  4. 廖雪峰Java8JUnit单元测试-2使用JUnit-1使用Before和After

    1. @Before和@After 同一个单元测试内的多个测试方法: 测试前都需要初始化某些对象 测试后可能需要清理资源fileInputStream.close() @Test public voi ...

  5. 廖雪峰Java1-1Java入门-java简介

    Java特点: 一种面向对象的跨平台变成语言 以字节码方式运行在虚拟机上 自带功能齐全的类库 非常活跃的开源社区支持 Java优点: 简单.健壮.安全 跨平台,一次编写,到处运行 高度优化的虚拟机 J ...

  6. git学习笔记——廖雪峰git教程

    OK,先附上教程--廖雪峰的官方网站 友情连接:git官网 简介 这里我只想引用他的原文: Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的.实际情况是这样的: L ...

  7. 廖雪峰Python电子书总结

    函数 1.注意:函数的默认参数必须指向不可变对象 未修改前: def add_end(L=[]): L.append('END') return L 存在的问题:如果连续调用多次,会出现多个 'END ...

  8. git常用命令总结--廖雪峰老师Git教程命令总结

    学习了廖雪峰老师的Git教程之后的命令总结,重点关于git和远程仓库的东西. 如果没有学过,这是传送门 下面这个图很重要 一.git初始化本地仓库和配置 echo "想输入到文件的内容,一般 ...

  9. git入门笔记汇总——(廖雪峰博客git入门)

    本文内容是对廖雪峰老师Git教程做的笔记,外加一些自己的学习心得,还抱着学以致用的心态来实践一番 如有显示错误 请移步本人github:git教程小结 Git学习笔记 Git简介 安装Git 创建版本 ...

随机推荐

  1. C语言进阶1-#define和const

    宏的命名规范:一般以项目前缀开头,key结尾. #开头表编译. 宏的用法:1.定义常用字符串. 2.定义一段代码. const与宏的区别:1.编译时刻:宏-预编译    const-command+b ...

  2. iOS开发,改变系统铃声音量和静音,并非媒体播放音量

    使用AVSystemController可以改变系统声音,而且是铃声,并非媒体播放的声音. 它可以让iPhone手机静音.但是,AVSystemController存在于私有Celestial框架中. ...

  3. 配置3层交换机VLAN间通信

    SW2 Switch>en Switch#conf t Enter configuration commands, one per line. End with CNTL/Z. Switch(c ...

  4. PC端的软件端口和adb 5037端口冲突解决方案

    引用https://www.aliyun.com/jiaocheng/32552.html 阿里云 >  教程中心   >  android教程 >  PC端的软件端口和adb 50 ...

  5. ssh 无秘钥登录

    三台centos 一台服务器192.168.2.152 一台客户端192.168.2.142 一台客户端192.168.2.151 (1)产生无密钥 [root@localhost ~]#  ssh- ...

  6. 手动清除mac的广告弹框病毒 MacOSDefender

    最近在浏览亚马逊, 京东的时候, 发现会自动弹出很多广告到浏览器, 其实是中了病毒MacOSDefender. 这个病毒非常烦人, 会在你浏览电商网页的时候拼命的打开广告页面, 而且还会弹出一些提示, ...

  7. nodejs之mock与跨域代理的三两事

    emmm...好久没写博客了,都忘了该怎么开始. 那就先说下mockjs.因为一些原因,导致后台接口没有数据,那么我们就开始自己造数据,使用的是比较流行mockjs,根据文档就能简单的配置,然后开始愉 ...

  8. 通过for 来获取数组里面的电话

    //存放的是电话号码包含的数字 , , , , , }; //电话号码出现的下标 , , , , , , , , , , }; //方式1 ; i < index.length; i++) { ...

  9. Python3.7 练习题(三) 将指定目录下的图片进行批量尺寸大小处理

    # 将指定目录下的图片进行批量尺寸大小处理 #修改图片尺寸 导入Image os 快捷键 alt+enter import os from PIL import Image def process_i ...

  10. vue 使用canvas仿芝麻分信用表

    如图所示: 画布组件:dashboard.vue <template> <div> <canvas ref="canvas" v-if="c ...