-
CreateProcess error=87,
2012-10-23 11:39:26
Cannot run program "C:\Program Files\Java\jdk1.6.0_17\bin\javaw.exe" (in directory "C:\Workspace\testSeam1-test"): CreateProcess error=87, The parameter is incorrect
今天非常悲剧的因为这个问题整了一整天,jdk、eclipse重装N遍都没用。
网上找到的资料也非常少。
http://blog.csdn.net/zhangren07/archive/2010/10/15/5944173.aspx
只怪半天没看明白余二爷说的意思。
二爷最后一句话说出解决的要点:修改maven的本地repository的默认路径
C:\Documents and Settings\liuyi\.m2把这个目录下的repository包全删除
再修改D:\tools\maven-2.2.1\conf目录下面setttings.xml文件。使用编辑器打开,找到localRepository一项,将它的值修改成<localRepository>D:\MavenRepository</localRepository>
保险起见把C:\Documents and Settings\liuyi\.m2目录下的setttings.xml也一起修改了。
运行maven命令,重新生成eclipse文件导入项目。纠结了一天的问题解决
原因分析有说法是maven的默认目录C:\Documents and Settings\liuyi\.m2太长或者是有空格造成 -
接口测试从零开始系列7_Maven使用
2011-12-16 19:28:48
1. Maven是什么:
Maven是一个项目管理工具,包含项目对象模型,一组标准集合,一个项目生命周期,一个依赖管理系统,和用来运行定义在生命周期阶段中插件目标的逻辑。
2. 如何配置maven:
1, 下载:从官网http://maven.apache.org/download.html 获取maven2的文件包;
2,解压该maven到D:\work\maven,并配置一下环境变量:
在系统变量里的添加path :D:\work\maven\bin
3,在dos下输入命令:mvn -v,如果配置正确将会得到maven的版本信息等。
注意:需要配置%JAVA_HOME%
3. 创建Maven工程
使用命令创建:
1,在dos下进入要创建项目的目录,如D:\mytestproject;
2,输入命令创建项目
mvn archetype:create -DgroupId=com.test.mytest -DartifactId=mytestproject
3, 命令执行完成后可以看到在D:\mytestproject下会生产一个maven工程
4, 导入eclipse工程
D:\mytestproject>mvn -U clean eclipse:clean eclipse:eclipse
D:\mytestproject>mvn -U clean eclipse:clean eclipse:eclipse -DdownloadSources=true
使用eclips创建:
1. Eclipse中新建选择maven工程,
4. 配置文件元素相关说明:
groupId:项目或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.test.mytest生成的相对路径为:/com/taobao/mytest
artifactId: 项目的通用名称
packaging: 打包的机制,如pom, jar, maven-plugin, ejb, war, ear, rar, par
version:项目的版本
name: 项目的名称, Maven 产生的文档用
url: 哪个网站可以找到这个项目,提示如果 Maven 资源列表没有,可以直接上该网站寻找, Maven 产生的文档用,一般有自己的资源库时不需要此项。
5. 常用命令
mvn package:依据项目将在target文件下生成jar文件:mytestproject-1.0-SNAPSHOT.jar
mvn clean:清除目标目录中的生成结果
mvn install: 将项目的jar文件添加到资源库中, 以备依赖此项目时使用
mvn eclipse:eclipse:生成Eclipse项目文件,此时项目可以成功import到eclipse中mvn deploy: 打包部署到仓库,需要有权限
mvn war inplace:打包为可执行jar包
mvn test -Dtest=类名 :执行某个测试类
mvn test 执行所有测试类
6. Pom文件常用元素说明
1. 继承:项目可以通过parent元素使用继承,避免在一个项目中不断的重复同样的依赖元素,当一个项目声明一个parent的时候,它从父pom中继承信息,也可以覆盖父pom中的值,或者可以添加一些新的值。Maven在读取当前项目的pom之前,会使用这个父pom作为起始点,同样的父pom中的依赖也会被子项目继承过来。
<parent>
<artifactId>test-harvest.business</artifactId>
<groupId>com.test</groupId>
<version>2.1.4-SNAPSHOT</version>
</parent>
2. 多模块: 一个项目有多个模块,也叫做多重模块,或者合成项目。
如下定义,比如在父工程厦门会包括api工程和service工程<modules>
<module>test-harvest.business-api</module>
<module>test-harvest.business-service</module>
</modules>
3. Build设置:bulid主要是配置编译相关的内容
1. Proviles:定义一些在项目生命周期中使用的环境变量
<profile>
<id>test</id> //表示是测试环境
<properties>
<props>src/main/filters/test.properties</props> //环境变量的配置文件
<projectName>${project.artifactId}</projectName>
使用于哪个项目
</properties>
<activation>
<activeByDefault>true</activeByDefault> //是否激活
</activation>
</profile>
2. 插件:项目中使用到的插件,比如junit测试用例执行插件
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip> //是否跳过测试用例执行
</configuration>
</plugin>
</plugins>
3. 资源:项目中需要指定的资源位置
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
4. 依赖关系
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version> //版本
<scope>test</scope> //表示是测试环境使用
</dependency>
7. Settings.xml:
maven的全局性的配置文件,使用于所有项目。在maven2中存在两个 settings.xml,一个位于maven2的解压目录conf下面,作为全局性配置。对于团队设置,保持一致的定义是关键,所以 maven2/conf下面的settings.xml就作为团队共同的配置文件,保证所有的团队成员都拥有相同的配置。当然对于每个成员,都需要特殊的自定义设置,如用户信息,所以另外一个settings.xml就作为本地配置。
一些配置说明:
1. localRepository:表示本地库的保存位置,也就是maven2主要的jar保存位置,默认在${user.dir}/.m2/repository,如果需要另外设置,就换成其他的路径,如: <localRepository>D:\\ Repository</localRepository>
2. offline:如果不想每次编译,都去查找远程中心库,那就设置为true。当然前提是你已经下载了必须的依赖包。
3. Servers:保存server相关的信息,
<server>
-
接口测试从零开始系列6_简简单单Spring2
2011-12-14 18:54:04
Spring的依赖注入
1. Sring的bean配置文件声明bean
<bean id="pingJiaDao" class="com.koubei.springdiwithbeans.PingJiaDaoImplForSpring">
<!-- 第一种配置方式 -->
<property name="username">
<value>liuzhan</value>
</property>
<!-- 第二种配置方式 -->
<!-- <property name="username" value="liuzhan"></property> -->
<!-- 第三种配置方式 -->
<!-- p:username="liuzhan" -->
</bean>
2. 实例化ioc容器及bean
public static void main(String args[]) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring.xml");
IStoreServiceForSpring storeService = (IStoreServiceForSpring) context
.getBean("storeService");
PingJia pingJia = new PingJia();
pingJia.setPingJiaId("123456");
storeService.addPingJia(pingJia);
}
3. Bean引用
<bean id="storeService" class="com.koubei.springdiwithbeans.StoreServiceForSpring"
autowire="byName">
<!—ref local:如果使用了local,验证拥有该id的bean是否在同一个xml配置文件里 -->
<property name="pingJiaDao">
<ref local="pingJiaDao" />
</property>
<!—ref:bean名称可以引用ioc容器里任意的bean,即使不在同一个xml配置文件里 -->
<!-- <property name="pingJiaDao" ref="pingJiaDao"></property> -->
<!—声明内部bean -->
<!-- <property name="pingJiaDao">
<bean class="com.koubei.springdiwithbeans.PingJiaDaoImplForSpring">
<property name="username" value="liuzhan" />
</bean>
</property> -->
</bean>
4. 检查属性:
问题:通过setter注入的方式,不能保证所有的属性一定会被注入
解决:spring的依赖检查特性可以检查bean上某些类型的所有属性是否都被设置
方法1:通过dependency-check指定依赖检查模式(缺点:只检查某些类型的所有属性,不能检查特定属性)
<!-- 业务Bean定义 -->
<bean id="pingJiaDao1" class="com.koubei.springdiwithbeans.PingJiaDaoImplForSpring"
dependency-check ="simple">
<!-- none:所有属性都可以不设置
simple 简单类型检查
objects 对象类型检查
all 任意对象类型检查 -->
<property name="username" value="liuzhan"></property>
</bean>
方法2:通过Required注解检查特定属性(需要设置<context:annotation-config/>)
@Required//自动检查username属性
public void setUsername(String username) {
this.username = username;
}
5. Bean的自动装配
问题:bean访问其他bean是需要显式的指定引用
解决:能够自动装配避免显式的指定
方法1:在xml使用autowire自动装配(缺点:如果使用几种方式都无法满足,autowire属性会自动装配bean的所有属性)
<bean id="storeService" class="com.koubei.springdiwithbeans.StoreServiceForSpring"
autowire="byName">
<!-- no*:不执行自动装配,需要显式装配依赖
byName 为bean属性装配与属性同名的bean,但是有时候并不一定属性名和bean名称一致
byType 为bean属性装配同类型的bean,如果存在多个类型一致的bean,则会失败
constructor 每个构造器参数,先找出类型与构造器参数一致的bean,然后再找出具有最
匹配参数的构造器
autodetect 如果能够找到默认没有参数的构造器,则依赖byType模式自动装配,否则
采用constructor模式 -->
</bean>
方法2:使用@Atuowired和@Resource自动装配bean(可以配置个别属性,需要注册<context:annotation-config/>)
@Autowired(required = false) //自动匹配类型兼容的bean,默认情况下,应用了@Autowired的属性都需要设置,使用required=false,则属性并不一定要设置
@Qualifier("pingJiaDao") //自动匹配类型兼容的bean,并且名称是pingJiaDao
@Resource(name = "pingJiaDao")//根据名称装配
private IPingJiaDaoForSpring pingJiaDao ;
6. Bean属性集合
Map集合
<bean id="columnNames" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="flag" value="1" />
<entry key="caseID" value="2" />
<entry key="caseName" value="3" />
<entry key="caseDes" value="4" />
<entry key="mothed" value="5" />
<entry key="param" value="6" />
<entry key="status" value="7" />
<entry key="resultDes" value="8" />
</map>
</constructor-arg>
</bean>
List
<bean id="idList" class="java.util.List">
<constructor-arg>
<list>
<value="1" />
<value="2" />
<value="3" />
<value="4" />
<value="5" />
<value="6" />
<value
-
接口测试从零开始系列6_简简单单Spring1
2011-12-14 18:52:14
一. 控制反转和容器的思想
1. 面向对象设计里,讲究“接口与实现分离”
//定义接口
public interface IPingJiaDaoForSpring {
//插入一条记录
public boolean insert(PingJia pingJia);
}
//接口实现
public class PingJiaDaoImplForSpring implements IPingJiaDaoForSpring {
@Override
public boolean insert(PingJia pingJia) {
//实现insert的具体方法
}
2. 在代码当中调用
public class StoreServiceForSpring {
//在此处写死了实现是PingJiaDaoImplForSpring()
private IPingJiaDaoForSpring pingJiaDao = new PingJiaDaoImplForSpring();
public boolean addPingJia(PingJia pingJia) {
return pingJiaDao.insert(pingJia);
}
}
3. 不同组织有不同的实现方式
private IPingJiaDaoForSpring pingJiaDao = new 其他实现();
问题:需要维护多个StoreServiceForSpring,每个各自创建和管理自己的依赖,对象之间的耦合性很高。
4. 使用一个容器来管理这些组件
public class Container {
public static Container instance;
private Map<String, Object> components;
public Container() {
components = new HashMap<String, Object>();
instance = this;
IPingJiaDaoForSpring pinjiaDao = new PingJiaDaoImplForSpring();
components.put("pinjiaDao", pinjiaDao);
IStoreServiceForSpring storeService = new StoreServiceForSpring();
components.put("storeService", storeService);
}
public Object getComponent(String id) {
return components.get(id);
}
}
在组件中使用容器生成组件:private IPingJiaDaoForSpring pingJiaDao = (IPingJiaDaoForSpring) Container.instance
.getComponent("pinjiaDao");
5. 使用容器后,可以用容器来生成需要的组件:
public class Main {
public static void main(String args[]) {
IStoreServiceForSpring storeService = (IStoreServiceForSpring) Container.instance
.getComponent("storeservice");
PingJia pingJia = new PingJia();
pingJia.setPingJiaId("123456");
storeService.addPingJia(pingJia);
}
}
6. 使用服务定位器查找组件(主动查找)
public class ServiceLocator {
public static Container container = Container.instance;
public static IPingJiaDaoForSpring getPingJiaDao() {
return (IPingJiaDaoForSpring) container.getComponent("pinjiaDao");
}
}
在组件中使用查找器:private IPingJiaDaoForSpring pingJiaDao = ServiceLocator.getPingJiaDao();
7. 应用控制反转和依赖注入
在组件中使用查找器查找组件时,组件依旧需要知道如何查找资源,然后向容器发起请求查找资源,容器返回资源,
使用控制反转原则:容器主动将资源推送到所管理的组件中,组件只是选择一种合适的方式接受资源。
public Container() {
//components = new HashMap<String, Object>();
//instance = this;
IPingJiaDaoForSpring pingJiaDao = new PingJiaDaoImplForSpring();
components.put("pinjiaDao", pingJiaDao);
StoreServiceForSpring storeService = new StoreServiceForSpring();
StoreServiceForSpring storeService1 = new StoreServiceForSpring(pingJiaDao);
storeService.setPingJiaDao(pingJiaDao); //设置资源
components.put("storeService", storeService);
components.put("storeService1", storeService1);
}
依赖注入的三种方式:接口注入,setter注入,构造器注入
8. 使用配置文件来配置容器
public Container() {
components = new HashMap<String, Object>();
// instance = this;
Properties properties = new Properties();
try {
properties.load(new FileInputStream("components.properties"));
for (Map.Entry entry : properties.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
processEntry(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
IPingJiaDaoForSpring pingJiaDao = new PingJiaDaoImplForSpring();
components.put("pinjiaDao", pingJiaDao);
StoreServiceForSpring storeService = new StoreServiceForSpring();
StoreServiceForSpring storeService1 = new StoreServiceForSpring(
pingJiaDao);
storeService.setPingJiaDao(pingJiaDao);
components.put("storeService", storeService);
components.put("storeService1", storeService1);
}
-
接口测试从零开始5_教你如何使用ibatis2
2011-12-12 19:41:20
4. 配置SqlMapConfig配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties resource="dbcpconfig.properties"/>
<settings cacheModelsEnabled="false" enhancementEnabled="true" lazyLoadingEnabled="false" errorTracingEnabled="true" maxRequests="400" maxSessions="40"
maxTransactions="32" useStatementNamespaces="true" />
<!--
1. cacheModelsEnabled 是否启动sqlMapClient上的缓存机制;
2. enhancementEnabled是否针对POJO启用字节码增强机制以提升getter/setter的调用效能,
避免使用Java Reflect所带来的性能开销,同时也为Lazy Loading带来了极大的性能提升;
3. errorTracingEnabled 是否启用错误日志;在开发期间建议设为“true”以方便调试
4. lazyLoadingEnabled 是否启动延迟加载机制
5. maxRequests 最大并发请求数(Statement并发数)
5. maxTransactions 最大并发事务
6. maxSessions 最大Session数,即当前最大允许的并发sqlMapClient数(介于maxRequests和maxTransactions之间)
7. useStatementNamespaces 是否使用Statement命名空间(为true时,需要追加命名空间)
-->
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<!--dataSource从属于transactionManager节点,用于设定ibatis运行期使用的DataSource属性
type属性: dataSource节点的type属性指定了dataSource的实现类型 ,指定了数据源的链接类型,也有3种类型(SIMPLE,DBCP,JNDI)
1. SIMPLE: SIMPLE是ibatis内置的dataSource实现,其中实现了一个简单的数据库连接池机制, 对应ibatis 实现类为
com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
2. DBCP: 基于Apache DBCP连接池组件实现的DataSource 封装,当无容器提供DataSource 服务时,
建议使用该选项,对应ibatis 实现类为com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
3. JNDI: 使用J2EE 容器提供的DataSource 实现,DataSource 将通过指定的JNDI Name 从容器中获取。
对应ibatis 实现类为com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
-->
<property name="JDBC.Driver" value="${driverClassName}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${username}" />
<property name="JDBC.Password" value="${password}" />
<property name="Pool.MaximumActiveConnections" value="10" /> <!--连接池维持的最大容量-->
<property name="Pool.MaximumIdleConnections" value="5"/> <!--连接池允许挂起的最大连接-->
<property name="Pool.MaximumCheckoutTime" value="120000"/> <!--连接被某个任务所允许占用的最大时间-->
<property name="TimeToWait" value="500"/> <!--线程允许等待的最大时间-->
</dataSource>
</transactionManager>
<!-- 指定映射文件的位置,配置中可出现多个sqlMap节点,以指定项目内所有映射文件 -->
<sqlMap resource="conf/sqlmap/pingjia.ibatis.xml"/>
</sqlMapConfig>
5. 读取配置文件
static {
try {
Reader reader = Resources.getResourceAsReader("conf/testlearnning.sqlmapconfig.xml");
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
}
6. 增删改查相关操作
@Override
public boolean insert(PingJia pingJia) {
boolean flag = false;
try {
sqlMap.insert("PingJiaDao.insert", pingJia);
flag =true;
} catch (SQLException e) {
e.printStackTrace();
}
return flag;
}
-
接口测试从零开始5_教你如何使用ibatis
2011-12-12 19:35:44
1. 创建pojo类
public class PingJia
2. 创建Dao接口
public interface IPingJiaDao
3. 使用ibatis编写实现类
1. 通过pom依赖引入ibatis包
<dependency>
<groupId>com.ibatis</groupId>
<artifactId>ibatis</artifactId>
<version>2.3.4.726</version>
</dependency>
2. 编写实现类,引入ibatis SqlMapClient和Resource
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
3. 配置POJO类的IBatis配置文件pingjia.ibatis.xm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="PingJiaDao">
<!--命名空间,在此空间外要引用此空间的元素,则需要加上命名空间名 -->
<typeAlias alias="pingJia" type="com.koubei.testlearnning.pojo.PingJia"/>
<!-- 实体别名, 如果有用到全名的地方,可以用别名代替,受命名空间约束 -->
<resultMap class="com.koubei.testlearnning.pojo.PingJia" id="PingJia">
<result column="pingjiaid" property="pingJiaId" />
<result column="pingjiacontent" property="pingJiaContent" />
<result column="storeid" property="storeId" />
<result column="pingjiatype" property="pingJiaType" />
<result column="pingjiadate" property="pingJiaDate" />
</resultMap>
<!-- 结果集映射, -->
<delete id="delete" parameterClass="java.lang.String" >
<!-- 删除操作 -->
delete from pingjia where pingjiaid=#pingJiaId#
</delete>
<insert id="insert" parameterClass="pingJia" >
<!-- 插入操作 , 对于自增主键的表,插入可以不配置插入的主键列,否则是必须的-->
insert
into pingjia (pingjiaid, pingjiacontent, storeid,
pingjiatype,pingjiadate)
values(#pingJiaId#, #pingJiaContent#, #storeId#, #pingJiaType#,#pingJiaDate#)
</insert>
<update id="update">
<!-- 更新操作-->
update task_info
<dynamic prepend="set">
<!-- 动态sql:prepend表示链接关键字,property表示属性值-->
<isNotNull prepend=" , " property="pingJiaContent">
pingjiacontent =
#excutePerson#
</isNotNull>
<isNotNull prepend=" , " property="storeid">
storeid =#storeId#
</isNotNull>
<isNotNull prepend=" , " property="pingJiaType">
pingjiatype
=#pingJiaType#
</isNotNull>
<isNotNull prepend=" , " property="pingjiadate">
pingjiadate
=#pingJiaDate#
</isNotNull>
</dynamic>
where pingjiaid =#pingJiaId#
</update>
<select id="getPingJiaList" parameterClass="java.lang.String" resultMap="PingJia">
<!-- 查询操作,插入语句入参通过parameterClass="类别名"来设定,可以设定类别名,也可以设定为map,
也可以设定为iBatis支持的原生类型(比如string、int、long等, map是最强大的入参方式,任何入参方式
都可以转换为这种入参方式,因为iBatis仅接受一个入参,当几个参数分布在不同对象中的时候,将这些对象
的属性(或者对象本身put)到map中,然后一次传递给sql语句-->
sselect * from pingjia where storeId = #storeId#
</select>
<select id="getGoodPingNum" parameterClass="java.lang.String">
sselect count(1) from pingjia where storeId = #storeId# and pingjiatype=1
</select>
<select id="getPingJiaNum" parameterClass="java.lang.String">
sselect count(1) from pingjia where storeId = #storeId#
</select>
</sqlMap>
-
接口测试从零开始系列4_junit断言介绍2
2011-12-12 19:07:00
需要增加
hamcrest
包
在测试类里导入包import static org.junit.Assert.*;//assertThat跟下面的Matchers配合使用
import static com.taobao.itest.matcher.Matchers.*;//增加了反射相关的匹配,比如验证两个对象的某几个属性相同
// 通用匹配符
@Test
public void testAssert_nomarl() throws Exception {
int num = 200;
String storeId = "123456";
// allOf:所有条件必须都成立
assertThat(num, allOf(greaterThan(100), lessThan(300))); //运行成功
assertThat(num, allOf(greaterThan(100), lessThan(150))); //运行失败
// anyOf:只要有一个条件成立
assertThat(num, allOf(greaterThan(100), lessThan(150)));//运行成功
assertThat(storeId, anyOf(equalTo("123456"), equalTo("1234")));//运行成功
// anything:无论什么条件
assertThat(num, anything()); //运行成功
// is:变量的值等于指定值时
assertThat(storeId, is("123456"));//运行成功
assertThat(num, is("200"));//运行成功
// not:和is相反,变量的值不等于指定值时
assertThat(storeId, notis("123456"));//运行成功
}
// 字符串相关匹配符
@Test
public void testAssert_String() throws Exception {
String storeId = "assertTest";
// 字符串匹配符
assertThat(storeId, containsString("assert"));//运行成功
// startsWith:字符串变量以指定字符串开头时
assertThat(storeId, startsWith("assert"));//运行成功
// endsWith:字符串变量以指定字符串结尾时
assertThat(storeId, endsWith("t"));//运行成功
// euqalTo:字符串变量等于指定字符串时
assertThat(storeId, equalTo("assertTest"));//运行成功
// equalToIgnoringCase:字符串变量在忽略大小写的情况下等于指定字符串时
assertThat(storeId, equalToIgnoringCase("assertTEst"));//运行成功
// equalToIgnoringWhiteSpace:匹配符断言被测的字符串testedString在忽略头
//尾的任意个空格的情况下等于expectedString,注意:字符串中的空格不能被忽
assertThat(storeId, equalToIgnoringWhiteSpace(" assertTest "));//运行成功
assertThat(storeId, equalToIgnoringWhiteSpace(" assert Test "));//运行失败
}
-
接口测试从零开始系列4_junit断言介绍
2011-12-12 18:53:21
一. Junit4 断言
assertEquals(a, b)
assertFalse(a)
assertTrue(a)
assertNotNull(a)
assertNull(a)
assertNotSame(a, b)
assertSame(a, b)
@Test
public void testAssert() throws Exception {
int expectNum = 123;
int actuNum = 123;
String storeId = "123456";
// assertEquals(expect,actual),测试expect是否等于actual(expect和actual是原始类型数值(primitive value)或者必须为实现比较而具有equal方法)
assertEquals(expectNum, actuNum);//运行成功
assertEquals(storeId, "12345"); //运行失败
//assertFalse(condition)测试是否为false(假),condition是一个Boolean数值
assertFalse(expectNum==100);//运行成功
// assertTrue(condition) 测试是否为true(真),condition是一个Boolean数值
assertTrue(expectNum==123);//运行成功
//assertNotNull(object),测试object是否非空,object是一个对象或者null。
PingJia pingjia= null;
assertNotNull(pingjia);//运行失败
//assertNull(object),测试object是否非空,object是一个对象或者null。
assertNull(pingjia);//运行成功
// assertNotSame(unexpected, actual)测试unexpected和actual是否没有都引用同一个对象。
String storeId1 = storeId;
assertNotSame(storeId, storeId1);//运行失败
// assertSame(unexpected, actual)测试unexpected和actual是否没有都引用同一个对象。
assertSame(storeId, storeId1);//运行成功
}
二. junit新断言
1. JUnit4.4引入了Hamcrest框架,使用全新的断言语法:assertThat,结合Hamcest提供的匹配符,只用这一个方法,就可以实现所有的测试,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活;
2. assertThat 语法如下:
assertThat(T actual, Matcher<T> matcher);
assertThat(String reason, T actual, Matcher<T> matcher);
actual 是接下来想要验证的值;
matcher是使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果 actual值与 matcher 所表达的期望值相符,则断言成功,否则断言失败。reason是自定义的断言失败时显示的信息。
3. 注意事项:
a. JUnit4.4之后的版本才能使用assertThat方法;
4. 优点
1. 统一:只需一条assertThat语句即可替代旧有的其他语句(如assertEquals,assertNotSame,assertFalse,assertTrue,assertNotNull,assertNull等),使断言变得简单、代码风格统一,增强测试代码的可读性和可维护性。
2. 直观:assertThat 不再像 assertEquals 那样,使用比较难懂的“谓宾主”语法模式(如:assertEquals(3, x);)。相反,assertThat 使用了类似于“主谓宾”的易读语法模式(如:assertThat(x,is(3));),使得代码更加直观、易读,符合人类思维习惯。
3. 错误信息更具描述性
旧的断言语法如果断言失败,默认不会有额外的提示信息,如assertTrue(testedString.indexOf(”taobao”) > -1);如果该断言失败,只会抛出无用的错误信息,如java.lang.AssertionError: ,除此之外不会有更多的提示信息。
新的断言语法会默认自动提供一些可读的描述信息,如
assertThat(testedString, containsString(”taobao”));
如果该断言失败,抛出的错误提示信息如下:
java.lang.AssertionError:
Expected: a string containing “taobao”
got: “taoba”
4. 跟Matcher匹配符联合使用更灵活强大
-
接口测试从零开始系列_mock技术使用
2011-12-08 20:12:27
1. 什么情况下会使用mock技术
1. 需要将当前被测单元和其依赖模块独立开来,构造一个独立的测试环境,不关注被测单元的依赖对象,只关注被测单元的功能逻辑
----------比如被测代码中需要依赖第三方接口返回值进行逻辑处理,可能因为网络或者其他环境因素,调用第三方经常会中断或者失败,无法对被测单元进行测试 ,这个时候就可以使用mock技术来将被测单元和依赖模块独立开来,使得测试可以进行下去。
2. 被测单元依赖的模块尚未开发完成,而被测单元需要依赖模块的返回值进行后续处理
----------比如service层的代码中,包含对Dao层的调用,但是,DAO层代码尚未实现
3. 被测单元依赖的对象较难模拟或者构造比较复杂
----------比如,支付宝支付的异常条件有很多,但是模拟这种异常条件很复杂或者无法模拟,比如,查询聚划算的订单结果,无法在测试环境进行模拟
2. Mock技术分类
1. 手动构造mock对象
---------------比如,可以自己写某个接口方法的实现,根据需要编写返回值,测试代码中使用该实现类对象
缺点:会增加代码量,在写mock对象代码时,有可能引入错误
2. 使用开源代码提供的构造mock方法
--------------比如easyMock,提供了对接口类的模拟,能够通过录制、回放、检查三步来完成大体的测试过程,可以验证方法的调用种类、次数、顺序,可以令 Mock 对象返回指定的值或抛出指定异常
3. EasyMock使用
1. 引入easyMock
------------在maven工程中,通过pom配置依赖关系
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
------------在普通java工程中,通过添加外部包的方式
2. 使用easyMock过程
1. 使用 EasyMock 生成 Mock 对象;
pingJiaDao = mockControl.createMock(IPingJiaDao.class);
2. 设定 Mock 对象的预期行为和输出;
EasyMock.expect(pingJiaDao.getGoodPingJiaRate(storeId)).andReturn(0.11);
3. 将 Mock 对象切换到 Replay 状态;
EasyMock.replay(pingJiaDao);
4. 调用 Mock 对象方法进行单元测试;
storeService.setStoredao(pingJiaDao);
double rate = storeService.getStoreGoodRate(storeId);
5. 对 Mock 对象的行为进行验证。
EasyMock.verify(pingJiaDao);
4. 其他easyMock功能
1. 特殊的mock对象:niceMock
2. 参数匹配器
3. 重置mock对象
4. 模拟异常抛出
5. 设置调用次数
-
接口测试从零开始2------接口测试的全过程2
2011-12-07 19:55:05
代码实现
1. DAO实现,使用ibatis进行dao的实现
2. Service实现,数据插入,更新,获取,直接通过调用dao方法实现,业务逻辑在service中实现
可测试接口方法
1. 添加评价 boolean addPingJia(PingJia pingJia)
2. 更新评价 boolean updatePingJia(PingJia pingJia);
3. 删除评价 boolean deletePingJia(String pingjiaId)
4. 获得店铺星数 int getSotreStar(String storeId)
5. 得到店铺排序位置 getStoreIndex(String storeId)
6. 得到店铺好评率 int getStoreHaoPingLv(String storeId);
接口测试过程
1. @BeforeClass注解中,做初始化相关的操作,比如需要创建服务实例:storeService = new StoreService();
2. @Test注解中,编写具体的测试用例,编写测试用例时可用的一些技巧:
a. 通过不同的接口方法参数来实现对不同业务场景的覆盖
b. 接口参数如果是基本数据类型,比如String,则需要考虑该参数是做什么用的,是否需要在调用被测方法之前准备相应的数据,比如,获得店铺星数, getSotreStar(String storeId) 需要的参数是String类型的storeId,我们在测试的时候,在调用被测方法之前,就需要先为这个storeId对应的店铺构造评价,来满足对应的测试用例。
c. 接口参数如果是对象类型,则需要考虑是否可以通过独立的方法来提取设置对象属性过程,而将不同对象属性值通过方法参数传递,而如果对象属性过多,则可以考虑将部分对象属性构造为另外的一个对象
d. 调用被测方法后,需要根据被测方法返回值,断言被测方法是否返回期望结果,同时需要通过数据库验证
e. 如果一个测试用例中,涉及到多个步骤的验证,则需要在每个步骤后增加对应的验证方法。
f. 在测试用例中,针对该测试产生的数据,需要进行销毁。
3. @AfterClass注解中,增加对数据清理及对象销毁相应的方法
4. 关于数据库比对:可以将数据库操作,比对的方法专门提取为一个公共类。
-
接口测试从零开始2------接口测试的全过程1
2011-12-07 19:45:26
接口测试培训系列2------接口测试的全过程
在接口测试培训系列1中,描述了针对一个需求的实现方法,及对这个需求方法接口测试用例的设计,在本篇中,在该需求的基础上再增加需求,同时将需求扩展为一个小的项目,讲解针对项目的接口测试如何去做。
需求描述:
1. 增加店铺对象,评价属于店铺
2. 可以针对店铺增加评价,删除评价,修改评价
3. 根据店铺id获得店铺的星
4. 根据店铺id获得店铺的好评率
5. 根据店铺id获得店铺在所有店铺当中的排序,排序算法是:星越多排序越靠前,如果星相等,则根据好评率排序,好评率越高,排序越靠前,如果好评率相等,则评价越多越靠前,如果评价数相等,则默认当前店铺排名靠前。
实现思路:
1. 建立一个店铺类,具有店铺名称,店铺ID两个属性
2. 建立一个评价类,具有所属店铺id,评价类型,更新时间属性
3. 增加一个店铺操作类,具有增加评价,删除评价,修改评价,获取店铺星,获取店铺好评,获取店铺排序的方法
4. 建立一个数据库,里面有两张表,一张店铺表,一张评价表
5. 店铺表字段:店铺id,店铺名称
6. 评价表字段:所属店铺id,评价类型,更新时间
分层开发
1. DAO层:具体的对数据库的操作
public interface IPingJiaDao {
//插入一条记录
public boolean insert(PingJia pingJia);
// 修改评价记录
public boolean update(PingJia pingJia);
// 删除评价记录
public boolean delete(String pingJiaId);
//得到一个店铺的评价列表
public List<PingJia> getPingJiaList(String storeId);
//得到一个店铺的好评率
public double getGoodPingJiaRate(String storeId);
}
2. Service层:具体的业务逻辑层
public interface IStoreService {
//添加评价,
public boolean addPingJia(PingJia pingJia);
//修改评价类型
public boolean updatePingJia(PingJia pingJia);
//删除评价
public boolean deletePingJia(String pingjiaId);
//根据店铺Id,得到店铺的星数
public int getSotreStar(String storeId);
//得到店铺排序位置
public int getStoreIndex(String storeId);
//得到店铺好评率
public double getStoreGoodRate(String storeId);
}
-
接口测试从零开始系列1_如何针对接口方法设计测试用例
2011-12-06 18:37:45
需求内容:
功能描述: 店铺会有很多的评价,评价分两种类型,好评,差评,根据店铺的没个评价,确定这个店铺有多少个星 。具体的要求是
1. 评价分好评,差评
2. 连续5个好评可以转换为1个星,有一个差评,减少1个星
3. 最多有5个星
4. 初始星为0,最少有0个星
接口设计:
public interface IStoreService {
/**
* 根据店铺Id,得到店铺的星数
* @param storeId店铺id
* @return 店铺星数
*/
public int getSotreStar(String storeId);}
分析过程:
从需求角度分析,需要测试的点包括:
1. 店铺没有评价
2. 店铺全部差评
3. 店铺全部好评
4. 店铺有差评,有好评
5. 点评评价数小于5个
6. 店铺评价中,连续好评不够5个
7. 根据星计算规则,店铺所得星号大于5个
具体实现:
private int getStar(List<PingJia> pingJiaList) {
if (pingJiaList == null) {
System.out.println("评价列表不能为null");
return 0;
}
int star = 0;
int pingJiaCount = pingJiaList.size();
if (pingJiaCount < 5) {
return star;
}
int goodPing = 0;
for (int i = 0; i < pingJiaCount; i++) {
if (pingJiaList.get(i).getPingJiaType() == PingType.goodPing) {
goodPing++;
if (goodPing == 5) {
star++;
goodPing = 0;
}
} else {
goodPing = 0;
if (star > 0) {
star -= 1;
}
}
}
if (star > 5) {
star = 5;
}
return star;
}
用例设计
略
测试过程:
1. 分析需求,找出被测需求测试点:
2. 分析测试点,通过测试用例设计方法,准备测试数据,添加期望结果,提炼测试点为可执行测试用例
常用测试用例设计方法:
1. 边界值
2. 等价类
3. 场景法
4. 错误推测法
5. 针对参数测试
3. 根据测试用例,准备测试数据
4. 编写测试代码,调用被测代码,执行测试,断言测试结果
测试注意点
1. 代码测试依赖的是需求,而不是开发的代码
2. 代码测试的测试用例和功能测试用例类似,增加关于传入参数的验证
我的栏目
标题搜索
我的存档
数据统计
- 访问量: 299638
- 日志数: 108
- 图片数: 2
- 文件数: 5
- 建立时间: 2007-07-06
- 更新时间: 2012-12-21