IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Agile PLM 进程扩展调试方式总结 -> 正文阅读

[开发测试]Agile PLM 进程扩展调试方式总结

需求描述

目前进程扩展项目代码写好之后,无法很好的进行调试,只能放到环境直接进行功能测试。

最好能有一种方式在功能测试之前,可以让开发人员提前调试自己的代码。

实现思路

目前项目中主要有如下方式可以调试代码。

  1. 单元测试。新建单元测试用例,构造入参,调试主方法。
  2. 远程调试。开启Agile的远程debug选项,进行业务操作时会进入到本地的断点中。

实现细节

单元测试

这种方式适合很多业务场景。但前提是必须要准确的构造入参。否则不一定能准确的重现正式环境的问题。

入参构造

一般常见的入参有:IAgileSession,INode,IEventInfo,可以写一个单元测试专用的类IAgileTestUtils,参考代码如下:

package com.purvar.agile.utils;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import com.agile.api.APIException;
import com.agile.api.AgileSessionFactory;
import com.agile.api.IAgileSession;
import com.agile.api.IDataObject;
import com.agile.api.ISignoffReviewer;
import com.agile.api.IStatus;
import com.agile.api.IWorkflow;
import com.agile.px.IEventDirtyCell;
import com.agile.px.IEventInfo;
import com.agile.px.IRoutableObjectEventInfo;
import com.agile.px.ISaveAsEventInfo;
import com.agile.px.ISignOffEventInfo;
import com.agile.px.IUpdateEventInfo;
import com.agile.px.IWFChangeStatusEventInfo;

/**
 * 本类仅供单元测试使用,请勿在正式的功能代码中使用本类的任何方法.会报异常的<br>
 * @deprecated 本类的所有方法仅供单元测试使用,请勿在正式功能中使用
 * @author namelessmyth
 * @see [相关类/方法]
 * @since [2016年11月24日]
 * @version 1.0 2016年11月24日
 */
public class IAgileTestUtils {
	/**
	 * 构造AgileSession,仅供单元测试使用
	 
	 * @author namelessmyth
	 * @since [2016年11月24日]
	 */
	public static IAgileSession getSession(String type) {
		IAgileSession session = null;
		String username = "admin";
		String pwd = "tartan";
		String url = null;
		if ("dev".equals(type)) {
			url = "http://192.168.2.134:7001/Agile";
		} else if ("test".equals(type)) {
			url = "http://10.8.0.25:7001/Agile";
		} else if ("prod".equals(type)) {
			url = "http://10.8.0.20:7001/Agile";
		} else {
			throw new RuntimeException("请指定正确的PLM环境类型,'prod'代表正式环境,请谨慎使用");
		}
		HashMap<Integer, String> params = new HashMap<Integer, String>();
		params.put(AgileSessionFactory.USERNAME, username);
		params.put(AgileSessionFactory.PASSWORD, pwd);
		params.put(AgileSessionFactory.URL, url);
		try {
			session = AgileSessionFactory.createSessionEx(params);
		} catch (APIException e) {
			throw new RuntimeException("连接PLM错误", e);
		}
		return session;
	}

	/**
	 * 创建一个测试用的批准事件<br>
	 * 
	 * @param data 事件中的数据对象
	 * @return IEventInfo
	 * @author namelessmyth
	 * @since [2016年7月20日]
	 */
	public static IEventInfo createISignOffEventInfo(final IDataObject data) {
		IEventInfo event = new ISignOffEventInfo() {

			public void setUserDefinedMap(Map arg0) throws APIException {
			}

			public Map getUserDefinedMap() throws APIException {
				return null;
			}

			public int getEventType() throws APIException {
				return 0;
			}

			public int getEventTriggerType() throws APIException {
				return 1;
			}

			public String getEventSubscriberName() throws APIException {
				return "事件订户名称";
			}

			public String getEventName() throws APIException {
				return "测试专用事件名称";
			}

			public String getEventHandlerName() throws APIException {
				return "事件处理器";
			}

			public IDataObject getDataObject() throws APIException {
				return data;
			}

			public IWorkflow getWorkFlow() throws APIException {
				return null;
			}

			public void setNotifyReviewers(boolean arg0) throws APIException {
			}

			public void setNotifyReviewerOption(int arg0) throws APIException {
			}

			public void setNotifyOriginator(boolean arg0) throws APIException {
			}

			public void setNotifyChangeAnalyst(boolean arg0) throws APIException {
			}

			public void setNotifiers(Collection arg0) throws APIException {
			}

			public void setComments(String arg0) throws APIException {
			}

			public boolean isNotifyReviewers() throws APIException {
				return false;
			}

			public boolean isNotifyOriginator() throws APIException {
				// TODO Auto-generated method stub
				return false;
			}

			public boolean isNotifyChangeAnalyst() throws APIException {
				return false;
			}

			public int getNotifyReviewerOption() throws APIException {
				return 0;
			}

			public IDataObject[] getNotifiers() throws APIException {
				return null;
			}

			public String getComments() throws APIException {
				return null;
			}

			public void setUrgent(boolean arg0) throws APIException {
			}

			public void setTransferUsers(Collection arg0) throws APIException {
			}

			public void setSignoffForSelf(boolean arg0) throws APIException {
			}

			public void setSignoffForGroups(Collection arg0) throws APIException {
			}

			public void setEscalationUsers(Collection arg0) throws APIException {
			}

			public boolean isUrgent() throws APIException {
				return false;
			}

			public boolean isSignoffForSelf() throws APIException {
				return false;
			}

			public IDataObject[] getTransferUsers() throws APIException {
				return null;
			}

			public IStatus getStatus() throws APIException {
				return null;
			}

			public ISignoffReviewer[] getSignoffForGroups() throws APIException {
				return null;
			}

			public IDataObject[] getEscalationUsers() throws APIException {
				return null;
			}
		};
		return event;
	}

	public static IEventInfo createIUpdateEventInfo(final IDataObject data) {
		IEventInfo event = new IUpdateEventInfo() {

			public IDataObject getDataObject() throws APIException {
				return data;
			}

			public String getEventHandlerName() throws APIException {
				return null;
			}

			public String getEventName() throws APIException {
				return null;
			}

			public String getEventSubscriberName() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			public int getEventTriggerType() throws APIException {
				return 0;
			}

			public int getEventType() throws APIException {
				return 0;
			}

			public Map getUserDefinedMap() throws APIException {
				return null;
			}

			public void setUserDefinedMap(Map arg0) throws APIException {
			}

			public Integer[] getAttributeIds() throws APIException {
				return new Integer[] { 1003 };
			}

			public IEventDirtyCell getCell(Object arg0) throws APIException {
				return null;
			}

			public IEventDirtyCell[] getCells() throws APIException {
				return null;
			}

			public Object getValue(Object arg0) throws APIException {
				return null;
			}

			public void removeCell(Object arg0) throws APIException {
			}

			public IEventDirtyCell setCell(Object arg0, Object arg1) throws APIException {
				return null;
			}
		};
		return event;
	}

	public static IEventInfo createISaveAsEventInfo(final String newNumber, final Integer newSubclassId) {
		IEventInfo event = new ISaveAsEventInfo() {

			public void setUserDefinedMap(Map arg0) throws APIException {
			}

			public Map getUserDefinedMap() throws APIException {
				return null;
			}

			public int getEventType() throws APIException {
				return 0;
			}

			public int getEventTriggerType() throws APIException {
				return 0;
			}

			public String getEventSubscriberName() throws APIException {
				return null;
			}

			public String getEventName() throws APIException {
				return null;
			}

			public String getEventHandlerName() throws APIException {
				return null;
			}

			public IDataObject getDataObject() throws APIException {
				return null;
			}

			public IEventDirtyCell setCell(Object arg0, Object arg1) throws APIException {
				return null;
			}

			public void removeCell(Object arg0) throws APIException {

			}

			public Object getValue(Object arg0) throws APIException {
				return null;
			}

			public IEventDirtyCell[] getCells() throws APIException {
				return null;
			}

			public IEventDirtyCell getCell(Object arg0) throws APIException {
				return null;
			}

			public Integer[] getAttributeIds() throws APIException {
				return new Integer[] { 1081 };
			}

			public void setNewSubclassId(Integer arg0) throws APIException {
			}

			public void setNewNumber(String arg0) throws APIException {

			}

			public Integer getNewSubclassId() throws APIException {
				return newSubclassId;
			}

			public String getNewNumber() throws APIException {
				return newNumber;
			}
		};
		return event;
	}

	/**
	 * 创建一个测试用的抽象事件父类<br>
	 * 
	 * @param data 事件中的数据对象
	 * @return IEventInfo
	 * @author namelessmyth
	 * @since [2016年7月20日]
	 */
	public static IRoutableObjectEventInfo createIRoutableObjectEventInfo(final IDataObject data) {
		IRoutableObjectEventInfo event = new IRoutableObjectEventInfo() {

			public void setUserDefinedMap(Map arg0) throws APIException {
			}

			public Map getUserDefinedMap() throws APIException {
				return null;
			}

			public int getEventType() throws APIException {
				return 0;
			}

			public int getEventTriggerType() throws APIException {
				return 1;
			}

			public String getEventSubscriberName() throws APIException {
				return "事件订户名称";
			}

			public String getEventName() throws APIException {
				return "文件发布流程邮件补发程序";
			}

			public String getEventHandlerName() throws APIException {
				return "事件处理器";
			}

			public IDataObject getDataObject() throws APIException {
				return data;
			}

			public IWorkflow getWorkFlow() throws APIException {
				return null;
			}
		};
		return event;
	}

	/**
	 * 创建一个测试用的状态变更事件<br>
	 * 
	 * @param data 事件中的数据对象
	 * @return IEventInfo
	 * @author namelessmyth
	 * @since [2016年7月20日]
	 */
	public static IWFChangeStatusEventInfo createIWFChangeStatusEventInfo(final IDataObject obj) {
		IWFChangeStatusEventInfo event = new IWFChangeStatusEventInfo() {
			@Override
			public void setUserDefinedMap(Map arg0) throws APIException {

			}

			@Override
			public Map getUserDefinedMap() throws APIException {
				return null;
			}

			@Override
			public int getEventType() throws APIException {
				return 0;
			}

			@Override
			public int getEventTriggerType() throws APIException {
				return 0;
			}

			@Override
			public String getEventSubscriberName() throws APIException {
				return null;
			}

			@Override
			public String getEventName() throws APIException {
				return null;
			}

			@Override
			public String getEventHandlerName() throws APIException {
				return null;
			}

			@Override
			public IDataObject getDataObject() throws APIException {
				return obj;
			}

			@Override
			public IWorkflow getWorkFlow() throws APIException {
				return null;
			}

			@Override
			public void setUrgent(boolean arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public void setObservers(Collection arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public void setComments(String arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public void setApprovers(Collection arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public void setAcknowledgers(Collection arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public boolean isUrgent() throws APIException {
				// TODO Auto-generated method stub
				return false;
			}

			@Override
			public ISignoffReviewer[] getObservers() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public String getComments() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public ISignoffReviewer[] getApprovers() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public ISignoffReviewer[] getAcknowledgers() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public void setNotifiers(Collection arg0) throws APIException {
				// TODO Auto-generated method stub

			}

			@Override
			public boolean isAutoPromote() throws APIException {
				// TODO Auto-generated method stub
				return false;
			}

			@Override
			public IStatus getToStatus() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public IDataObject[] getNotifiers() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public IStatus getFromStatus() throws APIException {
				// TODO Auto-generated method stub
				return null;
			}
		};
		return event;
	}
}

新建单元测试用例

Eclipse

打开要测试的类上选择File->new,选择单元测试用例。然后next

?选择junit4,如果是第一次新建单元测试用例,eclipse会自动将junit4库加入到classpath里面。然后选择单元测试专用的源代码目录。

?构造入参,调用已经写好的doAction方法:

	@Test
	public void testDoActionIActionParam() throws Exception {
		IAgileSession session = IAgileTestUtils.getSession("dev");
		IItem change = (IItem)session.getObject(IItem.OBJECT_TYPE, "P00005");
		IEventInfo event = IAgileTestUtils.createIUpdateEventInfo(change);
		new AutoSetValueEvent().doAction(session, null, event);
	}

然后在单元测试类里面右击选择debug as -> junit test 就可以调试程序了.

远程debug

环境准备

首先找一个没有人使用的环境,因为debug的时候会阻塞其他用户的操作。直到释放断点。

本文使用的Vmware本地虚拟机。网络适配器建议选择"NAT"和桥接模式。

注意:经测试“仅主机模式”是不行的。

在Agile的应用服务器目录中找到setDomainEnv.bat中开启debug选项。(具体的细节涉及信息安全不便贴出,需要的小伙伴可以联系我获取)。

然后进入到IDE的远程debug配置界面。本文以Eclipse为例:

启动远程debug模式。然后在环境中执行出触发程序的相关操作。就会进入到调试窗口了。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-02-04 11:19:58  更:2022-02-04 11:20:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:51:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码