Java单元测试之容器内部测试

发表于:2020-8-28 11:07

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:顾翔    来源:51Testing软件测试网原创

  1、HttpUnit
  HttpUnit是一个集成测试工具,主要关注Web应用的测试,提供的帮助类让测试者可以通过Java类和服务器进行交互,并且将服务器端的响应当作文本或者DOM对象进行处理。HttpUnit还提供了一个模拟Servlet容器,让你可以不需要发布Servlet,就可以对Servlet的内部代码进行测试。本文中作者将详细的介绍如何使用HttpUnit提供的类完成集成测试。
  HttpUnit简介
  HttpUnit是SourceForge下面的一个开源项目,它是基于JUnit的一个测试框架,主要关注于测试Web应用,解决使用JUnit框架无法对远程Web内容进行测试的弊端。当前的最新版本是1.5.4。为了让HtpUnit正常运行,你应该安装JDK1.3.1或者以上版本。
  工作原理
  HttpUnit通过模拟浏览器的行为,处理页面框架(frames),cookies,页面跳转(redirects)等。通过HttpUnit提供的功能,你可以和服务器端进行信息交互,将返回的网页内容作为普通文本、XML Dom对象或者是作为链接、页面框架、图像、表单、表格等的集合进行处理,然后使用JUnit框架进行测试,还可以导向一个新的页面,然后进行新页面的处理,这个功能使你可以处理一组在一个操作链中的页面。
  和其他商业工具的对比
  商业工具一般使用记录、回放的功能来实现测试,但是这里有个缺陷,就是当页面设计被修改以后,这些被记录的行为就不能重用了,需要重新录制才能继续测试。
  举个例子:如果页面上有个元素最先的设计是采用单选框,这个时候你开始测试,那么这些工具记录的就是你的单项选择动作,但是如果你的设计发生了变化,比如说我改成了下拉选择,或者使用文本框接受用户输入,这时候,你以前录制的测试过程就无效了,必须要重新录制。
  而HttpUnit因为关注点是这些控件的内容,所以不管你的外在表现形式如何变化,都不影响你已确定测试的可重用性。
  更多的关于httpunit的信息请访问httpunit的主页http://httpunit.sourceforge.net。
  案例如下:
  package HttpUnit.com.jerry;
  
  
  import static org.junit.Assert.*;
  
  
  import java.io.IOException;
  
  
  import org.junit.Before;
  import org.junit.Test;
  import org.xml.sax.SAXException;
  
  
  import com.meterware.httpunit.GetMethodWebRequest;
  import com.meterware.httpunit.HttpUnitOptions;
  import com.meterware.httpunit.PostMethodWebRequest;
  import com.meterware.httpunit.WebConversation;
  import com.meterware.httpunit.WebLink;
  import com.meterware.httpunit.WebRequest;
  import com.meterware.httpunit.WebResponse;
  
  
  public class WebTest {
    private  WebConversation wc;
    @Before
    public void setUp(){
      wc = new WebConversation();
    }
  
  
    @Test
    public void testEBusiness() throws IOException, SAXException {
      HttpUnitOptions.setScriptingEnabled(false);
      String username = "cindy";
      String password = "123456";
      WebRequest req = new PostMethodWebRequest("http://127.0.0.1:8000/login_action/");
      //给请求加上参数
      req.setParameter("username",username);
      req.setParameter("password",password);
      //获取响应对象
      WebResponse resp = wc.getResponse(req);
      //用getText方法获取相应的全部内容
      assertTrue(resp.getText().contains("购物车"));
    }
    
    @Test
    public void test3testing() throws IOException, SAXException {
      HttpUnitOptions.setScriptingEnabled(false);
      String CheckWord = "测试";
      WebResponse req = wc.getResponse("http://www.3testing.com/include/head.htm");
      WebLink link = req.getLinkWith("我的课程");
      link.click();
      WebResponse nextLink = wc.getCurrentPage();
      assertTrue(nextLink.getText().contains(CheckWord));
    }
  
  }
  2、DbUnit
  DbUnit设计理念
  熟悉单元测试的开发人员都知道,在对数据库进行单元测试时候,通常采用的方案有运用模拟对象(mock objects)和stubs两种。通过隔离关联的数据库访问类,比如JDBC的相关操作类,来达到对数据库操作的模拟测试。然而某些特殊的系统,比如利 用了EJB的CMP(container-managed persistence)的系统,数据库的访问对象是在最底层而且很隐蔽的,那么这两种解决方案对这些系统就显得力不从心了。
  DBUnit的设计理念就是在测试之前,备份数据库,然后给对象数据库植入我们需要的准备数据,最后,在测试完毕后,读入备份数据库,回溯到测试前的状态;而且又因为DBUnit是对JUnit的一种扩展,开发人员可以通过创建测试用例代码,在这些测试用例的生命周期内来对数据库的操作结果进行比较。
  DbUnit测试基本概念和流程
  基于DbUnit 的测试的主要接口是IDataSet。IDataSet代表一个或多个表的数据。
  可以将数据库模式的全部内容表示为单个IDataSet 实例。这些表本身由Itable 实例来表示。
  ·IDataSet 的实现有很多,每一个都对应一个不同的数据源或加载机制。最常用的几种 IDataSet实现为:
  ·FlatXmlDataSet:数据的简单平面文件 XML 表示 
  ·QueryDataSet:用 SQL 查询获得的数据 
  ·DatabaseDataSet:数据库表本身内容的一种表示 
  ·XlsDataSet :数据的excel表示
  ·DBUnit支持的数据库包括,db2,h2,hsqldb,mckoi,mssql,mysql,netezza,oralce,postgresql.
  DBUnit测试流程
  1.一般而言,使用DbUnit进行单元测试的流程如下:
  2.根据业务,做好测试用的准备数据和预想结果数据,通常准备成xml格式文件。
  3.在setUp()方法里边备份数据库中的关联表。
  4.在setUp()方法里边读入准备数据。
  5.对测试类的对应测试方法进行实装:执行对象方法,把数据库的实际执行结果和预想结果进行比较。
  6.在tearDown()方法里边,把数据库还原到测试前状态。
  案例如下:
  AbstractDbUnitTestCase.java
  package DbUnit.com.jerry;
  
  
  import static org.junit.Assert.*;
  
  
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.Reader;
  import java.sql.Connection;
  import java.sql.DriverManager;
  
  
  import org.dbunit.dataset.IDataSet;
  import org.dbunit.dataset.ReplacementDataSet;
  import org.dbunit.dataset.xml.FlatXmlDataSet;
  import org.dbunit.ext.hsqldb.HsqldbConnection;
  import org.junit.AfterClass;
  import org.junit.BeforeClass;
  
  
  public abstract class AbstractDbUnitTestCase {
    
    public static final String USER_FIRST_NAME = "Jeffrey";
    public static final String USER_LAST_NAME = "Lebowsky";
    public static final String USER_USERNAME = "ElDuderino";
    
    protected static UserDaoJdbcImpl dao = new UserDaoJdbcImpl();
    protected static Connection connection;
    protected static HsqldbConnection dbunitConnection;
    
    @BeforeClass
    public static void setupDatabase() throws Exception {
    String driverName="com.mysql.jdbc.Driver";
    String userName="root";
    String userPasswd="123456";
    String dbName="hr";
    String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&password="+userPasswd;
      Class.forName(driverName).newInstance(); 
      connection = DriverManager.getConnection(url);
      dbunitConnection = new HsqldbConnection(connection,null);
      dao.setConnection(connection);
      dao.createTables();
    }
  
  
    @AfterClass
    public static void closeDatabase() throws Exception {
      if ( dbunitConnection != null ) {
        dao.dropTables();
        dbunitConnection.close();
        dbunitConnection = null;
      }
    }
    
    public static IDataSet getDataSet(String name) throws Exception {
      InputStream inputStream = new FileInputStream(name);
      assertNotNull("file " + name + " not found in classpath", inputStream );
      Reader reader = new InputStreamReader(inputStream);
      FlatXmlDataSet dataset = new FlatXmlDataSet(reader);
      return dataset;
    }
    
    public static IDataSet getReplacedDataSet(String name, long id) throws Exception {
      IDataSet originalDataSet = getDataSet(name);
      return getReplacedDataSet(originalDataSet, id);
    }
    
    public static IDataSet getReplacedDataSet(IDataSet originalDataSet, long id) throws Exception {
      ReplacementDataSet replacementDataSet = new ReplacementDataSet(originalDataSet);
      replacementDataSet.addReplacementObject("[ID]", id);
      replacementDataSet.addReplacementObject("[NULL]", null);
      return replacementDataSet;
    }
    
    public static User newUser() {
        User user = new User();
        user.setFirstName(USER_FIRST_NAME);
        user.setLastName(USER_LAST_NAME);
        user.setUsername(USER_USERNAME);
        return user;
      }
    
    public static void assertUser(User user) {
        assertNotNull(user);
        assertEquals(USER_FIRST_NAME, user.getFirstName());
        assertEquals(USER_LAST_NAME, user.getLastName());
        assertEquals(USER_USERNAME, user.getUsername());
      }
      
  }
  UserDaoJdbcImplTest.java
  package DbUnit.com.jerry;
  
  
  import static org.junit.Assert.*;
  
  
  import org.dbunit.Assertion;
  import org.dbunit.dataset.IDataSet;
  import org.dbunit.operation.DatabaseOperation;
  import org.junit.Test;
  
  
  public class UserDaoJdbcImplTest extends AbstractDbUnitTestCase{
    
    @Test
    public void testGetUserById() throws Exception {
      IDataSet setupDataSet = getDataSet("Test/DbUnit/com/jerry/user.xml");
      DatabaseOperation.CLEAN_INSERT.execute(dbunitConnection, setupDataSet);
      User user = dao.getUserById(1);
      assertNotNull( user);
      assertEquals( "Jeffrey", user.getFirstName() );
      assertEquals( "Lebowsky", user.getLastName() );
      assertEquals( "ElDuderino", user.getUsername() );
    }
  
  
    
    @Test
    public void testAddUseIgnoringId() throws Exception {
      IDataSet setupDataSet = getDataSet("Test/DbUnit/com/jerry/user.xml");
      DatabaseOperation.DELETE_ALL.execute(dbunitConnection, setupDataSet);
      User user = newUser();
      int id = dao.addUser(user);
      assertTrue(id>0);
      IDataSet expectedDataSet = getDataSet("Test/DbUnit/com/jerry/user.xml");
      IDataSet actualDataSet = dbunitConnection.createDataSet();
      Assertion.assertEqualsIgnoreCols( expectedDataSet, actualDataSet, "users", new String[] { "id" } );
    }
    
    @Test
    public void testGetUserByIdReplacingIds() throws Exception {
    int id = 42;
      IDataSet setupDataset = getReplacedDataSet("Test/DbUnit/com/jerry/user-token.xml", id );
      DatabaseOperation.INSERT.execute(dbunitConnection, setupDataset);
      User user = dao.getUserById(id);
      assertUser(user);
    }
    
    @Test
    public void testAddUserReplacingIds() throws Exception {
      IDataSet setupDataSet = getDataSet("Test/DbUnit/com/jerry/user-token.xml");
      DatabaseOperation.DELETE_ALL.execute(dbunitConnection, setupDataSet);
      User user = newUser();
      int id = dao.addUser(user);
      assertTrue(id>0);
      IDataSet expectedDataSet = getReplacedDataSet(setupDataSet, id );
      IDataSet actualDataSet = dbunitConnection.createDataSet();
      Assertion.assertEquals( expectedDataSet, actualDataSet );
    }
    
  }
  user-token.xml
  <?xml version="1.0"?>
  <dataset>
    <users id="[ID]" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
  </dataset>
  user.xml
  <?xml version="1.0"?>
  <dataset>
    <users id="1" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
  </dataset>

  本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号