jBPM学习笔记5--简单流程测试剖析
2011-01-11 11:14
435 查看
本章节,我们将给大家剖析两个流程测试类。一个是简单的基于内存模型的流程测试FirstFlowProcessTest;一个是更贴近实用的,基于MySQL数据库操作的标准测试案例。通过对这两个测试例程的分析,来直观的学习如何通过Java
API操作jPDL。
简单流程测试案例
测试案例类:FirstFlowProcessTest.java
该案例是在没有数据库支持的情况下,对报销流程进行运行测试,测试逻辑如下:
1. 加载流程定义
2. 实例化流程对象
代码说明:
在获得流程定义的实例后,可以用它生成流程实例,使用如下的语句:
pi = pdf.createProcessInstance();
流程实例拥有自己的ContextInstance环境变量对象。它实际上是一个HashMap,以key-value方式记录了流程的上下文变量值,代码中的
pi.getContextInstance().createVariable("initiator",
user);就是向环境变量中添加一个key为initiator的对象。
每个流程实例都拥有自己Token令牌对象,主流程有自己的RootToken,子流程也拥有自己的子Token。父流程的Token和子流程的Token相互关联,形成Token树。
Token对象表示流程运行的当前位置(运行到哪个节点了)。通过对Token对象的signal()方法调用,可以使流程向下运行。代码中的pi.signal();实际上是间接调用了pi.getRootToken().signal();它使得新建的流程继续向下个节点(即借款申请单填写)进发。
3. 员工发起借款申请
代码说明:
在借款流程发起后,流程进入了申请单填写阶段。这个阶段是个人工的任务,需要用户的介入。因此,对于要借款的用户而言,首先是获取填写申请单的任务实例:
TaskInstance ti =
(TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator()
.next()
在这个测试类中,由于没有数据库。对流程实例的引用是依靠了类的全局标量pi。这里通过pi获取全部的任务列表。实际上有且仅有一个任务,就是我们刚刚发起的申请单填写任务。
接下来,我们获取流程的上下文变量,将申请借款的数额记录在上下文变量中ContextInstance ci =
ti.getContextInstance();
ci.setVariable("money",new Integer(money));
最后,我们要结束当前任务,告诉流程继续下行,调用ti.end();
这个方法的本质依然是调用了token.signal(),它选择了一个默认的transition进行转向。这里要说明的是signal方法有多态的实现signal(Transition
transition),是可以指定具体转向参数的。
4. 部门领导审批申请
代码说明:
这里,流程进入了部门经理审批阶段。由于没有数据库支持,我们只能采取遍历任务列表,并比对委派者ID的方式来确定委派给部门经理的任务实例。(在后面的基于数据库的标准案例中,我们会看到如果根据用户的ID来获取分配给指定用户的任务)
ti.getActorId().equals("DepartmentManager") // 比对任务的委派人。
ti.getToken().getNode().getLeavingTransitions();//获取任务在当前节点上的所有转向。
这里我们要特别指出的是ti.end("部门经理审批通过")和ti.end("部门经理驳回")这实际上调用token.signal(transition);来完成任务的转向,从而使流程继续。
5. 总经理审批申请
代码说明:
此步代码同“部门经理审批”代码相似,不作更多说明。
API操作jPDL。
简单流程测试案例
测试案例类:FirstFlowProcessTest.java
public class FirstFlowProcessTest extends TestCase { ProcessDefinition pdf ; ProcessInstance pi; public void test4000YuanApplication() throws Exception { deployProcessDefinition(); createProcessInstance("linly"); submitApplication(4000); approveByManager(true); checkTasks(); } public void test6000YuanApplication() throws Exception { deployProcessDefinition(); createProcessInstance("linly"); submitApplication(6000); approveByManager(true); approveByPresident(true); checkTasks(); } public void test7000YuanApplication() throws Exception { deployProcessDefinition(); createProcessInstance("linly"); submitApplication(7000); approveByManager(true); approveByPresident(false); checkTasks(); } /** * 部署流程定义 * @throws Exception */ protected void deployProcessDefinition() throws Exception{ System.out.println("==FirstFlowProcessTest.deployProcessDefinition()=="); pdf = ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml"); assertNotNull("Definition should not be null", pdf); } /** * 生成流程实例 */ protected void createProcessInstance(String user){ System.out.println("==FirstFlowProcessTest.createProcessInstance()=="); assertNotNull("Definition should not be null", pdf); //生成实例 pi = pdf.createProcessInstance(); assertNotNull("processInstance should not be null", pi); //设置流程发起人 pi.getContextInstance().createVariable("initiator", user); //触发流程转向 pi.signal(); } /** * 填写提交申请单 * @param money */ protected void submitApplication(int money){ System.out.println("==FirstFlowProcessTest.submitApplication()=="); TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() ; System.out.println("ti.actor = " + ti.getActorId()); ContextInstance ci = ti.getContextInstance(); ci.setVariable("money",new Integer(money)); ti.end(); } /** * 部门经理审批 * @param pass */ @SuppressWarnings("unchecked") protected void approveByManager(boolean pass){ System.out.println("==FirstFlowProcessTest.approveByManager()=="); Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator(); for( ;it.hasNext(); ){ TaskInstance ti = it.next(); if(ti.getActorId().equals("DepartmentManager")){ List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions(); for(Transition t : transitions){ System.out.println("----Transition" + t.getName()); } assertEquals("DepartmentManager",ti.getActorId()); if(pass){ ti.end("部门经理审批通过"); }else{ ti.end("部门经理驳回"); } return; } } } /** * 总经理审批 * @param pass */ @SuppressWarnings("unchecked") protected void approveByPresident(boolean pass){ System.out.println("==FirstFlowProcessTest.approveByPresident()=="); Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator(); for( ;it.hasNext(); ){ TaskInstance ti = it.next(); if(ti.getActorId().equals("President")){ List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions(); for(Transition t : transitions){ System.out.println("----Transition" + t.getName()); } assertEquals("President",ti.getActorId()); if(pass){ ti.end("总经理审批通过"); }else{ ti.end("总经理驳回"); } return; } } } /** * 打印任务记录 */ @SuppressWarnings("unchecked") protected void checkTasks(){ System.out.println("==FirstFlowProcessTest.checkTasks()=="); Collection<TaskInstance> coll = pi.getTaskMgmtInstance().getTaskInstances(); System.out.println("====Process has task:===="); for(TaskInstance ti : coll){ System.out.println("=="+ti.getName()+"=="); System.out.println("=="+ti.getActorId()+"=="); System.out.println("=="+ti.getVariables().toString() +"=="); } System.out.println("====end===="); }
该案例是在没有数据库支持的情况下,对报销流程进行运行测试,测试逻辑如下:
1. 加载流程定义
ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")
2. 实例化流程对象
//生成实例 pi = pdf.createProcessInstance(); assertNotNull("processInstance should not be null", pi); //设置流程发起人 pi.getContextInstance().createVariable("initiator", user); //触发流程转向 pi.signal();
代码说明:
在获得流程定义的实例后,可以用它生成流程实例,使用如下的语句:
pi = pdf.createProcessInstance();
流程实例拥有自己的ContextInstance环境变量对象。它实际上是一个HashMap,以key-value方式记录了流程的上下文变量值,代码中的
pi.getContextInstance().createVariable("initiator",
user);就是向环境变量中添加一个key为initiator的对象。
每个流程实例都拥有自己Token令牌对象,主流程有自己的RootToken,子流程也拥有自己的子Token。父流程的Token和子流程的Token相互关联,形成Token树。
Token对象表示流程运行的当前位置(运行到哪个节点了)。通过对Token对象的signal()方法调用,可以使流程向下运行。代码中的pi.signal();实际上是间接调用了pi.getRootToken().signal();它使得新建的流程继续向下个节点(即借款申请单填写)进发。
3. 员工发起借款申请
/** * 填写提交申请单 * @param money */ protected void submitApplication(int money){ System.out.println("==FirstFlowProcessTest.submitApplication()=="); TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() System.out.println("ti.actor = " + ti.getActorId()); ContextInstance ci = ti.getContextInstance(); ci.setVariable("money",new Integer(money)); ti.end(); }
代码说明:
在借款流程发起后,流程进入了申请单填写阶段。这个阶段是个人工的任务,需要用户的介入。因此,对于要借款的用户而言,首先是获取填写申请单的任务实例:
TaskInstance ti =
(TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator()
.next()
在这个测试类中,由于没有数据库。对流程实例的引用是依靠了类的全局标量pi。这里通过pi获取全部的任务列表。实际上有且仅有一个任务,就是我们刚刚发起的申请单填写任务。
接下来,我们获取流程的上下文变量,将申请借款的数额记录在上下文变量中ContextInstance ci =
ti.getContextInstance();
ci.setVariable("money",new Integer(money));
最后,我们要结束当前任务,告诉流程继续下行,调用ti.end();
这个方法的本质依然是调用了token.signal(),它选择了一个默认的transition进行转向。这里要说明的是signal方法有多态的实现signal(Transition
transition),是可以指定具体转向参数的。
4. 部门领导审批申请
/** * 部门经理审批 * @param pass */ @SuppressWarnings("unchecked") protected void approveByManager(boolean pass){ System.out.println("==FirstFlowProcessTest.approveByManager()=="); Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator(); for( ;it.hasNext(); ){ TaskI a25c nstance ti = it.next(); if(ti.getActorId().equals("DepartmentManager")){ List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions(); for(Transition t : transitions){ System.out.println("----Transition" + t.getName()); } assertEquals("DepartmentManager",ti.getActorId()); if(pass){ ti.end("部门经理审批通过"); }else{ ti.end("部门经理驳回"); } return; } } }
代码说明:
这里,流程进入了部门经理审批阶段。由于没有数据库支持,我们只能采取遍历任务列表,并比对委派者ID的方式来确定委派给部门经理的任务实例。(在后面的基于数据库的标准案例中,我们会看到如果根据用户的ID来获取分配给指定用户的任务)
ti.getActorId().equals("DepartmentManager") // 比对任务的委派人。
ti.getToken().getNode().getLeavingTransitions();//获取任务在当前节点上的所有转向。
这里我们要特别指出的是ti.end("部门经理审批通过")和ti.end("部门经理驳回")这实际上调用token.signal(transition);来完成任务的转向,从而使流程继续。
5. 总经理审批申请
/** * 总经理审批 * @param pass */ @SuppressWarnings("unchecked") protected void approveByPresident(boolean pass){ System.out.println("==FirstFlowProcessTest.approveByPresident()=="); Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator(); for( ;it.hasNext(); ){ TaskInstance ti = it.next(); if(ti.getActorId().equals("President")){ List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions(); for(Transition t : transitions){ System.out.println("----Transition" + t.getName()); } assertEquals("President",ti.getActorId()); if(pass){ ti.end("总经理审批通过"); }else{ ti.end("总经理驳回"); } return; } } }
代码说明:
此步代码同“部门经理审批”代码相似,不作更多说明。
相关文章推荐
- JAVA学习笔记_Junit测试简单使用_assertEquals
- jBPM学习笔记3--流程的部署
- spark学习笔记之三:调度流程剖析
- tensorflow 学习笔记(四) - mnist实例--用简单的神经网络来训练和测试
- Linux 学习笔记_5_Linux引导流程解析_2_inittab文件剖析及系统启动流程分析
- J2EE学习笔记二:配置一个简单的J2EE测试环境
- webkit学习笔记1---webcore简单执行流程
- Struts 1 学习笔记-5-1(Struts中I18N的简单测试)
- jBPM-jPDL学习笔记——流程设计与控制
- maven 学习笔记(三)-创建简单的eclipse+android+maven工程2(带子测试工程)
- node.js学习笔记(二)--使用mongoose简单的CRUD操作及测试模块mocha的使用
- JBPM创建数据库,流程定义以及发布学习笔记
- zeromq学习笔记2——简单的客户端和服务端测试程序
- jmeter学习_2(创建一个测试用例的简单流程)
- MyBatis学习笔记(一)----简单的环境搭建及测试Demo
- 软件测试学习笔记之二 测试流程
- 基于《Selenium 2自动化测试实战》的学习笔记(4)—— 简单对象的定位
- tensorflow学习笔记四:mnist实例--用简单的神经网络来训练和测试
- jfinal学习笔记【3】-freemarker简单测试-laymi(雷米快速开发平台)
- Linux——系统引导流程学习简单笔记