开源测试工具 开源自动化测试平台 phoenixframework 环境搭建及使用

mengfeiyang · 2016年04月18日 · 最后由 大白 回复于 2016年09月27日 · 80 次阅读
本帖已被设为精华帖!

          关于 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
在以上的交流方式中都可以给我留言和实时沟通。 当然,在这个社区中留言,我也会及时的回复,谢谢啦!

如果觉得这个平台对您有帮助,或如果您对这个平台感兴趣,劳烦给个 “赞” 啊。

最后多啰嗦一句啊,平台是永远开源不收费的,我是抱着和大家互相交流的心态才发的贴,只有不断和高手交流才会知道自己的不足,才会知道该从哪些地方改进,呵呵。欢迎拍砖,但轻点啊-_-。。。,若管理员看到这个帖子并觉得本文格式方面有需要改正的地方,请留言提醒,我将及时修正。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 14 条回复 时间 点赞

这么好的文章为啥没人顶哈,已 mark!

#1 楼 @tspring 哈哈,谢谢

几天没来了,是不是还差一个赞就能上精华贴了?哈哈,哪个小伙伴帮忙支持一下啊

棒👍🏻

#4 楼 @kekeguo 谢谢支持,互相交流啊

已经是精华帖了,社区效率好高啊,赞!!!

细致的地方值得学习,赞!!!

#7 楼 @mars_shi0315 谢谢,还有些功能没加,待功能都完善之后,还有一些细节需要调整,但整体结构不会动了

很好很干的文章!

干货 啊 可惜看的不是很懂...

#9 楼 @miyawang 谢谢支持

#10 楼 @sysayy 有不懂地方可以直接在这给我留言:http://www.cewan.la/feedback/qq 群:246776066,里面还有很多大牛~~,或加入我们的

平台最近更新到了 1.4.8u2,修复了一些 bug,也添加了更多好用功能。感兴趣的去下载源码吧,http://www.cewan.la

好文章,点了赞

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册