当前位置:   article > 正文

【软件测试】JUnit 单元测试 基础学习教程

junit

目录

一、什么是单元测试

二、为什么要使用单元测试

1、使用main0方法测试的缺点

2、单元测试的好处

三、 JUnit 单元测试框架介绍

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

2、 JUnit 的特点

四、JUnit 设计

1、Assert 断言常用方法:

五、使用JUnit测试方法

1、示例程序

六、总结

JUnit 单元测试实战

一、使用@ Before 和@ After

示例代码

二、使用@BeforeCss 和@ AfterClass 静态方法(过程)

示例代码

三、@ Before 、@ After 、@ BeforeClass 、@ AfterClass 使用场景

四、总结

异常测试

1、对可能抛出的异常进行测试:

2、如何测试异常

总结

示例程序一

测试程序二

超时测试

程序示例一

测试程序二

参数化测试

1、参数化测试

2、参数化测试要求

示例程序


一、什么是单元测试

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

二、为什么要使用单元测试

1、使用main方法测试的缺点

  • 只能有一个 main ()方法,不能把测试代码分离;
  • 没有打印出测试结果和希望结果;
  • 需要一种测试框架,帮我们编写测试。

2、单元测试的好处

  • 确保单个方法运行正常;
  • 如果修改了代码,只需要确保其对应的单元测试通过。
  • 测试代码本身就可以作为实例代码;
  • 可以自动化运行所有测试并获得报告。

三、 JUnit 单元测试框架介绍

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

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

2、 JUnit 的特点

  • 使用断言( Assertion )测试期望结果;﹣可以方便地组织和运行测试
  • 可以方便地查看测试结果
  • 常用 IDE (例如 IntelliJ ldea 、 eclipse )都集成了 JUnit
  • 可以方便地集成到 Maven 。

四、JUnit 设计

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

1、Assert 断言常用方法:

  • 断言相等: assertEquals (100, X );
  • 断言数组相等: assertArrayEquals ((1,2,3, X );
  • 浮点数断言相等:0 assertEquals (3.1416, X , 0.0001);
  • 断言为 nul:assertNull ( X );
  • 断言为 true / false:assertTrue ( x >0 ) / assertFalse ( x < 0 )
  • 其它:assertNotEquals / assertNotNull

五、使用JUnit测试方法

1、示例程序

  1. public class Demo01 {
  2.        public String sum(String d,int...arg){
  3.               int ss=Integer.parseInt(d.trim());
  4.               int sum=0;
  5.               for(int i=0;i<arg.length;i++){
  6.                      sum=sum+arg[i];
  7.               }
  8.               return sum+""+ss;
  9.        }
  10. }

对于以上这个用于测试的程序而言,我们要测试它,最土的方法就是使用main函数,如下图所示:

下面我们讨论一下使用JUnit进行测试的方法:(使用eclipse)

1、首先要建立一个JUnit的测试包

2、建立测试项目:

3、选择存放目录和确定文件名

4、选择要进行测试的方法

5、使用断言和更改测试的方法的参数

6、运行结果

7、使用多个@Test测试

  1. @Test
  2. public void testSum() {
  3.         assertEquals("125", new Demo01().sum("5", 2,4,6));
  4.         assertEquals("127", new Demo01().sum("7", 2,4,6));
  5. }
  6. @Test
  7. public void test02() {
  8.         assertEquals("127", new Demo01().sum(" 7", 2,4,6));
  9. }

8、修改主方法

  1. package com.dw.service
  2. public class Demo01 {
  3. public String sum(String d, int...arg){
  4. int ss = Integer.parseInt(d.trim());
  5. int sum = 0;
  6. for(int i = 0; i < arg.length; i++){
  7. sum = sum + arg[i];
  8. }
  9. return sum + "" + ss;
  10. }
  11. }

六、总结

  1. 一个 TestCase 包含一组相关的测试方法;
  2. 使用断言测试结果(注意浮点数 assertEquals 要指定 delta )
  3. 每个测试方法必须完全独立;
  4. 测试代码必须非常简单;
  5. 不能为测试代码再编写测试
  6. 测试需要覆盖各种输入条件,特别是边界条件。

JUnit 单元测试实战

一、使用@Before和@After

同一个单元测试内的多个测试方法:测试前都需要初始化某些对象,测试后可能需要清理资源; Junit 使用@Before和@After可以实现,在@Before方法中初始化测试资源,在@After方法中释放测试资源。

JUnit 对每个@Test 方法:(执行过程)

  1. 实例化测试用例;
  2. 执行@ Before 方法;
  3. 执行@ Test 方法;
  4. 执行@ After 方法。

注意:使用@Before 和@After 可以保证:

  • 单个@Test 方法执行前会创建新的 XxxTest 实例;实例变量的状态不会传递给下一个@ Test 方法。
  • 单个@Test 方法执行前后会执行@ Before和@ After方法。

示例代码

  1. import org.junit.After;
  2. import org.junit.Before;
  3. import org.junit.Test;
  4. public class demoTest {
  5.    
  6.     public DemoTest() {
  7.         System.out.println("Demotest对象创建");
  8.     }
  9. @Before
  10. public void before() {
  11.     System.out.println("beforeTest方法执行");
  12.     }
  13. @Test
  14. public void test01() {
  15.       System.out.println("test01方法执行......");
  16. }
  17.   @Test
  18.  public void test02() {
  19.      System.out.println("test02方法执行......");
  20. }
  21.   @Test
  22.   public void test03() {
  23.      System.out.println("test03方法执行......");
  24. }
  25.   @After
  26.   public void after() {
  27.       System.out.println("after方法执行......");
  28.      }
  29. }

运行结果:

我们可以用@Before创建对象demo,那么每一次@test的执行都会执行@Before下的对象的创建。每一个test都是一个独立的单元,然后再使用@After销毁对象,释放资源。

二、使用@BeforeCss @AfterClass 静态方法(过程)

  1. 在执行所有@Test 方法前执行@Beforedass 标注的静态方法;
  2. 执行所有测试
  3. 在执行所有@Test 方法后执行@AfterClass 静态方法。

注意:@BeforeClass 静态方法初始化的对象只能存放在静态字段中,静态字段的状态会影

响到所有的@Test 。

示例代码

  1. import org.junit.AfterClass;
  2. import org.junit.BeforeClass;
  3. import org.junit.Test;
  4. public class DemoTest02 {
  5.     public DemoTest02() {
  6.         System.out.println("Demotest对象创建");
  7.     }
  8.     @BeforeClass
  9.     public static void beforeClass() {
  10.         System.out.println("beforeClass方法执行");
  11.     }
  12.     @Test
  13.     public void test01() {
  14.         System.out.println("test01方法执行......");
  15.     }
  16.     @Test
  17.     public void test02() {
  18.         System.out.println("test02方法执行......");
  19.     }
  20.     @Test
  21.     public void test03() {
  22.         System.out.println("test03方法执行......");
  23.     }
  24.     @AfterClass
  25.     public static void afterclass() {
  26.         System.out.println("afterclass方法执行......");
  27.     }
  28. }

执行结果:

  1. beforeClass方法执行
  2. Demotest对象创建
  3. test01方法执行......
  4. Demotest对象创建
  5. test02方法执行......
  6. Demotest对象创建
  7. test03方法执行......
  8. afterclass方法执行......

在这个结果中,@Beforeclass@Afterclass就只执行了一次,且@Beforeclass的执行早于@Demotest对象创建的执行。类中所有的方法或对象共享。而@Beforet @After是成员对象所独享的。所有@test都会共享@Beforeclass里面的内容。我们可以在@Beforeclass中申明一个对象,这个对象可以在各@Test中使用。

三、@Before @After @BeforeClass @AfterClass 使用场景

  • @Before:初始化测试对象;例如: input = new FilelnputStream();
  • @After:销毁@ Before 创建的测试对象;例如: input .Close();
  • @BeforeClass:初始化非常耗时的资源,例如:创建数据库。
  • @AfterClass:清理@ BeforeClass 创建的资源,例如:删除数据库。

四、总结

理解 JUnit 执行测试的生命周期

  1. @Before 用于初始化测试对象,测试对象以实例变量存放;
  2. @After 用于清理@ Before 创建的对象;
  3. @BeforeClass 用于初始化耗时资源,以静态变量存放;
  4. @AfterClass 用于清理@ BeforeClass 创建的资源。

异常测试

1、对可能抛出的异常进行测试:

异常本身是方法签名的一部分。

public static int parselnt() throws NumberFormatException

 测试错误的输入是否导致特定的异常。

  1. Integer.parselnt ( null );
  2. Integer.parselnt (“”);
  3. Integer.parselnt (“ xyz”);

2、如何测试异常

我们可以通过 try - catch测试,但这样会写出很多这样的语句,从而使其变得复杂起

来;更好的方法就是使用 expected 测试异常,具体操作如下:

  1. @Test( expected = NumberFormatException.class )
  2. public void testNumberFormat (){
  3.   Integer . parseInt ( null);
  4. //如果测试过程中抛出了以上异常,则测试通过。
  5. }

总结

  1. 测试异常可以使用@Test ( expected = Exception. class )
  2. 对可能发生的每种类型的异常进行测试。

示例程序一

  1. public class Demo03 {
  2.     public void testNumberFormat(String num){
  3.         Integer.parseInt(num);
  4.     }
  5.    public void testExtends() {
  6.        Object msg=null;
  7.        System.out.println(msg.toString());
  8.    }
  9. }

测试程序二

  1. import static org.junit.jupiter.api.Assertions.*;
  2. import org.junit.Before;
  3. import org.junit.jupiter.api.Test;
  4. import static org.junit.jupiter.api.Assertions.*;
  5. import org.junit.Before;
  6. import org.junit.jupiter.api.Test;
  7. public class Demo03Test {
  8.     Demo03 d2;
  9.     @Before
  10.     public void before() {
  11.     d2=new Demo03();
  12.     }
  13.     @Test( expected = NumberFormatException.class )
  14.     public void testTestNumberFormat() {
  15.         d2.testNumberFormat("abc");
  16.     }
  17. //如果出现运行通过,表示出现异常。如果输入12,则运行不通过,表示没有出现异常。
  18. @Test( expected = NumberFormatException.class )
  19.     public void testTestExtends() {
  20.         d2.testExtends();
  21.     }
  22.     //空指针异常
  23. }

超时测试

可以为 JUnit 的单个测试设置超时

超时设置为1秒:@Test ( timeout =1000)【 timeout 单位是毫秒】

强调:如果测试方法执行时间小于超时设置的时间,测试通过,反之不通过。

注意:超时测试不能取代性能测试和压力测试。

程序示例一

  1. public class Demo04 {
  2.     public int culate() {
  3.         int b=100;
  4.         int sum=0;
  5.         for(int i=1;i<=100;i++) {
  6.             sum=sum+i;
  7.         }
  8.         return sum;
  9.     }
  10. public int culate02(){
  11. int b=500;
  12. int sum=0;
  13. for(int i=1;i<=100;i++) {
  14. sum=sum+i;
  15. }
  16.       try {
  17.           Thread.sleep(1000);
  18.       } catch(InterruptedException e) {
  19.           //TODD Auto-generated catch block
  20.           e.printStackTrace();
  21.       }
  22.       return sum;
  23.   }
  24. }

测试程序二

  1. import static org.junit.jupiter.api.Assertions.*;
  2. import org.junit.Before;
  3. import org.junit.jupiter.api.Test;
  4. import org.junit.jupiter.api.Timeout;
  5.   public class Demo04Test {
  6.    Demo04 d4;
  7.    @Before
  8.    public void before() {
  9.        d4=new Demo04();
  10.    }
  11.    @Test
  12.    @Timeout(600)
  13.    public void testCulate(){
  14.       d4.culate();
  15.    }
  16.    @Test
  17.    @Timeout(600)
  18.    public void testCulate02() {
  19.       d4.culate02();
  20.    }
  21. }

参数化测试

1、参数化测试

如果待测试的输入和输出是一组数据,可以把测试数据组织起来,用不同的测试数据调用相同的测试方法。

2、参数化测试要求

  1. 参数必须有静态方法 data()返回,返回类型为 Collection <?> ,静态方法必须标记为
  2. @Parameters ;
  3. 测试类必须标记为:@RunWith ( Parameterized.class );
  4. 构造方法参数必须和测试参数对应。

示例程序

  1. @RunWith(Parameterized.class)/
  2. public class  Demo05Test{
  3.    @Parameters
  4.    public static Collection<?> data() {
  5.       return Arrays.asList(new Object[][]{{0,0},{1,1}, {-1,1}});
  6.    }
  7. //这是一种固定的结构,我们要做的就是改变其中的数组的参数值。其它的部分//都不能改变
  8.    int input;
  9.    int expected;
  10. // 参数必须要对应;
  11.    public Demo05Test(int input, int expected) {
  12.       this.input = input;
  13.       this.expected = expected;
  14.    }
  15.    @Test
  16.    public void Test() {
  17.       int r=Math.abs(this.input);//绝对值
  18.       assertEquals(this.expected, r);
  19.    }
  20. //对应这三组数据会执行三次
  21. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/876428
推荐阅读
相关标签
  

闽ICP备14008679号