参考自:
偏头痛杨的为什么我们要写单元测试用例?
junit4入门视频
junit4备忘录
先来看一下目录:
1. JUnit是什么?
2. 为什么用JUnit?
3. 测试驱动开发是什么?
4. 在eclipse中为项目添加Junit环境
5. 创建单元测试类实例
6. 常用JUnit4注解
7. 测试失败的两种情况
8. 断言
9. JUnit测试套件的使用
10. JUnit参数化设置
最后 本来 JUnit4要结合Web项目才更实用,可是吧 我还是没接触到,现在也只是简单介绍一下
下面内容只要有java基础和eclipse的使用能力就可以参考
学新知识的三个必问:
JUnit是什么?
为什么用JUnit?
JUnit怎么用?
JUnit是什么?
JUnit是单元测试的基础单元测试框架。
那又什么是单元测试呢?
每编写完一个函数之后,都应该对这个函数的方方面面进行测试,
这样的测试我们称之为单元测试。
单元测试是代码正确性验证的工具。需要编写代码才能进行测试的一种测试方法。
为什么用JUnit?
使用单元测试能够帮助我们减少在开发过程中的错误,把Bug扼杀在萌芽之中,
有利于代码的后期维护和检查。
做好了单元测试可以缩短开发周期,提高代码质量。主要用于中大型项目
而JUnit是单元测试的基本单元测试框架
对复杂的单元测试情况则要借助第三方框架和技术,这里就不多介绍了。
简单举例:
当你项目编译,打包,启动项目后发现没有启动相关权限,然后手动开启,然后
又发现有个bug,然后断点调试,修改后又编译,打包,启动项目,
这个时候又发现自己修改错了,又得从头来过。这个时候是不是要炸了,
反正是我就原地螺旋爆炸, 效率低不说,还不利于维护。
总结:
通过写单元测试用例的方式,把问题暴露在没有这一堆前置步骤的时候
这样会节省我们大量的前置步骤时间。
开发人员实现某个功能或者修补了某个bug,如果有相应的单元测试支持的话,
开发人员可以马上通过运行单元测试来验证之前完成的代码是否正确,
粗浅理解:
JUnit可以不用main就可以启动单元测试用例,
查看指定的方法是否跟预期的一样。
有句话说的好:
测试用例不是用来证明你(的逻辑)是对的,
而是用来证明你(的断言)没有错。
上面什么意思?
答:测试用例只是用来达到想要的预期结果,但对代码逻辑错误无能为力。
你也可以说测试用例只看结果 不看过程
测试驱动开发:
“码未动,测试先行。”这是极限编程中倡导的一种编程模式,为什么要这样呢?
因为我们在编写单元测试的过程中,其实就是在设计我们的代码将要处理哪些问题。
单元测试写的好,就代表你的代码写的好。
而且你会根据单元测试的一些预先设想的情况去编写代码,
就不会盲目的添加一个属性、添加一个方法了。
好了进入正题 前面bb了好多,其实也是参考了别人的原话来的,如果想看的话 参考开头贴出的几个地址,因为我也是从上面总结的。
要是没理解 那我再来总结一遍:
以前我们要是测试一段代码是否正确怎么做呢?
反正我是System.out.println() 或者断点才可以查看代码的结果 不只是我
相信大家都是这么过来的吧。
现在介绍一个新的方法就是`JUnit`来测试代码。
JUnit是一个Java语言的单元测试框架。
至于JUnit4还是JUnit5这个选择还是得看你自己,前者已经统治了10余年,后者刚出来没多久还在测试阶段,网上的资料也很多都是围绕JUnit4的。
junit4基本用注解实现. 有人会问 什么是注解?
我也是直接百度百科搜的:
也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
这里也就介绍JUnit4
了。
在eclipse中为项目添加Junit环境:
右键Java项目,在build path中“add library”,添加Junit 然后选择Junit4
最后会显示这样:
首先创建一个你需要检测的类 然后写正常方法
再创建单元测试类实例:
- 右键要src 选择Source Folder,创建来源于src的文件夹 最好是test名字,因为是用来存放单元测试类的。(注意 :文件是在src文件夹下哦)
- 然后右击创建的文件夹选择“new”,创建Junit test case(测试类实例)
3. 然后自己添加一个测试方法:
项目或者包或者测试方法右击 run as ->JUnit Text
显示:
第二个有x是因为fail
fail方法是指测试失败 删掉就好了
其中:
Runs: 运行的测试单元方法数 是指@Test数量
Errors:抛出异常的测试方法计数器
Failures:失败的测试方法计数器
其中使用@Test标签标注测试方法
assertEquals测试2个参数是否相等。
测试方法通过@Test来标识,初始化方法通过@Before来标识,释放资源的方法通过@After来标识。
问题1:
可是上面这个run as方法 是全部都测试
那有没有办法只测试其中的方法呢?
点击单元测试类,下面显示全部测试方法 ,选择要测试的方法
然后run as即可
问题2:
如果手动添加单元测试类的测试方法那多累啊 万一有很多方法呢?
答:右击要测试的类 然后new -->other
选择 JUnit Test Case
然后 next
最后finsh
结果:
遇到这个问题:
重新创建一个项目就好了 不知道为什么……有知道的 可以告诉我一下,谢谢
常用JUnit4注解
@BeforeClass: public static void方法 是静态方法,当前测试类被加载后就执行,意思就是在所有的测试方法运行前被执行; 在内存中也只有一份实例,适合加载配置文件
@Before: public void方法,当前测试类,他会在所有方法运行结束后被执行; 可以用来创建一些测试数据。 无论用例成功or失败都会run这个
@Test: public void方法,将一个普通的方法修饰成为一个测试方法。具有两个参数(可选):
timeout: 该测试方法允许执行的最大时间长度。单位ms
@Test(timeout=5000)
执行超出时间无法通过(单位毫秒)会抛出error错误 但是程序也强制结束
一般用于解决死循环问题
expected: 捕获抛出的异常。xx.class
@Test(expected=NullPointerException.class)
出了指定异常才会通过,上面定义的异常可以是父类异常,方法中抛的异常只要是其子类都可以。
@AfterClass: public static void方法,与@BeforeClass组成一对,在当前测试类做完所有测试后执行的一个方法;通常用来对资源的清理,如数据库的关闭
@After:对应@Before
使用了该元数据的方法在每个测试方法执行之后要执行一次,
如果希望每次运行测试方法之后运行指定的回收资源的方法。
无论用例成功or失败都会run这个
@Ignore: 所修饰的测试方法会被测试运行器忽略,需要写在@Test上面;
还可以加上点信息 如@Ignore("...")
@RunWith: 更改测试运行器,自定义运行器需要继承于org.junit.runner.Runner。 一般使用默认的就可以完成大部分工作
@Ignore
如果希望Junit忽略某个被测试的方法,可以使用@Ignore Annotaion来修饰.
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
junit测试用例,按文字顺序执行,修饰在类上。
可以选择创建测试用例的时候自动生成after等:
看一下样例:
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("BeforeClass");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("AfterClass");
}
@Before
public void setUp() throws Exception {
System.out.println("Before");
}
@After
public void tearDown() throws Exception {
System.out.println("After");
}
@Test
public void test1() {
System.out.println("test1");
}
@Test
public void test2() {
System.out.println("test2");
}
输出:
BeforeClass
Before
test1
After
Before
test2
After
AfterClass
注意:
1. 测试方法上必须使用@Test进行修饰;
2. 测试方法必须使用public void 进行修饰,不能待任何的参数;
3. 新建一个源文件目录存放我们的测试代码
4. 测试单元中的每个方法必须可以独立测试,
测试方法间不能有任何的依赖;
5. 测试类的包应该和被测试的包保持一致
测试类使用Test作为类名的后缀(可选);
测试方法使用test作为方法名的前缀(可选);
测试失败的两种情况:
- Failure一般是由单元测试使用的断言方法判断失败所引起的 这表示程序输出的结果和我们预期的不一样
- error是代码异常引发的,他可以产生于测试代码本身的错误,也可以产生于被测试代码中的一个隐藏的bug
那怎么看错误:
可以看Failure Trac 错误队列
断言:
断言在org.junit.Assert类中,有一组以assert开头的方法用于断言测试,基本上涵盖了大部分需求。
回到开头讲的
测试用例不是用来证明你(的逻辑)是对的,
而是用来证明你(的断言)没有错。
如果断言为真,测试通过,如果断言为假,测试失败。
就是我们用来测试程序是否和预期值结果一样的 static void 方法
如:
assertEquals(expected, actual); 这是比较方法返回值和预期值的比较
来判断程序是否符合某个条件,
在举一下其他栗子:
assertTrue 真值断言
assertFalse 假植断言
assertEquals 相等断言
assertNotEquals 不等断言
assertNull 空值断言
assertNotNull 非空值断言
assertFail 断言失败
JUnit测试套件的使用--批量运行测试类
测试套件就是组织测试类一起运行 而不需要一次运行一个测试类
写一个作为测试套件的入口类,这个类不能包涵其他的方法
然后 更改测试运行器Suite.class
将要测试的类作为参数传入到Suite.SuiteClasses({})中
举个栗子 : 正常创建一个测试类
@RunWith(Suite.class)
@Suite.SuiteClasses({ssTestaa.class,ssTest11.class})
public class hah {
}
然后启动hah这个测试类就行了
效果图:
JUnit参数化设置--批量运行多组测试用例
很多时候,我们需要对一个测试,输入多组测试用例来验证代码的正确性。在junit4中,我们不需要编写n个测试方法。 只需要参数化设置
- 更改默认的测试运行器为RunWith(Parameterized.class)
- 声明变量存放预期值和结果值 (随便起名字,class中自己使用,expected/input1/input2);
- 声明一个返回值为Collection的公共静态方法,并使用@Parameters进行修饰
- 为测试类声明一个带有参数的公共构造函数,并在其中为之声明变量赋值
举个栗子:
package day1;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class ssText {
int expected=0;
int input1=0;
int input2=0;
@Parameterized.Parameters
public static Collection<Object[]> params(){
return Arrays.asList(new Object[][]{
{3,2,1},
{4,1,4}
});
}
public ssText(int expected,int input1,int input2) {
this.expected=expected;
this.input1=input1;
this.input2=input2;
}
@Test
public void test() {
assertEquals(expected, new ss().add(input1, input2));
}
}
结果:
自己也是初学,难免有差错
如有问题,欢迎讨论,一起学习,一起进步。