junit学习一

一、简介

这个估计大家都比我清楚了,JUnit是一个单元测试框架,我们可以基于它编写用来测试代码的代码,从而更方便地进行回归测试。

二、编写测试与断言(Assertion)

在Junit4中,编写一个测试方法只需要使用@Test注解并保证被注解的方法满足以下条件

  • 方法可见性为public
  • 方法无返回值
  • 方法没有参数

在一个测试中,往往需要满足某种条件才能断定测试成功,而不仅仅是测试方法执行完毕,org.junit.Assert对象提供了各种断言方法,用于判定程序的执行结果是否符合预期,从而通过测试。

例如我们需要测试以下类的两个方法:

 1 package org.haibin369.common;
 2
 3 public class ObjectGenerator {
 4     public String getString(){
 5         return "String";
 6     }
 7
 8     public Object getNull(){
 9         return null;
10     }
11 }  

我们需要编写以下的测试类和方法:

 1 package org.haibin369.test;
 2
 3 import org.haibin369.common.ObjectGenerator;
 4 import org.junit.Test;
 5
 6 //静态导入,方便使用Assert对象的断言方法
 7 import static org.junit.Assert.*;
 8
 9 /**
10  * 测试类,不需继承任何JUnit的类
11  */
12 public class ObjectGeneratorTest {
13     //使用@Test标注测试方法
14     @Test
15     public void testGetString() {
16         ObjectGenerator generator = new ObjectGenerator();
17         String msg = generator.getString();
18         if (msg == null) {
19             //Assert中也有使测试失败的fail方法,参数为失败信息(此处仅作演示)
20             fail("Message is null");
21         }
22
23         //断言得到的msg为AString,否则测试失败,第一个参数为失败时的信息
24         assertEquals("Wrong message generated.", "AString", msg);
25     }
26
27     @Test
28     public void testGetNull() {
29         ObjectGenerator generator = new ObjectGenerator();
30         //断言为空
31         assertNull("Returned object is not null", generator.getNull());
32     }
33 }  

执行以上测试,第二个测试会通过,而第一个会报错(org.junit.ComparisonFailure: Wrong message generated.),表明代码返回的结果和预期的不一样。

org.junit.Assert对象中还有很多断言方法,详情可参考API。

 三、Before & After

现在有一个简单的登陆Action需要测试(User和ACLException代码比较简单,这里就不贴出来了)。

public class LoginAction {
    private static final User FORBIDDEN_USER = new User("admin", "admin");
    private static final List<User> LOGIN_USER = new ArrayList<User>();  

    public void login(User user) throws ACLException, InterruptedException {
        if (FORBIDDEN_USER.equals(user)) {
            Thread.sleep(2000);
            throw new ACLException("Access Denied!");
        }  

        if (!LOGIN_USER.contains(user)) {
            LOGIN_USER.add(user);
        }
    }  

    public void logout(User user) throws InterruptedException {
        LOGIN_USER.remove(user);
    }  

    public List<User> getLoginUser() {
        return LOGIN_USER;
    }
}

  

测试类很简单,如下:

 1 public class LoginActionTest {
 2     @Test
 3     public void testLoginSuccess() throws Exception {
 4         LoginAction loginAction = new LoginAction();
 5         User user = new User("haibin369", "123456");
 6         loginAction.login(user);
 7
 8         assertTrue("User didn‘t login!", loginAction.getLoginUser().contains(user));
 9     }
10
11     @Test
12     public void testLogout() throws Exception {
13         LoginAction loginAction = new LoginAction();
14         User user = new User("haibin369", "123456");
15         loginAction.login(user);
16         loginAction.logout(user);
17
18         assertFalse("User didn‘t logout!", loginAction.getLoginUser().contains(user));
19     }
20 }  

问题是这些测试中都有重复的代码去创建LoginAction,所以可以考虑把LoginAction作为成员变量,只初始化一次。同时为了避免测试方法间的影响,可以在每个测试执行完之后重置LoginAction的状态,即清空LOGIN_USER。在一般的测试中也许也会有类似的需求:在测试开始时打开一个文件,所有测试结束之后关闭这个文件。为了实现这种目的,JUnit提供了以下四个方法注解实现这种目的:

  • @BeforeClass / @AfterClass:在所有测试方法执行之前 / 后执行,被注解的方法必须是public,static,无返回值,无参数;
  • @Before / @After:在每个测试方法执行之前 / 后执行,被注解的方法必须是public,无返回值,无参数;

重写后的测试如下:

 1 public class LoginActionTest {
 2     private static LoginAction loginAction;
 3     private static User user;
 4
 5     @BeforeClass
 6     public static void init() {
 7         loginAction = new LoginAction();
 8         user = new User("haibin369", "123456");
 9     }
10
11     @After
12     public void clearLoginUser() {
13         loginAction.getLoginUser().clear();
14     }
15
16     @Test
17     public void testLoginSuccess() throws Exception {
18         loginAction.login(user);
19
20         assertTrue("User didn‘t login!", loginAction.getLoginUser().contains(user));
21     }
22
23     @Test
24     public void testLogout() throws Exception {
25         loginAction.login(user);
26         loginAction.logout(user);
27
28         assertFalse("User didn‘t logout!", loginAction.getLoginUser().contains(user));
29     }
30 }  

 四、异常测试

在上面的LoginAction中,当使用Admin帐号登陆时,会抛出异常,这部分代码也需要测试,我们可以在@Test注解中配置期待异常,当测试抛出指定异常的时候则测试成功。

1 //当测试方法抛出ACLException时测试成功
2 @Test(expected = ACLException.class)
3 public void testAdminLogin() throws ACLException, InterruptedException {
4     loginAction.login(new User("admin", "admin"));
5 }  

上面的测试能测试出方法按照预期抛出异常,但是如果代码里面不只一个地方抛出ACLException(只是包含的信息不一样),我们还是无法分辨出来。这种情况可以使用JUnit的ExpectedException Rule来解决。

 1 //使用@Rule标记ExpectedException
 2 @Rule
 3 public ExpectedException expectedException = ExpectedException.none();
 4
 5 @Test
 6 public void testAdminLogin2() throws ACLException, InterruptedException {
 7     //期待抛出ACLException
 8     expectedException.expect(ACLException.class);
 9     //期待抛出的异常信息中包含"Access Denied"字符串
10     expectedException.expectMessage(CoreMatchers.containsString("Access Denied"));
11     //当然也可以直接传入字符串,表示期待的异常信息(完全匹配)
12     //expectedException.expectMessage("Access Denied!");
13
14     loginAction.login(new User("admin", "admin"));
15 }  

五、超时测试

在JUnit中测试超时是使用@Test的timeout属性设置

1 //设置1000ms的超时时间,当超过这个时间测试还没执行完毕则失败
2 @Test(timeout = 1000)
3 public void testLoginTimeout() throws Exception {
4     loginAction.login(new User("admin", "admin"));
5 }  

也可以使用Timeout Rule设定全局的超时时间

1 //设置1000ms的超时时间,当超过这个时间测试还没执行完毕则失败
2 @Rule
3 public Timeout timeout = new Timeout(1000);
4
5 @Test
6 public void testLoginTimeout() throws Exception {
7     loginAction.login(new User("admin", "admin"));
8 }  

上面两个测试执行都会失败:java.lang.Exception: test timed out after 1000 milliseconds

六、忽略测试

使用@Ignore可以忽略一个测试

1 //忽略该测试,参数为输出信息
2 @Ignore("Temporary ignored as no changes.")
3 @Test(timeout = 1000)
4 public void testLoginTimeout() throws Exception {
5     loginAction.login(new User("admin", "admin"));
6 }  

执行类里的所有测试,会输出一下信息,表示该测试被忽略了。

Test ‘org.haibin369.test.LoginActionTest.testLoginTimeout‘ ignored (Temporary ignored as no changes.)

七、使用Suite执行多个测试类

现在我们有了ObjectGeneratorTest和LoginActionTest,如果需要一次过执行多个测试类的所有方法,可以使用@Suite与@Suite.SuiteClasses注解

 1 //使用JUnit的Suite Runner执行测试
 2 @RunWith(Suite.class)
 3 //配置所有需要执行的测试
 4 @Suite.SuiteClasses({
 5         ObjectGeneratorTest.class,
 6         LoginActionTest.class
 7 })
 8
 9 //创建一个类作为Test Suite的入口
10 public class MyTestSuite {
11 }  

此文为转载的日志,如有版权限制,愿意自动放弃

junit学习一

时间: 2024-11-09 00:49:30

junit学习一的相关文章

JUnit学习

很早以前就知道JUnit也知道它用来做单元测试.今天突然又想到还是要学一下这个JUnit,不然说出去不知道怎么用JUnit做单元测试……作为一个程序员怪丢人的.第一篇JUnit不算是一个总结性的文章,只算是第一次摸索着学习JUint怎么来用.到目前来看,确实可能和网上说的一样,不过是多了几个main方法而已,不过,我相信随着学习的深入,JUnit不仅仅是作为几个main方法来调用这么简单. 使用JUnit官方提供了几种方法,一是手动导入jar包,但在手动导入jar包的时候一定要记得导入两个包:

阿里知识储备之二——junit学习以及android单元测试

一,junit框架 http://blog.csdn.net/afeilxc/article/details/6218908 详细见这篇博客 juit目前已经可以和maven项目进行集成和测试,而且貌似不需要单独引入junit的组件就可以(maven自身已经引入?) 注意一下以下几个标记 @BeforeClass,@Before,@Test(timeout = 50),@After,@Before,@Test(expected = Exception.class),@After,@Before,

学习笔记之JUnit学习总结 [ 光影人像 东海陈光剑 的博客 ]

JUnit中的assert方法全部放在Assert类中,现在总结一下经常用到的junit类中assert方法. 1.assertTrue/False([String message],boolean condition) 判断一个条件是true还是false. 2.fail([String message,]); 失败,可以有消息,也可以没有消息. 3.assertEquals([String message],Object expected,Object actual); 判断是否相等,可以指

Junit 学习1 junit的简单使用

package junit; import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; import dbex.DBUtil2; /** * @ClassName: JUnitTest * @Description: 学习最单元测试JUnit的使用 * @author penny * @date 2017年12月2日 下午11:24:56 * */ public class JUnitTest

junit学习(3.x)

自动化测试 测试所有测试类 1 import junit.framework.TestCase; 2 import junit.framework.Assert; 3 4 /** 5 *测试类必须要继承TestCase类 6 *在junit3.8中,测试方法需要满足以下原则: 7 *1.public 8 *2.void 9 *3.无方法参数 10 *4.方法名称必须以test开头 11 *执行每个测试用例前会调用setup方法,后会调用tearDown方法 12 */ 13 public cla

junit学习之junit的基本介绍

Junit目前在一些大的公司或者相对规范的软件中使用的比较多,相当多的小公司并没有把单元测试看的太重要.在大点的公司开发人员每天上班后,第一件事情就是从svn上把自己负责的代码checkout下来,然后运行单元测试,如果单元测试通过,那么说明自己的代码没有问题,然后就在代码块上修改与添加,完成后再用junit进行测试,测试完成后如果没有问题,那么就把相应的代码块提交给svn上. 测试一般分为:单元测试.集成测试(主要看一块代码加进去后,系统会不会有问题).验收测试和压力测试. 在以前的的项目中也

Junit学习笔记(一):Junit的入门使用

junit4和junit3的区别  JUnit4中所有的测试用例采用@Annotation标注,JUnit3的通过类继承和特定方法名实现,Junit4比Junit3更灵活. JUnit的生命周期 @BeforeClass.@Before.@Test.@After.@AfterClass <<Before Class>> <<Person Constructor>> <<Before>> Test Method 1. <<A

JUnit学习笔记-入门介绍

新建Java项目,目录结构如图 T.java package com.umgsai.junit4; public class T { public int add(int x, int y) { return x + y; } public static void main(String[] args) { System.out.println(new T().add(2, 5)); //单元测试是写一个类要给别人用,测试会不会有bug //不用main方法来测试原因:不能一起运行,大多数情况下

Junit学习笔记

idea中使用junit 选中需要测试的类,使用快捷键ctrl+shit+T,快捷生成junit测试类 在idea中执行junit时,可以使用代码覆盖率形式执行 原文地址:https://www.cnblogs.com/Hawthorn-Garden/p/8442267.html