JUnit4教程(一):基本应用

article/2025/10/2 13:08:22

一、简介

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

 

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

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

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

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

 

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

Java代码   收藏代码
  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. }  

 

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

Java代码   收藏代码
  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代码比较简单,这里就不贴出来了)。

 

Java代码   收藏代码
  1. public class LoginAction {  
  2.     private static final User FORBIDDEN_USER = new User("admin""admin");  
  3.     private static final List<User> LOGIN_USER = new ArrayList<User>();  
  4.   
  5.     public void login(User user) throws ACLException, InterruptedException {  
  6.         if (FORBIDDEN_USER.equals(user)) {  
  7.             Thread.sleep(2000);  
  8.             throw new ACLException("Access Denied!");  
  9.         }  
  10.   
  11.         if (!LOGIN_USER.contains(user)) {  
  12.             LOGIN_USER.add(user);  
  13.         }  
  14.     }  
  15.   
  16.     public void logout(User user) throws InterruptedException {  
  17.         LOGIN_USER.remove(user);  
  18.     }  
  19.   
  20.     public List<User> getLoginUser() {  
  21.         return LOGIN_USER;  
  22.     }  
  23. }  

 

 

 测试类很简单,如下:

Java代码   收藏代码
  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,无返回值,无参数;

重写后的测试如下:

Java代码   收藏代码
  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注解中配置期待异常,当测试抛出指定异常的时候则测试成功。

Java代码   收藏代码
  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来解决。

 

Java代码   收藏代码
  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属性设置

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

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

Java代码   收藏代码
  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可以忽略一个测试

Java代码   收藏代码
  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注解

Java代码   收藏代码
  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. }  

 原文链接:http://haibin369.iteye.com/blog/2077638


http://chatgpt.dhexx.cn/article/wo7oRnRZ.shtml

相关文章

JUnit4使用教程-快速入门

序言 大学刚学java的时候就听说过JUnit了&#xff0c;单元测试框架&#xff0c;很好用的测试框架&#xff0c;JUnit测试框架将测试更加便捷和容易&#xff0c;编写测试代码也是简单、明了&#xff0c;功能强大。今天我给大家简单分享一下最新JUnit4的使用&#xff0c;几分钟入…

单元测试——junit4入门例子

简单的Junit4 单元测试入门例子 新建第一个测试test case 这次我使用一个简单的例子来介绍如何写一个简单的单元测试&#xff0c;这里所用的测试工具是eclipse。 点击下载->涉及的项目源代码下载 被测文件 Calculate.java package com.junit4.main;public class Calcul…

JUnit4教程

因jdk5中的新特性&#xff0c;JUnit4也因此有了很大的改变。确切的说&#xff0c;Junit4简直就不是3的扩展版本&#xff0c;而是一个全新的测试框架。下面详细介绍JUnit4的使用方法 1.测试方法&#xff1a; 在junit4之前&#xff0c;测试类通过继承TestCase类&#xff0c;并使用…

JUnit4 jar包下载

JUnit4 jar包 链接&#xff1a;https://pan.baidu.com/s/112B-PaQvlTAzEXxHcpC9Sw 密码&#xff1a;ktrn

JUnit4单元测试入门教程

JUnit4单元测试入门教程 - 简书 本文按以下顺序讲解JUnit4的使用 下载jar包单元测试初体验自动生成测试类执行顺序Test的属性 下载jar包## 下载地址 在github上&#xff0c;把以下两个jar包都下载下来。 下载junit-4.12.jar&#xff0c;junit-4.12-javadoc.jar&#xff08;文…

JUnit4的使用和配置

JUnit4是JUnit框架有史以来的最大改进&#xff0c;其主要目标便是利用Java5的Annotation特性简化测试用例的编写。 先简单解释一下什么是Annotation&#xff0c;这个单词一般是翻译成元数据。元数据是什么&#xff1f;元数据就是描述数据的数据。也就是说&#xff0c;这个东西在…

浅谈java单元测试框架junit4/5

0 前言 junit是一个开源的Java语言的单元测试框架。目前junit主要有版本junit3&#xff0c;junit4和junit5。因在junit3中&#xff0c;是通过对测试类和测试方法的命名来确定是否是测试&#xff0c;且所有的测试类必须继承junit的测试基类TestCase&#xff0c;所以本文不再讨论…

IDEA中使用JUnit4(单元测试框架)超详细!

IDEA中使用JUnit4教程 超详细&#xff01;(单元测试框架) 导语&#xff1a;自动化测试的必经之路–Selenium 作者&#xff1a;变优秀的小白 Github&#xff1a;YX-XiaoBai QQ交流群(new): 811792998 爱好&#xff1a;Americano More Ice ! 话不多说&#xff0c;实战为主&…

Junit 4 的使用

一、什么是 Junit 我们来百度一波&#xff0c;什么是 Junit 可以看到哈&#xff0c;Junit 是一个 Java 语言的单元测试框架&#xff0c;这个东西是程序员自测所需要的一个东西&#xff0c;这个测试也被称为白盒测试。&#xff08;下面会去说什么是白盒测试&#xff09; 我们之…

JUnit4

1.JUnit4全面引入Annotation来执行我们编写的测试 2.JUnit4并不要求测试类继承TestCase父类 3.在一个测试类中&#xff0c;所有被Test注解所修饰的public,void方法都是test case,可以被JUnit所执行。 4.虽然JUnit4并不要求测试方法名以test开头&#xff0c;但我们最好还是按照 …

Junit 4详解

Java单元机测试框架 --- Junit4 1、什么是Junit4 JUnit4是一个易学易用的Java单元测试框架,一般我们在写完一段代码或一个方法的时候,都要测试一下这段代码和这个方法的逻辑是不是正确,输入一定的数据,返回的数据是不是我们想要的结果,即我们在写单个业务代码针对结果进行…

IOS UIBUtton

Type 第二个是Customer 常用 按钮的阴影效果只能左右 这是区别于标签的地方 阴影设置没有负值 按钮的代码使用 按钮点击方法 代码设置 传参

UIButton设置图片位置

设置小图片image的位置 image默认图片保持原大小可以通过设置contentVerticalAlignment和contentHorizontalAlignment&#xff0c;修改位置&#xff0c;甚至填充满按钮 // 修改图片位置 图2的效果[button setImage:image forState:UIControlStateNormal];button.contentVerti…

UIButton基础总结

1、UIButton简介 UIButton继承自UIControl。 2、UIButton的四种状态 UIButton的四种状态分别为Normal、Highlighted、Disabled和Selected。 **&#xff08;1&#xff09;Normal&#xff1a;**按钮的普通状态&#xff0c;即为按钮的初始状态 **&#xff08;2&#xff09;Highlig…

[Swift]代码触发UIButton的点击事件

使用极光的手机号码一键登录功能&#xff0c;要求点击按钮后先弹出协议同意&#xff0c;同意协议后自动改变底部协议状态再自动代码触发登录按钮的点击事件。 OC: [but sendActionsForControlEvents:UIControlEventTouchUpInside];Swift: but.sendActions(for: .touchUpInsid…

iOS UIButton控件

UIButton是UIControl的子类&#xff0c;实现了按钮功能&#xff0c;交互事件和控件状态可查看iOS UIControl控件。 1. 初始化 通过指定按钮类型来创建UIButton对象 (instancetype)buttonWithType:(UIButtonType)buttonType;UIButtonType是一个枚举类型 值说明UIButtonTypeCu…

UIButton基础

一、UIButton基础 与UILabel相同&#xff0c;UIButton对象也需要在ViewController中写一个创建函数来建立 UIButton对象的建立如下&#xff1a; //创建普通按钮函数 - (void) createUIRectButton {//创建一个btn对象&#xff0c;更具类型来创建btn//圆角类型btn:UIButtonType…

UIButton 基础

创建一个button 注意button只能通过类方法创建&#xff0c;不能使用alloc 该段代码添加在函数- (void)viewDidLoad 中 //通过类方法创建一个UIbuttonUIButton* btn [UIButton buttonWithType:UIButtonTypeRoundedRect] ;//设置按钮的位置btn.frame CGRectMake(100, 100, 100…

UIButton基础知识和自定义详解

UIButton是我们经常用的UI控件&#xff0c;继承UIControl。这里将对UIButton的基本使用方法和自定义UIButton进行详细介绍。 一、UIBUtton基本知识介绍 对于我们学习一个新的控件、无外乎两种方法。第一种是在xcode中的.m文件查看该控件的属性和相关方法&#xff0c;第二种直…

UI基本控件(二):UIButton

UIButton——按钮 作用&#xff1a;用户交互的主要控件&#xff0c;有六种类型&#xff0c;其中自定义类型使用最为普遍 属性&#xff1a; title属性&#xff1a;是按钮的文字 titleColor属性&#xff1a;是按钮的颜色 image属性&#xff1a;是按钮显示的图像 提示&#…