关于 phoenixframework 测试平台的说明,请见贴:https://testerhome.com/topics/4632,本篇主要说明一下环境搭建及使用方法。有了上次的经验,本篇文章我尽量写的完整,达到通过这篇文章就能顺利的将环境搭建起来目的。本来也想建立一个 wiki 目录,有关该平台的信息放到一起,但没有找到创建 wiki 的帮助文档,若管理员看到此篇文章,请帮忙发个创建 wiki 的方法啊,我会及时处理。
本人比较笨,开发这平台从有这个想法到基本完成过程中,也是慢慢的不断向高手学习请教,自己还算勤奋,代码一行行的也都敲出来了,反正过程中完全是凭着一颗执着的心和情怀驱使完成的,尽管如此,肯定还有诸多的不完善和有待改进的地方。所以,大家如果对这个平台有任何意见或不满意的地方,欢迎拍砖,但请轻拍啊~~。我会参考各位的意见,不断的去完善和改进它。另外需要说明的是,这个平台是取之互联网也将用之互联网,永远不会收费。
一、环境搭建过程
1、环境搭建前
平台支持在 Linux 和 Windows,环境搭建前,请在系统中安装 JDK 1.7 及以上版本和 tomcat 等服务器,还要劳烦去网盘中(网盘地址:http://pan.baidu.com/s/1c1hOxv6)获取以下附件:
(1)phoenix_web.war:平台的控制端,管理平台的数据和各个 node 节点
(2)phoenix_node.war:平台的节点,用于执行测试用例
(3)phoenix_develop:普通 j2se 工程,用于开发调试脚本。将此工程导入到 eclipse 等开发工具中,在这个工程中可以开发 webUI,mobile,及接口测试业务逻辑代码。
(4)phoenix_gui.sql:平台 mysql 数据库结构初始化。创建 MySQL,数据库名:phoenix_gui
(5)dataInit.sql:初始化一些数据,如初始的用户名
2、部署过程
(1)将 phoenix_web.war,phoenix_node.war 放到 tomcat 等的 webapp 目录下,启动 tomcat。phoenix_web.war,phoenix_node.war 部署到同一个 tomcat 或将 phoenix_node.war 部署到多个 tomcat 下要看具体测试需求。
(2)修改数据库连接方式。Node 节点数据库默认连接方式修改地址如:..\apache-tomcat-8.0.9\webapps\phoenix_node\WEB-INF\classes\hibernate.cfg.xml,找到相关用户名和密码进行修改。Phoenix_web 则修改:jdbc.propertes 中的用户名和密码。
(3)修改完成后,重启 tomcat 即可。
(4)访问:http://localhost:8080/phoenix_web/
,端口及 host 根据部署的情况指定即可。页面打开后,使用 admin / admin 登陆系统。
3、部署完成后
(1)添加 node 节点,使其受控制台控制。在平台控制端的 ‘执行机管理’ 菜单下添加 node 节点的 host 与端口,格式:localhost:8080,80 端口的话可不用添加端口,直接填写如:localhost 即可。在节点状态下,可以看到添加的 node 分机的状态。如:http://localhost:8080/phoenix_node/
(2)可修改..\apache-tomcat-8.0.9\webapps\phoenix_web\WEB-INF\classes\beans.xml 配置文件中的 Email 服务器,及 mail.setFrom 信息,否则将不能发送任务失败时的邮件, 为自动扫描 t_msgpool 的频率,为 10 秒一次,可修改成适当规则。其他配置建议不要修改。
(3)管理员账户,可在系统管理—用户管理下增删改用户信息。普通账户只能修改个人信息。
二、平台的基本使用
1、创建场景及用例
在场景管理下新增测试场景,一个场景将包含多个测试用例。平台的最小执行单位是用例。
2、为用例添加执行脚本
在用例管理菜单下,找到创建的用例,单击编辑脚本,在打开的页面中将在 phoenix_develop 中创建的业务逻辑代码复制粘贴到脚本内容文本域中,需要说明的是,UI 及接口测试的业务逻辑代码的开发必须严格按照平台的模板,否则会编译失败或者收集不到执行结果日志,可批量导入导出测试数据。如图:
3、创建测试任务
通过测试任务,可以将用例分配给指定的执行机(node 节点),由执行机来完成任务的执行及日志收集。任务分配及任务修改界面如下:
4、在任务列表界面点击启动,即可启动任务。任务执行过程中,可在任务界面看到进展。任务执行完成后,点击任务状态则会跳转到对应的日志界面。如图:
详细信息界面列出了详细的执行步骤及步骤的通过失败截图等信息。如:
统计图则统计了本次用例或场景执行的步骤及检查点的通过失败数,场景的统计是以折线图形式展示。如用例的统计图:
三、相关用例类型的 Demo 代码实例
以下演示的代码来自:phoenix_develop 工程,且代码只能在该工程下才能调试通过。
1、webUI 测试(支持在 Linux 及 Windows 下执行)
/**
* 定位信息使用本地数据的方法
* @author mengfeiyang
*
*/
public class TestPhoenixCaseUseLocator extends WebElementActionProxy{
private static String caseName = "消息测试用例";//用例的名称或id都能加载到该用例下的定位信息和数据
//private static int caseName = 5;//用例的id
public TestPhoenixCaseUseLocator() {
}
@Override
public LinkedList<UnitLogBean> run(CaseLogBean caseLogBean) {
init(caseName,caseLogBean);
//webProxy.openNewWindowByIE("http://www.baidu.com");
//webProxy.openNewWindowByFirefox("http://www.baidu.com");//首先需要指定Firefox.exe的路径,方法是:webProxy.setFirefoxExePath(arg0);
//webProxy.openNewWindowByChrome("http://www.baidu.com");//首先需要指定ChromeDriver.exe的路径,方法是:webProxy.setChromeDriverExePath(arg0);
webProxy.openNewWindowByPhantomJs("http://www.baidu.com");
webProxy.webElement("#kw",null).setText("1");
String s = webProxy.webElement("#su",null).getAttrValue("value");
System.out.println(s);
webProxy.checkPoint().checkIsEqual("百度一下", s);
webProxy.webElement("#su",LocatorType.CSS).click();
webProxy.checkPoint().checkIsFalse(s!=null);
webProxy.sleep(5000);
Iterator<SelenideElement> els = webProxy.webElementLinkFinder(".s_tab",null).$$(By.tagName("a")).iterator();
while(els.hasNext()){
SelenideElement se = els.next();
if(se.getText().equals("文库")){
se.click();
break;
}
System.out.println(se.getText());
}
webProxy.closeWindow();
return getUnitLog();
}
public static void main(String[] args) {
TestPhoenixCaseUseLocator t = new TestPhoenixCaseUseLocator();
LinkedList<UnitLogBean> ll = t.run(new CaseLogBean());
for(UnitLogBean l : ll){
System.out.println(l.getContent());
}
}
}
2、接口测试
/**
* 使用phoenix做接口测试的案例,:<br>
* 设置代理<br>
* 若对wsdl形式的接口做测试,则wsdl的文件需要以Dom方式解析。使用WebResponse中的Dom即可。
* @author mengfeiyang
*
*/
public class HostTestByHttpClient extends WebElementActionProxy{
private static String caseName = "接口测试用例";
public HostTestByHttpClient() {
}
@Override
public LinkedList<UnitLogBean> run(CaseLogBean arg0) {
init(caseName,arg0);
HashMap<String,String> headers = new HashMap<String,String>();
headers.put("Accept-Language", "Accept-Language: en,zh");
headers.put("Accept-Charset", "Accept-Charset: iso-8859-1");
//执行的步骤日志,将有平台自动收集
HttpClient httpClient = webProxy.webAPIAction().getHttpClientWithProxy("10.138.65.213", 80, "", "");
HttpResponse response = webProxy.webAPIAction().getResponseByHttpClient(httpClient, "http://trunk.dianjing.e.360.cn", "get", headers);
try {
System.out.println(Arrays.toString(response.getAllHeaders()));
System.out.println(IOUtils.toString(response.getEntity().getContent()));
webProxy.checkPoint().checkIsEqual(response.getStatusLine().getStatusCode(), 200);//记录日志
} catch (Exception e) {
e.printStackTrace();
webProxy.checkPoint().checkIsEqual(e.getMessage(), 200); //将在日志中记录失败原因
}
return getUnitLog();
}
public static void main(String[] args) {
HostTestByHttpClient yw = new HostTestByHttpClient();
LinkedList<UnitLogBean> ll = yw.run(new CaseLogBean());
for(UnitLogBean l : ll){
System.out.println(l.getContent());
}
}
}
3、对 svn 的操作
/**
* svn客户端测试,通过获取开发提交的代码来自动启动对应的测试用例
* @author mengfeiyang
*
*/
public class SvnPluginTest extends WebElementActionProxy{
@Override
public LinkedList<UnitLogBean> run(CaseLogBean arg0) {
init("",arg0);
ISvnClient svnClient = webProxy.svnClient().configSvnClient(
"http://svn.svnkit.com/repos/svnkit/trunk/gradlew",
"anonymous",
"anonymous",
""
);
List<SvnLogModel> logList = svnClient.displaySvnLog();
for(SvnLogModel s : logList){
//获取提交代码的开发人员名称 ,可根据开发人员名称,提交信息,代码路径来调用测试用例
System.out.println(s.getAuthor());
System.out.println(s.getMessage());//获取提交代码信息
for(String sl : s.getChangedPaths()){
System.out.println(sl);//获取提交代码的路径
webProxy.checkPoint().checkNotNull(sl);
}
}
return getUnitLog();
}
public static void main(String[] args) {
SvnPluginTest p = new SvnPluginTest();
LinkedList<UnitLogBean> ll = p.run(new CaseLogBean());
for(UnitLogBean l : ll){
System.out.println(l.getContent());
}
}
}
4、对 Android app 的测试(Android browser 的测试与 webUI 开发一致,只是驱动不同)
启动本用例前,请先在本地安装并调试好 Android 虚拟机或实体机,用例启动时,会自动启动虚拟机或实体机。
/**
* android基本操作测试
* @author mengfeiyang
*
*/
public class AndroidBaseTest extends WebElementActionProxy{
@Override
public LinkedList<UnitLogBean> run(CaseLogBean arg0) {
init("",arg0);
webProxy.openAndroidAppBySelendroidWithEmulator("F:\\baozhanggl.apk");//apk的物理路径
WebElement el = webProxy.appElementLinkFinder("#TextField1", null);
String tagN = el.getTagName();
String valN = el.getText();
System.out.println("TagName:"+tagN+" value:"+valN);
webProxy.checkPoint().checkIsNull(tagN);
webProxy.checkPoint().checkIsEqual("Hello", valN);
webProxy.appElement("#TextField2", null).appElementSetText("shuruceshi");
webProxy.appElement("#gaoji", null).appElementClick();
webProxy.appElement("#chushimima", LocatorType.ID).appElementSetText("test123");
//根据XPath定位app元素,XPath无需手写,用例编写过程中可通过录制方式获取
webProxy.appElement("(//TextView[@id='text1'])[1]", LocatorType.XPATH).appElementClick();
webProxy.appElement("(//CheckedTextView[@id='text1'])[2]", LocatorType.XPATH).appElementClick();
WebElement v = webProxy.appElementLinkFinder("//Button[@id='button1']", LocatorType.XPATH);
System.out.println(v.getText());
webProxy.checkPoint().checkIsEqual("查询", v.getText());
webProxy.appElement("//Button[@id='button1']", LocatorType.XPATH).appElementClick();
webProxy.pressKeyByKeyboard("\uE100");//操作Android硬件,本次点击的是返回键
webProxy.checkPoint().checkNotNull(webProxy.getSelendroidDriver().getBrightness());
webProxy.setBrightness(80);//调整Android屏幕的亮度为80
webProxy.setBrightness(40);
webProxy.closeSelendroidServer();//关闭本次与Android设备上server的连接
return getUnitLog();
}
public static void main(String[] args) {
AndroidBaseTest p = new AndroidBaseTest();
LinkedList<UnitLogBean> ll = p.run(new CaseLogBean());
for(UnitLogBean l : ll){
System.out.println(l.getContent());
}
}
}
5、操作远程 socket 服务器,并接收响应内容
/**
* Telnet客户端测试,向远程的socket服务器发送指令,并接收服务器的响应内容
* @author mengfeiyang
*
*/
public class TelnetPluginTest extends WebElementActionProxy{
@Override
public LinkedList<UnitLogBean> run(CaseLogBean arg0) {
init("",arg0);
//连接SocketServer
ITelnetClient telnet = webProxy.telnetClient().configTelnetClient("localhost", 8889);
String rs = telnet.sendCommand("!showorders", "datas");//向socketServer发送指令,如果返回值以datas结尾,则终止数据接收
System.out.println(rs);
webProxy.checkPoint().checkIsNull(rs);
String rs2 = telnet.sendCommand("!showusers", "]");
System.out.println(rs2);
webProxy.checkPoint().checkIsNull(rs2);
telnet.disconnect();//断开本次的连接
return getUnitLog();
}
public static void main(String[] args) {
TelnetPluginTest p = new TelnetPluginTest();
LinkedList<UnitLogBean> ll = p.run(new CaseLogBean());
for(UnitLogBean l : ll){
System.out.println(l.getContent());
}
}
}
其他更多的实例代码,请见网站:http://www.cewan.la,或加入我们的 QQ 交流群:246776066,或关注平台的微信公众号:phoenixframework
在以上的交流方式中都可以给我留言和实时沟通。 当然,在这个社区中留言,我也会及时的回复,谢谢啦!
如果觉得这个平台对您有帮助,或如果您对这个平台感兴趣,劳烦给个 “赞” 啊。
最后多啰嗦一句啊,平台是永远开源不收费的,我是抱着和大家互相交流的心态才发的贴,只有不断和高手交流才会知道自己的不足,才会知道该从哪些地方改进,呵呵。欢迎拍砖,但轻点啊-_-。。。,若管理员看到这个帖子并觉得本文格式方面有需要改正的地方,请留言提醒,我将及时修正。