单元/接口测试常用测试框架+相关其他

Spring Framework (spring框架)

Spring Framework 是一个开源的JavaJava EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于Expert One-on-One Java EE Design and DevelopmentISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

Spring 中包含的关键特性

  • 强大的基于 JavaBeans 的采用控制翻转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。
  • 数据库事务的一般化抽象层,允许声明式(Declarative)事务管理器,简化事务的划分使之与底层无关。
  • 内建的针对 JTA 和 单个 JDBC 数据源的一般化策略,使 Spring 的事务支持不要求 Java EE 环境,这与一般的 JTA 或者 EJB CMT 相反。
  • JDBC 抽象层提供了有针对性的异常等级(不再从SQL异常中提取原始代码),简化了错误处理,大大减少了程序员的编码量。再次利用JDBC时,你无需再写出另一个 '终止' (finally) 模块。并且面向JDBC的异常与Spring 通用数据访问对象(Data Access Object)异常等级相一致。
  • 以资源容器,DAO 实现和事务策略等形式与HibernateJDO 和iBATIS SQL Maps 集成。利用众多的翻转控制方便特性来全面支持,解决了许多典型的Hibernate集成问题。所有这些全部遵从Spring通用事务处理和通用数据访问对象异常等级规范。
  • 灵活的基于核心 Spring 功能的 MVC 网页应用程序框架。开发者通过策略接口将拥有对该框架的高度控制,因而该框架将适应于多种呈现(View)技术,例如 JSPFreeMarkerVelocityTilesiText 以及 POI。值得注意的是,Spring 中间层可以轻易地结合于任何基于 MVC 框架的网页层,例如 StrutsWebWork,或Tapestry

在设计应用程序Model时,MVC 模式(例如Struts)通常难于给出一个简洁明了的框架结构。Spring却具有能够让这部分工作变得简单的能力。程序开发员们可以使用Spring的 JDBC 抽象层重新设计那些复杂的框架结构。


控制反转:---------------------------------------------------------------------------------------------

也称为依赖注入,面向对象编程的一种设计原则。降低计算机代码之间的耦合度


关于依赖

[plain]  view plain  copy
  1. Class X 依赖于 class Y 只在如下状况中成立:  
  2.   
  3.     X 拥有 Y 的控制并且在 X 中使用 Y  
  4.     X 是 Y 的派生物  
  5.     X 依赖于 Z,而 Z 又依赖于 Y (transitivity)  
  6.   
  7. X 依赖于 Y 并不表示 Y 也依赖于 X。但如果 X 和 Y 同时依赖于对方,这种依赖性被称作 循环依赖:这时,X 无法和 Y 分开单独使用,反之亦然。如果在一个面对对象程序中拥有太多的循环依赖,这可能表示这个程序是个欠佳的设计。  

打破依赖 -- 控制翻转 -- 依赖注入

[plain]  view plain  copy
  1. 如果实例对象x,调用了类Y的实例对象y的方法, 成为 对象x依赖于 对象y  
  2.   
  3. 为了消除这种依赖,进入第三方类(接口)。  
  4.   
  5. 接口中定义x调用的Y中所有方法。  
  6.   
  7. Y类实现接口类。  
  8.   
  9. x不再调用Y类的方法,改为调用接口中的方法。  
  10.   
  11. 这样,XY之间的依赖关系不存在,XY都依赖于接口。  


Spring框架简介

http://www.ibm.com/developerworks/cn/java/wa-spring1/

-------------------------------------------------------------------------------------------------------------------

Spring 2.5 TestContext 测试框架

用于测试基于 Spring 的程序,TestContext 测试框架和低版本 Spring 测试框架没有任何关系,是一个全新的基于注解的测试框架,为 Spring 推荐使用该测试框架。----本来是为了测试基于Spring的应用程序而开发的,其实在非Spring程序测试中一样可以运用它、

1.需要测试的类

2.放在类路径下的applicationContext.xml :Spring配置文件        -----(基本配置文件:src/test/resources/applicationContext.xml

jdbc配置文件:src/test/resources/jdbc.properties

数据源配置文件:src/test/resources/datasource-item.xml

3.编写基于注解的测试用例(测试类要继承Spring提供的AbstractTransactionalJunit4SpringContestTests的抽象测试类   - - 这测试类名字真长!)

---该抽象测试类得作用是,让TestContext测试框架可以在JUnit4.4测试框架的基础上运行起来


[java]  view plain  copy
  1. package com.baobaotao.service;  
  2.   
  3. import org.springframework.test.context.junit4.  
  4.     AbstractTransactionalJUnit4SpringContextTests;  
  5. import org.springframework.test.context.ContextConfiguration;  
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7. import org.junit.Test;  
  8. import com.baobaotao.domain.User;  
  9.   
  10. import java.util.Date;  
  11.   
  12. @ContextConfiguration  //①引入Spring配置文件  
  13. public class TestUserService extends   
  14.     AbstractTransactionalJUnit4SpringContextTests {  
  15.      
  16. @Autowired  //②自动转配bean,当Spring容易启动是,将扫描Spring容器的所有Bean,当发现Bean中拥有@Autowired注释时就找到和其匹配的Bean,注入到对应的地方  
  17.    private UserService userService;  
  18.   
  19.    @Test  //③  
  20.    public void handleUserLogin(){  
  21.        User user = new User();  
  22.        user.setUserId(1);  
  23.        user.setLastIp("127.0.0.1");  
  24.        Date now = new Date();  
  25.        user.setLastVisit(now.getTime());  
  26.        userService.handleUserLogin(user);  
  27.    }  
  28. }  

在 ① 处,标注了一个类级的 @ContextConfiguration 注解

这里 Spring 将按 TestContext 契约查找 classpath:/com/baobaotao/service/TestUserService-context.xml 的 Spring 配置文件,并使用该配置文件启动 Spring 容器。@ContextConfiguration 注解有以下两个常用的属性:

  • locations:可以通过该属性手工指定 Spring 配置文件所在的位置,可以指定一个或多个 Spring 配置文件。如下所示:

    @ContextConfiguration(locations={“xx/yy/beans1.xml”,” xx/yy/beans2.xml”})

  • inheritLocations:是否要继承父测试用例类中的 Spring 配置文件,默认为 true。如下面的例子:
[java]  view plain  copy
  1. @ContextConfiguration(locations={"base-context.xml"})  
  2.  public class BaseTest {  
  3.      // ...  
  4.  }  
  5.  @ContextConfiguration(locations={"extended-context.xml"})  
  6.  public class ExtendedTest extends BaseTest {  
  7.      // ...  
  8.  }  

如果 inheritLocations 设置为 false,则 ExtendedTest 仅会使用 extended-context.xml 配置文件,否则将使用 base-context.xml 和 extended-context.xml 这两个配置文件。

② 处的 @Autowired 注解让 Spring 容器自动注入 UserService 类型的 Bean。

③ 处标注的 @Test 注解则让 handleUserLogin() 方法成为一个 JUnit 4.4 标准的测试方法, @Test 是 JUnit 4.4 所定义的注解。


4.测试类所引用的Spring配置

5.准备测试数据并检测运行结果

在 TestContext 中,你可以通过使用 JUnit 4.4 的 @Before 注解达到这个目的


理解TestContext的博文:

http://www.uml.org.cn/j2ee/200905075.asp

http://shenzhenchufa.blog.51cto.com/730213/342851

http://www.ibm.com/developerworks/cn/java/j-lo-spring25-test/


junit单元测试框架-------------------------------------------------------------------------------------

1.使用junit,测试代码和业务代码分离。

2.下载junit,配置环境变量,classpath

3.使用junit  --no1,编写测试类,使其继承TestCase(junit4不需要继承TestCase)

no2 ,编写测试方法,testXXXX的方式来命名测试方法(junit4可以随便命名测试方法名)

no3,编写断言。清理数据

-----------------------------------

junit4新特性:

|----junit4是不需要继承TestCase的,但并不是说TestCase类就没有用了,它仍然是JUnit工作的基础。但需要import org.junit.Assert来实现断言  

       TestCase类正是通过runBare实现了在测试方法前初始化相关变量和环境,在测试方法后销毁相关变量和环境

|----以前,JUnit使用SetUp和TearDown方法来进行初始化和销毁动作,JUnit 4.0以上版本将不再强制使用SetUp和TearDown方法来进行初始化和

       销毁,而是使用@Before 和@After 来进行。

|----初始化和销毁都是针对一个方法来说的,每个方法执行前都要进行初始化,执行完毕都要进行销毁。而JUnit的最新版本则提供了新的特性,

       针对类进行初始化和销毁。也就是说,该类中的方法只进行一次初始化和销毁,方法就是使用@BeforeClass和@AfterClass

|-----以前,使用JUnit进行单元测试时,如果遇到异常情况,需要使用try…catch的形式来捕捉异常。junit4使用 

        @Test(expected=异常类.class) 来判断异常



SimpleJdbcTemplate------------------------------------------------------------------------------


需要访问数据库来验证业务逻辑,可以使用SimpleJdbcTemplate  --封装了常用的Jdbc操作,也支持迭代访问查询的ResultSet结果集

简单的应用示例:

[java]  view plain  copy
  1. 2.1.1 Construct new instance  
  2.   
  3.  SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);  
  4.   
  5.  2.1.2  
  6.  queryForInt     
  7. The query is expected to be a single row/single column query that results in an int value.  
  8.   
  9.  String sql = "SELECT COUNT(1) FROM bmw_users";  
  10. int result = jdbcTemplate.queryForInt(sql);  
  11.   
  12.  2.1.3   
  13. queryForList   
  14. The results will be mapped to a List (one entry for each row) of Maps (one entry for each column, using the column name as the key).  
  15.   
  16.  String sql = "SELECT * FROM bmw_users WHERE city=? AND user_gender=? ";  
  17. List<Map> resutls = jdbcTemplate.queryForList(sql, "杭州","m");  
  18.   
  19.  2.1.4   
  20. query like queryForList but mapping each row to a Java object  
  21.   
  22.  String sql = "SELECT user_id userId,nick,user_gender sex FROM bmw_users WHERE city=? AND user_gender=?";  
  23. List resutls = jdbcTemplate.query(sql, ParameterizedBeanPropertyRowMapper.newInstance(User.class),"杭州","m");  
  24.   
  25.  2.1.5   
  26. update or delete data  
  27.   
  28.  String sql = "DELETE FROM bmw_users WHERE id=? ";  
  29. jdbcTemplate.update(sql, “1111”);   


ITest测试框架------------------------------------------------------------------------------------------------

淘宝的测试部门开发的一套单元测试框架(也用于接口测试),以Junit4为核心,结合DbUnit,Unitils等主流测试框架。

Itest的具体使用:

1.在Maven中引入itest框架:

[html]  view plain  copy
  1. <dependency>  
  2.   <groupId>com.taobao.test</groupId>  
  3.   <artifactId>itest</artifactId>  
  4.   <version>1.0</version>  
  5.   <scope>test</scope>  
  6. </dependency>  


2.编写测试的基类:

[java]  view plain  copy
  1. import com.taobao.itest.ITestSpringContextBaseCase;  
  2. import com.taobao.itest.annotation.ITestSpringContext;  
  3.   
  4. @ITestSpringContext({ "/spring_test/spring-userportal-db-test.xml" })  
  5. public class BaseTestCase extends ITestSpringContextBaseCase {  
  6. }  


3.编写具体的测试类:
[java]  view plain  copy
  1. import static org.hamcrest.Matchers.equalTo;  
  2. import static org.junit.Assert.assertThat;  
  3.   
  4. import javax.annotation.Resource;  
  5.   
  6. import org.junit.Test;  
  7. import org.springframework.transaction.annotation.Transactional;  
  8.   
  9. import com.taobao.common.dao.persistence.exception.DAOException;  
  10. import com.taobao.itest.annotation.ITestDataSet;  
  11. import com.taobao.itest.annotation.ITestSpringContext;  
  12.   
  13. /** 
  14. * @author 
  15. * 
  16. */  
  17. @ITestDataSet  
  18. @ITestSpringContext(locations = { "/spring/spring-userportal-servcase.xml" })  
  19. public class AddServCaseTest extends BaseTestCase {  
  20. @Resource  
  21.   
  22. @Test  
  23. @Transactional  
  24. public void testAddServCase() throws DAOException {  
  25. ......  
  26. }  
  27. }  


4.准备测试数据(.xls文件)
5.Run As JUnit Test


iTest为单元/接口测试提供整体的解决方案,目前总体分为三个部分:itest-webapp,itest-framework和itest-plugin。三者之间既可独立使用,又可相辅相成,其关系可参见下图:

:

itest-app是一个独立的应用,主要功能为用例设计管理和用例回归报表。

itest-framework以Junit4为核心,集合DbUnit、Unitils等主流测试框架,通过封装和功能扩展,降低各种测试框架的学习成本,解决复杂需求,使单元/接口测试编码更加简单高效。

itest-plugin通过Maven插件或Eclipse插件提供一些测试辅助功能,如利用其Mavne插件可快速创建基于itest-framework的Maven测试工程,如果你使用itest-webapp管理你的用例设计,你还可以利用itest-plugin的代码生成和用例同步功能。

iTest提供了如下特性:

  • 测试用例设计管理(itest-webapp)
    • 用例设计管理
    • 用例回归报表
  • 测试代码框架(itest-framework)
    • 上下文加载
    • 依赖注入
    • 测试数据生成
    • 测试数据事前加载和事后自动清理
    • 解耦入参数据和代码
    • 自动打印调用日志
    • 统一的断言机制
    • 支持Webx测试(itest-framework-webx)
      • Webx配置文件及上下文加载
      • 运行时动态修改HSF生产配置为HSF单元测试配置。
      • Webx之Action/Screen层测试
  • 测试辅助(itest-plugin)
    • 创建基于itest-framework的测试工程及代码示例
    • 骨干代码生成
    • 用例设计跟用例代码同步

iTest虚拟项目由淘宝测试部于2009年12月中旬发起,志在通过一站式的解决方案,使单元/接口测试更加低成本、高效率。



Unitils测试框架 -----------------------------------------------------------------------------------------

[plain]  view plain  copy
  1. <span style="font-size:13px;">断言工具  
  2. Unitils 模块  
  3. 数据库测试  
  4. 自动测试数据维护  
  5. 使用hibernate的程序测试  
  6. 使用JPA的应用测试  
  7. 使用Spring的应用的测试  
  8. 使用Mock对象的应用的测试  
  9. 对EasyMock的支持</span>  

1.断言工具 ---为断言使用映射

来看例子:

[java]  view plain  copy
  1. public class User {  
  2.     private long id;  
  3.     private String first;  
  4.     private String last;  
  5.   
  6.     public User(long id, String first, String last) {  
  7.         this.id = id;  
  8.         this.first = first;  
  9.         this.last = last;  
  10.     }  
  11. }  
  12.   
  13. User user1 = new User(1"John""Doe");  
  14. User user2 = new User(1"John""Doe");  
比较两个用户:

assertEquals(user1,user2);

你可能期望这个断言是成功的,因为两个实例包含合理相同的值,然而不是这种情况,因为User对象没有重写equals方法,检查两个User实例的相等其实是检查两个对象是否为同一个对象。换句话说上面的验证将会返回fail.

加入你实现了如下的相等方法:

[java]  view plain  copy
  1. public boolean equals(Object object) {  
  2.     if (object instanceof User) {  
  3.         return id == ((User) object).id;  
  4.     }  
  5.     return false;  
  6. }  

这是一个合理的实现符合你的应用逻辑,通过两个用户实例是否有相同的idl来比较他们是否相等。然而这个方法对你的单元测试是没用的。测试是否两个对象相等便成了测试他们是否拥有相同的id了。

User user1 = newUser(1, "John", "Doe");

User user2 = newUser(1, "Jane", "Smith");

assertEquals(user1,user2);

这个断言将是成功的,但可能不是你想要的。最好的是避免使用equals()当你比较对象的时候(当然除了表达值的对象,如java.lang.String?)。

你也可以比较每一个属性:

User user1 = newUser(1, "John", "Doe");

User user2 = newUser(1, "John", "Doe");

assertEquals(user1.getId(),user2.getId());

assertEquals(user1.getFirst(),user2.getFirst());

assertEquals(user1.getLast(),user2.getLast());

Unitils提供了更容易的方式来检查这些属性,就是通过映射。

使用 ReflectionAssert.assertReflectionEquals上面的例子可以被改写成这样:

User user1 = newUser(1, "John", "Doe");

User user2 = new User(1,"John", "Doe");

assertReflectionEquals(user1,user2);

这个断言通过反射来循环比两个对象的所有的属性值,对上面的例子,他会以此比较id值,first值和last值。

如果一个属性自己也是一个对象,它将递归的去比较这个对象的属性值。对collections,maps,arrays类型也是一样。他们的元素将被贯穿的递归的通过反射来比较。

如果一个值是基本类型或者基本封装类型,他们将会通过值的是否相同来比较。结果是下面的断言将返回成功。

assertReflectionEquals(1,1L);

 

List<Double>myList = new ArrayList<Double>();

myList.add(1.0);

myList.add(2.0);

assertReflectionEquals(Arrays.asList(1,2), myList);

http://www.diybl.com/course/3_program/java/javajs/20100719/462300.html



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值