`
hypercube1024
  • 浏览: 85257 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Seam 使用心得(一)测试先行

    博客分类:
  • seam
阅读更多
最近开始关注Seam,正值Seam2.0发布之际我也下载来试用,还是准备先做一个用户注册的例子。由于一直喜欢TDD所以先从测试用例开始写起吧。
首先使用seam-gen生成一个项目目录,然后再进行必要的配置。
1)配置数据源,我使用的hsqldb内存数据库,这样比较方便
在myApp-test-ds.xml这样进行配置
<datasources>
   <local-tx-datasource>
        <jndi-name>myAppTestDatasource</jndi-name>
        <connection-url>jdbc:hsqldb:.</connection-url>
        <driver-class>org.hsqldb.jdbcDriver</driver-class>
        <user-name>sa</user-name>
        <password></password>
    </local-tx-datasource>
</datasources>


persistence-test.xml中的配置
<persistence-unit name="myApp" transaction-type="JTA">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/myAppTestDatasource</jta-data-source>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
         <property name="hibernate.show_sql" value="true"/>
         <property name="hibernate.format_sql" value="false"/>
         <property name="hibernate.cache.use_second_level_cache" value="false"/>
         <property name="jboss.entity.manager.factory.jndi.name" value="java:/myAppEntityManagerFactory"/>
      </properties>
</persistence-unit>


这样测试数据源的配置就完成了,当然还要把hsqldb.jar放在测试的classpath中。

2)配置测试用例
在测试文件夹中创建一个用于配置测试用例类的xml,我的就是在test/org/qpt/test/user里面建立一个RegisterTest.xml,内容如下:
<suite name="Register Tests" verbose="2" parallel="false">
    <test name="Register Test">
	<!--配置jndi数据源,用于数据库测试-->
        <parameter name="datasourceJndiName" value="java:/myAppTestDatasource"/>
        <classes>
            <class name="org.qpt.test.user.RegisterTest" />
        </classes>
    </test>
</suite>


3)检查你的build.xml中test任务是否正确的拷贝了测试所有需要用到的jar包和xml文件,我的build.xml是用seam-gen自动生成的,有些文件例如dataset.xml模拟数据库的标准数据的文件就没有被自动拷贝到相应的目录导致运行测试就报异常,我为此郁闷了好几天,网上一直找不到答案,结果静下心仔细研究了一下才发现build.xml的问题-_-!,所以我在build.xml加入了如下任务:
<copy todir="${test.dir}">
            <fileset dir="${src.test.dir}">
                <exclude name="**/*.java" />
            </fileset>
</copy>
<copy tofile="${test.dir}/myApp-ds.xml"
              file="${basedir}/resources/myApp-test-ds.xml"
              overwrite="true"/>


4)编写测试用例
一般来说用户注册要调用一个register()的业务方法,所以我的无状态session bean接口如下:

package org.qpt.facade;
import javax.ejb.Local;

@Local
public interface Register {

    /**
     * 注册一个新用户
     * @return 状态码有5种情况:1,注册成功(SUCCESS)
     * 2,两次输入的密码不同(PWD_NOT_EQ_IN_TWICE)
     * 3,两次输入的email不同(EMAIL_NOT_EQ_IN_TWICE)
     * 4,用户名已经在数据库里面存在(EXISTS_NAME)
     * 5,email已经在数据库里面存在(EXISTS_EMAIL)
     */
    public String register();
}


返回的状态码可以用enum来实现,如:
public enum RegState {
        EXISTS_EMAIL, EXISTS_NAME, PWD_NOT_EQ_IN_TWICE, EMAIL_NOT_EQ_IN_TWICE, SUCCESS
}

现在就可以在org.qpt.test.user.RegisterTest类里面开始编写测试用例了,但是由于使用了ejb所以现在要用到嵌入式jboss,要把jboss-embedded-all.jar放到测试的classpath中。(注意:根据官方文档的说明,嵌入式jboss只能在jdk1.5下面使用,如果使用的jdk1.6将报异常,但是经过搜索官方网站已经发现了解决方案,那就是要下载一个新的org.jboss.metadata.spi.signature.Signature类重新编译后覆盖原始的,这个类的源文件在最后附上)

下面的代码是测试代码的一部分,完整的代码应该验证register方法返回的5种状态 :
public class RegisterTest extends DBUnitSeamTest {// 1
@Override
    protected void prepareDBUnitOperations() {
        beforeTestOperations.add(new DataSetOperation("org/qpt/test/user/RegisterDataSet.xml")); // 2
    }
	......
@Test
    public void testCorrectCase() throws Exception { //3
        new FacesRequest() {

            @Override
            protected void updateModelValues() {
                setValue("#{user.name}", "qwerty");
                setValue("#{user.pwd}", "123456");
                setValue("#{user.confirmPwd}", "123456");
                setValue("#{user.email}", "qwerty@123.com");
                setValue("#{user.confirmEmail}", "qwerty@123.com");
            }

            @Override
            protected void processValidations() {
                validateValue("#{user.name}", "qwerty");
                validateValue("#{user.pwd}", "123456");
                validateValue("#{user.confirmPwd}", "123456");
                validateValue("#{user.email}", "qwerty@123.com");
                validateValue("#{user.confirmEmail}", "qwerty@123.com");
                assert !isValidationFailure();
            }

            @Override
            protected void invokeApplication() {
                assert invokeMethod("#{register.register}").equals("SUCCESS");
            }
        }.run();
    }
  @Test
    public void testPwdIllegaCase() throws Exception { 
        new FacesRequest() {

            @Override
            protected void updateModelValues() {
                setValue("#{user.name}", "qwerty");
                setValue("#{user.pwd}", "654321");
                setValue("#{user.confirmPwd}", "123456");
                setValue("#{user.email}", "qwerty@123.com");
                setValue("#{user.confirmEmail}", "qwerty@123.com");
            }

            @Override
            protected void invokeApplication() {
                assert invokeMethod("#{register.register}").equals("PWD_NOT_EQ_IN_TWICE");
            }
        }.run();
    }
	......

@Test
    public void testNameExistsCase() throws Exception {
        new FacesRequest() {

            @Override
            protected void updateModelValues() {
                setValue("#{user.name}", "hypercube");
                setValue("#{user.pwd}", "654321");
                setValue("#{user.confirmPwd}", "654321");
                setValue("#{user.email}", "qwerty@124.com");
                setValue("#{user.confirmEmail}", "qwerty@124.com");
            }

            @Override
            protected void invokeApplication() {
                assert invokeMethod("#{register.register}").equals("EXISTS_NAME");
            }
        }.run();
    }

	......

}

1,因为用户注册肯定要操作数据库,所以我继承了DBUnitSeamTest,这样就可以方便的使用dbunit和hsqldb内存数据库进行测试了。
2,继承DBUnitSeamTest就要实现他的一个抽象方法protected void prepareDBUnitOperations(),主要是使用标准数据初始化数据库。RegisterDataSet.xml里面就是定义了表结构和标准数据,我的users表内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <users name="hypercube" pwd="123456" email="hypercube@123.com" />
</dataset>

如果你被有指定其他的操作,DataSetOperation默认使用DatabaseOperation.CLEAN_INSERT作为一个构造参数。这个例子首先清空定义在BaseData.xml中所有的表然后插入所有声明在BaseData.xml中的行在@test方法每次调用之前。
3,这个方法模拟了JSF请求的生命周期包括初始化模型的值,验证模型属性的合法性(配合hibernate验证),调用register()方法,然后通过assert验证方法是否正确的执行。
  • Signature.java.zip (201 Bytes)
  • 描述: 用于修正嵌入式jboss在jdk6下的问题
  • 下载次数: 117
分享到:
评论
2 楼 bigcatJavaEye 2008-01-24  
你好,我现在也在做jboss seam测试。
用到home class
在调用getDefinedInstance的时候,总出现异常。
网上的资料比较少,不知道您可否指导一下。
谢谢。
package org.domain.demo.session;

import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.framework.EntityNotFoundException;

import org.domain.demo.entity.*;
import java.util.ArrayList;
import java.util.List;

import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.framework.EntityHome;

@Name("kokyakuHome")
public class KokyakuHome extends EntityHome<Kokyaku> {

	@In(create = true)
	ShainHome shainHome;

	public void setKokyakuKokyakuCd(String id) {
		setId(id);
	}

	public String getKokyakuKokyakuCd() {
		return (String) getId();
	}

	@Override
	protected Kokyaku createInstance() {
		Kokyaku kokyaku = new Kokyaku();
		return kokyaku;
	}

	public void wire() {
		Shain shain = shainHome.getDefinedInstance();
		if (shain != null) {
			getInstance().setShain(shain);
		}
	}

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String checkExist() {
		boolean isSuccess = true;
		try {
			Shain shain = shainHome.getDefinedInstance();
			if (shain != null) {
				getInstance().setShain(shain);
			}
		} catch (EntityNotFoundException ex) {
			FacesMessages.instance().add("filled in Shain does not exist  ");
			isSuccess = false;
		}
		if (isSuccess) {
			getInstance().setKokyakuTel(
					formatNum(getInstance().getKokyakuTel()));
			getInstance().setKokyakuFax(
					formatNum(getInstance().getKokyakuFax()));
			return "success";
		} else
			return "input";
	}

	public boolean isWired() {
		return true;
	}

	public Kokyaku getDefinedInstance() {
		return isIdDefined() ? getInstance() : null;
	}

	public List<Torihiki> getTorihikis() {
		return getInstance() == null ? null : new ArrayList<Torihiki>(
				getInstance().getTorihikis());
	}

	public String formatNum(String strOrignal) {
		strOrignal = strOrignal.replaceAll("-", "");
		int len = strOrignal.length();
		if (len > 0) {
			String firstTwo = "", secondFour = "", thireFour = "", reslutStr = "";
			if (len > 2) {
				firstTwo = strOrignal.substring(0, 2);
				if (len > 6) {
					secondFour = strOrignal.substring(2, 6);
					if (len >= 10) {
						thireFour = strOrignal.substring(6, 10);
						reslutStr = firstTwo + "-" + secondFour + "-" + thireFour;
					} else {
						thireFour = strOrignal.substring(6, len);
						reslutStr = firstTwo + "-" + secondFour + "-" + thireFour;
					}
				} else {
					secondFour = strOrignal.substring(2, len);
					reslutStr = firstTwo + "-" + secondFour;
				}
			} else {
				firstTwo = strOrignal.substring(0, len);
				reslutStr = firstTwo;
			}

			return reslutStr;
		}
		return null;
	}
	
	public void clearIds() {
		this.setId(null);
		this.setInstance(null);
		this.shainHome.setId(null);
		this.shainHome.setInstance(null);

	}

	@End(beforeRedirect = true)
	public void clear() {
		getEntityManager().clear();
	}

	public void setShainHome(ShainHome shainHome) {
		this.shainHome = shainHome;
	}

}

1 楼 lucyuan 2008-01-18  
请教一个问题,比如在RegisterDataSet.xml中
<users name="hypercube" pwd="123456" email="hypercube@123.com" /> 
请问这个users表在哪里创建,bootstrap/data/hypersonic中localDB.script,是在这里吗?

相关推荐

    提高Seam系统性能测试点

    Seam是一个Java EE框架,主要用于构建富互联网应用程序(Rich Internet Applications)。它整合了JSF、EJB、CDI、Hibernate等技术,为开发者提供了一种更高效、更灵活的开发方式。性能测试是确保Seam应用能够高效...

    近两个星期seamtest的学习

    在过去的两周里,我深入学习了SeamTest,这是一个用于Java EE应用测试的强大工具,尤其在Seam框架的上下文中。SeamTest提供了一种结构化的、声明式的测试方法,帮助开发者更有效地验证应用程序的各个层面,包括组件...

    使用 Maven 管理 Seam 项目

    本篇文章将深入探讨如何使用Maven来管理Seam项目,一个基于Java EE的轻量级框架,专为富互联网应用程序(RIA)设计。 Seam项目是一个集成框架,它将JSF、EJB、CDI、JPA等Java EE技术紧密融合,提供了丰富的功能和...

    seam carving 测试数据集免费分享

    Seam Carving是一种在计算机视觉领域中用于图像内容自适应调整的技术,主要应用于图像缩放而不失真关键特征。这个测试数据集显然专注于这一技术的实际应用和效果验证。以下是关于Seam Carving及相关知识点的详细解释...

    seam in action 中文 english

    8. **测试支持**:Seam提供了一套完整的测试工具,包括单元测试、集成测试和端到端测试,确保应用的质量。 然而,根据描述中的反馈,英文版可能在阅读体验上并不理想,可能需要花费更多的时间和精力去理解。对于...

    JBOSS SEAM组件中文手册

    4. **测试框架**: Seam 2.0引入了集成测试框架,使得单元测试和集成测试变得更加方便。 5. **国际化(i18n)和本地化(l10n)支持**: 提供了全面的国际化和本地化解决方案,方便多语言应用的开发。 **五、Seam的...

    Seam框架文档简述

    Seam作为一个胶水框架,能够很好地整合各种技术栈,如AJAX、Facelet、JSF、EJB3、Hibernate、Hibernate Search、JBPM、Drools、Email、iText、JMS等,为开发者提供了一个完整的开发环境。 通过以上介绍,我们可以...

    为Seam做好准备

    JSF是一种MVC(Model-View-Controller)框架,了解其组件模型和生命周期对于使用Seam至关重要。 3. **Java Persistence API (JPA)**:JPA是Java EE中的ORM(对象关系映射)标准,允许开发者用面向对象的方式操作...

    MATLAB_Seam_Carving_seamcarving_

    MATLAB_Seam_Carving_seamcarving_ 是一个与图像处理相关的项目,主要涉及到一种称为“seam carving”的技术,这是一种动态图像调整大小的方法,它可以在不改变图像整体视觉效果的情况下,增加或减少图像的宽度和...

    jboss seam 学习资料,seam in action和官方手册

    7. **测试与调试**:掌握Seam的测试工具和策略,确保代码质量。 8. **Seam组件**:了解如Conversation、Transactions、邮件服务等Seam内置组件的使用方法。 9. **实时性与Ajax**:探索Seam如何实现实时更新和Ajax...

    jboss seam 2.01GA REF DOC

    本节通过一个酒店预订系统示例展示了如何使用 Seam 和 Hibernate 开发应用。 **1.8.1 简介** - **应用场景**:酒店预订系统是一个典型的企业级应用案例。 - **功能需求**:包括用户管理、房间预订、支付等功能。 ...

    seam_in_action

    #### 2.1 第一部分:起步使用Seam - **第1章:Seam统一Java EE 3**:介绍 Seam 如何整合 Java EE 3 技术,形成统一的应用开发平台。 - **第2章:将Seam-Gentoo投入工作**:展示如何在 Gentoo Linux 系统上安装和配置...

    Seam in Action

    《Seam in Action》这本书详细介绍了如何使用Seam进行实际项目开发,包括设置环境、创建Seam应用、使用Seam组件、调试和测试等步骤。读者可以通过这本书了解到Seam的精髓,掌握如何利用Seam构建高效的企业级应用。 ...

    Jboss Seam中文版

    8. **RESTful的Seam应用程序:Blog示例**:通过一个博客系统,演示了如何使用Seam构建RESTful风格的服务。 - **使用“拉”风格的MVC**:解释了如何通过Seam实现客户端发起请求、服务器响应数据的经典MVC模式。 - *...

    Seam_in_Action

    《Seam in Action》这本书是关于JBoss Seam框架的一部权威指南,由业界专家撰写,旨在帮助开发者深入了解和高效使用Seam。JBoss Seam是一个开源的企业级Java框架,它将JavaServer Faces (JSF)、Java Persistence API...

    Seam Carving的C++实现代码

    Seam Carving是一种图像内容感知的尺寸调整方法,它能够在保持图像主要结构不变的情况下,智能地减少或增加图像的宽度和高度。这种方法是由Amit Agarwal和Matthieu Salzmann于2007年提出的,其核心思想是通过找到...

    seam_carving 代码实现 seam

    Seam Carving,又称图像拉链,是一种基于能量最小化的图像调整方法,主要用于图像大小的动态调整,而不仅仅是简单的等比例缩放。它能够在保持图像主要结构不变的情况下,根据需要增加或减少图像的宽度和高度。这种...

    Seam security

    Seam Security是针对Java Web应用程序的安全框架,它是JBoss Seam项目的一部分,提供了全面的安全解决方案,包括身份验证、授权和身份管理等功能。Seam Security以易于配置和使用为特点,允许开发者快速设置应用程序...

    SEAM 中文开发指南

    - **SEAM**:SEAM 是一个基于 Java EE 的企业级应用框架,它简化了复杂的应用程序开发过程,并且提供了丰富的功能来支持业务逻辑的实现。 - **版本信息**:本文档介绍了 SEAM 2.0 GA 版本的功能特性及其使用方法。 ...

    jboss-seam2.1

    Seam 是一种业级 企 Java 的应规用程序框架。它的灵感源自下列原 : 只有一种“工具” Seam为 应 业务业业 义 种统 组 你的 用程序中所有的 定 了一 一的 件模型。 Seam组件可能是 态义 关关 态 有状 的,包含与几...

Global site tag (gtag.js) - Google Analytics