单元测试

单元测试
   1,自动化测试
       1.1通过断言的方式来确定结果是否正确Assert
       1.2引入junit的jar包 不建议直接使用eclipse中提供的包
       1.3创建一个操作类 在src目录下编写服务器代码
           1,导入junit的jar,不建议直接使用eclipse中所提供的包
           2,在src目录下编写服务代码
           3.创建测试类
           基本原则 1.在eclipse中创建一个source folder命名为test
               2,创建一个测试类所在的包,包的名称和要测试的类一致
           4.Junit3和Junit4两者之间区别是非常明显的
           在Junit3中,如果某个类需要是测试类,必须将其继承与TestCase,如果某个方法需要是测试方法,必须让这个方法
           范通过textxx开头,在Junit3中,如果希望指定某个测试方法运行某个初始方法,这个方法名称必须setUp,如
           果希望在某个测试方法运行之后运行某个释放资源的方法,这个方法名称必须testDown
        在Junit4中,一个POJO类就是一个测试类,测试方法通过@Test来标识,初始化方法通过@Before,释放资源的方法通过 @After来
        标注,但是为了让Junit4中的类在Junit3中可以使用,习惯把初始化方法命名为setUp ,释放资源的方法命名为testDown 测试方法同样以test开头
        5, 如果使用断言
        
        hamcrest可以有效增加junit的测试能力,用一些相对通俗的语言来进行测试
        要使用junit中的assertThat来进行断言
        第一个参数表示实际值,第二个参数表示hamcrest的表达式
        
        特别注意,如果使用junit4.10 必须把hamcrest的jar包移到junit的jar之前,否则,组合条件allOf, anyOf都会抛出异常
        
        TestSuite
        可以通过testSuite来组成多个测试组件
        
        正常的开发流程
        编码---》测试-》重复--》提交
        基于测试驱动的开发
        测试-》编写-->重复---》提交
        先写了测试之后,由于测试的覆盖率要求为100%,所以就会让代码中可能存在的分支都进行测试,这样先写测试单元,
        可以为将来的代码提供了一种有效的参考
        
        cobertura使用
        1,将cobertura的路径设置到path中
        2,将要测试的源代码,编译之后的字节码文件和所需要的jar包拷贝到一个单独的目录中做处理
        3,在命令提示符中使用命令为生成测试覆盖报告的代码生成一个ser的文件
        3.1
         cobertura-instrument --destination instrumented  com/test/junit/     
        
        4.基于ser文件运行测试
        4.1java -cp lib/junit-4.10.jar;lib/cobertura.jar;.;instrumented;.;-Dnet.sourceforge.cobertura.datafile=cobertura.ser org.junit.runner.JUnitCore org.konghao.manager.TestUsertManager

        5.根据ser文件生成测试覆盖率的报告
        特别注意:如果文件的编码是utf-8的,在生成报告前需要为coberture-report.bat文件增加DfileEncoding的处理
        
        java -cp "%COBERTURA_HOME%cobertura.jar;%COBERTURA_HOME%lib\asm-3.0.jar;%COBERTURA_HOME%lib\asm-tree-3.0.jar;%COBERTURA_HOME%lib\log4j-1.2.9.jar;%COBERTURA_HOME%lib\jakarta-oro-2.0.8.jar" net.sourceforge.cobertura.reporting.Main %CMD_LINE_ARGS%
        
        
        黑盒测试
        
        白盒测试
        
   2,基于测试开发的方式和优点
   
   3,stub和mock
       mock对象用来测试一些未实现关联对象的类进行测试的对象
       mock和stub的区别
           mock关注的是交互
           stub关注的是状态
           EasyMock就是实现mock对象的框架
               1,导入easymock的jar包    
               2,Mock对象的三个生命周期
                   三个阶段 record  replay verify
                   Mock的关注点是在交互上,注意解决的问题是对象之间的交互,诸如:Service就依赖于DAO,如果DAO没有实现,我们可以通过Mock来模拟DAO的实现
            record阶段就是用来说明这个DAO上面可能存在的值
            
            @Test
    public void testLoad(){
        //1,创建DAO的Mock对象,目前就进入record阶段
        IUserDao ud= EasyMock.createMock(IUserDao.class);
        User u = new User(1,"admin","123","管理员");
        //2,记录ud可能会发生的操作的结果
        /*
         * 以下代码所指的是,当在dao中调用了load方法并且参数为admin的时候,返回值是u对象
         */
        //必须把交互的所有过程记录下来
        EasyMock.expect(ud.load("asd")).andReturn(u);
        ud.delete("abc");
        //以下用来操作没有返回值的方法
        EasyMock.expectLastCall();
        EasyMock.expect(ud.load("admin")).andReturn(u);
        //3进入测试阶段,也就是replay阶段
        EasyMock.replay(ud);
        //创建Service和DAO的关联
        IUserService us = new UserService(ud);
        //完成测试
        User tu = us.load("admin");
        EntitiesHelper.assertUser(tu,u);
        //3,验证交互关系是否正确
        EasyMock.verify(ud);
        
    }
    mock的几种创建方式,
    1,createMock
    通过createMock所创建的mock对象,在进行verify的时候仅仅只是检查关联方法是否正确完成调用,如果完成次数一致
    就认为测试通过,不考虑顺序问题
      public void testLoadMock(){
        //创建DAO的对象,目前就进入record阶段
        IUserDao ud = EasyMock.createMock(IUserDao.class);
        User u = new User(1,"admin","123","管理员");
        EasyMock.expect(ud.load("asd")).andReturn(u);
        //使用的CreateMock,如果方法的调用顺不一致,不会抛出异常
        ud.delete("abc");
        EasyMock.expectLastCall();
        EasyMock.expect(ud.load("admin")).andReturn(u);
        EasyMock.replay(ud);
        //创建Service和Dao关联
        IUserService us = new UserService(ud);
        //完成测试
        User tu = us.load("admin");
        EntitiesHelper.assertUser(tu,u);
        //验证交互关系是否正确
        EasyMock.verify(ud);
    }
    2,createSrtictMock
    在verify时不仅仅验证关联方法的调用此时还要验证顺序
    public void testLoadStrictMock(){
        //创建DAO的Mock对象,目前就进去了record阶段
        IUserDao ud = EasyMock.createStrictMock(IUserDao.class);
        User u = new User(1,"admin","123","管理员");
        EasyMock.expect(ud.load("asd")).andReturn(u);
        //使用的CreateStrictMock,方法的顺序不一致,所以会抛出异常
        ud.delete("abc");
        EasyMock.expectLastCall();
        EasyMock.expect(ud.load("admin")).andReturn(u);
        EasyMock.replay(ud);
        //关系serviceDao
        IUserService us = new UserService(ud);
        //完成测试
        User tu = us.load("admin");
        EntitiesHelper.assertUser(tu,u);
        //3,验证交互关系是否正确
        EasyMock.verify(ud);
    }
                               
   4,在容器中测试
     4.1,jetty
     4.2 cactus 可以完成模拟J2EE的容器测试
             可以测试servlet jsp filter 和EJB
     cactus注意是基于junit3.8来进行操作的,并不支持junit4中的annotaion
          搭建环境
          导入包 aspectjrt-1.5.3.jar  
          cactus.core.framework.uberjar.javaEE.14-1.8.1.jar
          cactus.integration.ant-1.8.1.jar
          cactus.integration.shared.api-1.8.1.jar
          commons-discovery-0.4.jar
          commons-httpclient-3.1.jar
          commons-logging-1.1.jar
          geronimo-j2ee-management_1.0_spec-1.1.jar
        httpunit-1.6.jar
        servlet-api-2.4.jar
        org.mortbay.jetty-5.1.9.jar
        commons-codec-1.7.jar
        cargo-core-uberjar-1.0-beta-2.jar
        cargo-core-container-jonas-1.0-beta-2.jar
        创建servlet的测试类
   5.dbUnit
       dbunit具体隔离数据库的访问,
         1导入jar包
           dbunit.jar
           slf4j.jar(一定使用1.6的版本)
         2,创建dbunit的测试数据xml文件
         <?xml version="1.0" encoding="UTF-8"?>
            <dataset>
                <!--  <t_user>
                    <id>1</id>
                    <username>kh</username>
                    <password>123</password>
                    <nickname>孔浩</nickname>
                </t_user>-->
                <t_user id="1" username="admin" password="123" nickname="超级管理员"></t_user>
            </dataset>
         3,创建dbunit的Connection
         dbunit的connection是用来对数据文件进行操作的,这个connection必须依赖于目前项目中所使用的connection
        IDatabaseConnection com = new DatabaseConnection(DbUtil.getConnection());         
     4.创建IDdataSet,通过DATASET来获取测试数据
                 /**
             * FlatXmlDataSet 用来获取基于属性存储的属性值
             * XMLDateSet用来获取基于节点类型存储的属性值
             */
            IDataSet ds = new FlatXmlDataSet(
                    new FlatXmlProducer(
                    new InputSource(
                    TestDbUnit.class.getClassLoader().getResourceAsStream("t_user.xml"))));
     
     5.初始化数据并且完成测试
             //从DAO中获取数据并且完成测试
            IUserDao ud = new UserDao();
            User tu = ud.load("admin");
            assertEquals(tu.getId(), 1);
            assertEquals(tu.getUsername(), "admin");
            assertEquals(tu.getPassword(), "123");
            assertEquals(tu.getNickname(), "超级管理员");
            
     6. 备份
     
     @Test
    public void testBackup(){
        //超级dbunit的Connection 需要插入一个数据的connection作为参数
        try {
            DatabaseConnection con = new DatabaseConnection(DbUtil.getConnection());
            //根据con创建相应的dataset,这个dataset包含了所有表
            IDataSet ds = con.createDataSet();
            //将ds中的数据通过FlatXmlDataSet的格式写到文件中
            FlatXmlDataSet.write(ds, new FileWriter("D:/android_app/junit/junit01/test.xml"));
        } catch (DatabaseUnitException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    以上演示的是备份数据库的所有文件
    
    备份某些特定的表
    
    @Test
    public void testBackUpTable(){
        try {
            //创建dbunit的Connection ,需要传入一个数据库的connection作为参数
            IDatabaseConnection con = new DatabaseConnection(DbUtil.getConnection());
            //通过QueryDataSet可以有效的选择要处理的表来作为数据集
            QueryDataSet backup = new QueryDataSet(con);
            //添加t_user这张表作为备份表
            backup.addTable("t_user");
            FlatXmlDataSet.write(backup, new FileWriter("D:/android_app/junit/junit01/test1.xml"));
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (DatabaseUnitException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值