背景

        Jenkins做集成测试是不错的工具,那么UI自动化是否可以,appium与testng结合能否集成到jenkins中去做定时运行。如果要执行,先解决jenkins怎么识别testng:

  • 通过pom文件执行
  • 通过调用main方式testng

今天只演示通过main方式执行testng

一、生成xml文件

1、创建xml方法


1. import org.dom4j.Document;
2. import org.dom4j.DocumentHelper;
3. import org.dom4j.Element;
4. import org.dom4j.io.OutputFormat;
5. import org.dom4j.io.XMLWriter;
6. import java.io.FileNotFoundException;
7. import java.io.FileOutputStream;
8. import java.io.IOException;
9. import java.io.UnsupportedEncodingException;
10. import java.util.Properties;
11. 
12. /**
13.  * @author liwen
14.  * @Title: createTestngXml
15.  * @Description: 生存xml文件
16.  * @date 2019/11/24 / 16:15
17.  */
18. public class createTestngXml {
19. 
20.     static Properties sysProperty = System.getProperties();
21. 
22.     public static void createTestngXml(String classname) {
23.         Document document = DocumentHelper.createDocument();
24.         Element root = DocumentHelper.createElement("suite");
25.         document.setRootElement(root);
26.         root.addAttribute("name", "automation");
27.         root.addAttribute("thread-count", String.valueOf("1"));
28.         //生成监听器
29.         Element listeners = root.addElement("listeners");
30.         Element listener1 = listeners.addElement("listener");
31.         listener1.addAttribute("class-name", "appout.reporter.ReporterListener");
32.         Element test = root.addElement("test");
33.        //增加设备号与端口号:
34.         Element paramUuid = test.addElement("parameter");
35.         paramUuid.addAttribute("name", "udid");
36.         //根据实际情况修改
37.         paramUuid.addAttribute("value", "127.0.0.1:62001");
38.         Element paramPort = test.addElement("parameter");
39.         paramPort.addAttribute("name", "port");
40.         //根据实际情况修改
41.         paramPort.addAttribute("value", "4723");
42.         test.addAttribute("name", "127.0.0.1");
43.         Element classes = test.addElement("classes");
44.         Element classNode = classes.addElement("class");
45.         classNode.addAttribute("name", classname);
46.         OutputFormat format = new OutputFormat("    ", true);
47.         XMLWriter xmlWrite2;
48.         try {
49.             xmlWrite2 = new XMLWriter(new FileOutputStream(sysProperty.getProperty("user.dir") +"/comsevenday/src/main/resources/mytestng.xml"), format);
50.             xmlWrite2.write(document);
51.         } catch (
52.                 UnsupportedEncodingException e) {
53.             e.printStackTrace();
54.         } catch (
55.                 FileNotFoundException e) {
56.             e.printStackTrace();
57.         } catch (
58.                 IOException e) {
59.             e.printStackTrace();
60.         }
61.     }
62. 
63. }

2、执行主类MainTest

    1. import appout.utils.createTestngXml;
    2. import org.testng.TestNG;
    3. import java.util.ArrayList;
    4. import java.util.List;
    5. import java.util.Properties;
    6. 
    7. /**
    8.  * @author liwen
    9.  * @Title: MainTest
    10.  * @Description: 主方法
    11.  * @date 2019/11/24 / 19:49
    12.  */
    13. public class MainTest {
    14. 
    15.     static Properties sysProperty = System.getProperties();
    16.     private static final String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
    17. 
    18.     public static void main(String[] args) {
    19.         try {
    20.             //执行的类
    21.             createTestngXml.createTestngXml("appout.appcase.CartTest");
    22.         } catch (Exception e) {
    23.             e.printStackTrace();
    24.         }
    25.         System.setProperty(ESCAPE_PROPERTY, "false");
    26.         List<String> suites = new ArrayList<String>();
    27.         System.out.println(suites);
    28.         suites.add(sysProperty.getProperty("user.dir") + "/comsevenday/src/main/resources/appxml/mytestng.xml");
    29.         TestNG tng = new TestNG();
    30.         tng.setTestSuites(suites);
    31.         tng.run();
    32.     }
    33. }

    3、自动生成的xml


    1. <?xml version="1.0" encoding="UTF-8"?>
    2. 
    3. <suite name="automation" parallel="Automatically generate xml" thread-count="1">
    4.     <listeners>
    5.         <listener class-name="appout.reporter.ReporterListener"/>
    6.     </listeners>
    7.     <test name="127.0.0.1">
    8.       <parameter name="udid" value="127.0.0.1:62001"/>
    9.         <parameter name="port" value="4723"/>
    10.         <classes>
    11.             <class name="appout.appcase.CartTest"/>
    12.         </classes>
    13.     </test>
    14. </suite>

    4、工程目录

    自动化工具之Appium之main启动_xml


    5、执行结果为:

    自动化工具之Appium之main启动_xml_02


    二、命令行执行appium服务

          如果使用命令行执行,需要了解下appium启动命令,这样咱们才可以拼接命令,启动服务

    先试下编写好的命令appium -p 4327 -bp  11 -U 127.0.0.1:62001

    自动化工具之Appium之main启动_java_03

    编写执行启动服务器


    1.  /**
    2.      * 启动或者关闭appium servers
    3.      * kill server with appium servers
    4.      *
    5.      * @return
    6.      */
    7.     public static boolean killServer() {
    8.         String command = null;
    9.         if (osName.toLowerCase().contains("mac")) {
    10.             command = "killall node";
    11.         } else if (osName.toLowerCase().contains("win")) {
    12.             command = "taskkill -F -PID node.exe";
    13.         } else {
    14.             command = "taskkill -F -PID node.exe";
    15.         }
    16.         if (execCmd(command)) {
    17.             log.debug("kill server node  Succeed");
    18.             return true;
    19.         } else {
    20.             log.error("kill server node Failure");
    21.             return false;
    22.         }
    23.     }
    24. 
    25.  
    26.     
    
    27. 
    28.  /**
    29.      * 启动appium服务
    30.      */
    31.     public void startAppium() {
    32.         String deviceName = getDeviceName();
    33.         String cmmd = "appium -p 4327 -bp  11 -U " + deviceName + ">" + deviceName + "_log.log";
    34.         execCmd(cmmd);
    35.     }
    36.  
    37. 
    38.     /**
    39.      * 执行操作命令
    40.      *
    41.      * @param cmdString
    42.      * @return
    43.      */
    44.     public static boolean execCmd(String cmdString) {
    45.         if (cmdString == null) {
    46.             return false;
    47.         }
    48.         //获取当前执行环境
    49.         Runtime p = Runtime.getRuntime();
    50.         Process process = null;
    51.         try {
    52.             if (osName.toLowerCase().contains("mac")) {
    53.                 String[] command = {"/bin/sh", "-c", cmdString};
    54.                 process = p.exec(command);
    55.             } else if (osName.toLowerCase().contains("win")) {
    56.                 process = p.exec("cmd /c " + cmdString);
    57.             }
    58.             return true;
    59.         } catch (Exception e) {
    60.             e.printStackTrace();
    61.             return false;
    62.         }
    63.     }
    64. 
    65. 
    66.     /**
    67.      * 获取设备号
    68.      *
    69.      * @return name of the device
    70.      * @throws IOException
    71.      */
    72.     public static String getDeviceName() {
    73.         return runCmdCommand(GET_DEVICE_NAME).trim();
    74.     }
    75.      /**
    76.      * 执行命令
    77.      *
    78.      * @param command
    79.      * @return string
    80.      * @throws IOException
    81.      */
    82.     public static String runCmdCommand(String command) {
    83.         ProcessBuilder builder;
    84.         if (SYSTEM_TYPE_UPPER.indexOf("WINDOWS") != -1) {
    85.             builder = new ProcessBuilder("cmd.exe", "/c", command);
    86.         } else {
    87.             builder = new ProcessBuilder("/bin/sh", "-c", command);
    88.         }
    89.         StringBuffer content = null;
    90.         try {
    91.             builder.redirectErrorStream(true);
    92.             Process p = builder.start();
    93.             BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    94.             content = new StringBuffer();
    95.             String line;
    96.             while ((line = r.readLine()) != null) {
    97.                 content.append(line);
    98.             }
    99.         } catch (IOException e) {
    100.             e.printStackTrace();
    101.         }
    102.         return content.toString();
    103.     }

    判断是否存在

    如果存在就kill


    1. /**
    2.      * 启动或者关闭appium servers
    3.      * kill server with appium servers
    4.      *
    5.      * @return
    6.      */
    7.     public static boolean killServer() {
    8.         String command = null;
    9.         if (osName.toLowerCase().contains("mac")) {
    10.             command = "killall node";
    11.         } else if (osName.toLowerCase().contains("win")) {
    12.             command = "taskkill -F -PID node.exe";
    13.         } else {
    14.             command = "taskkill -F -PID node.exe";
    15.         }
    16.         if (execCmd(command)) {
    17.             LogUtil.debug("kill server node  Succeed");
    18.             return true;
    19.         } else {
    20.             LogUtil.error("kill server node Failure");
    21.             return false;
    22.         }
    23.     }

    主方法启动类


    1. import appout.utils.OperationalCmd;
    2. import appout.utils.createTestngXml;
    3. import org.testng.TestNG;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. import java.util.Properties;
    7. 
    8. /**
    9.  * @author liwen
    10.  * @Title: MainTest
    11.  * @Description: 主方法
    12.  * @date 2019/11/24 / 19:49
    13.  */
    14. public class MainTest {
    15. 
    16.     static Properties sysProperty = System.getProperties();
    17.     private static final String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
    18. 
    19.     public static void main(String[] args) {
    20. 
    21.         //先执行kill
    22.         OperationalCmd.killServer();
    23.         //在启动服务
    24.         OperationalCmd.startAppium();
    25. 
    26.         try {
    27.             //执行的类
    28.             createTestngXml.createTestngXml("appout.appcase.CartTest");
    29.         } catch (Exception e) {
    30.             e.printStackTrace();
    31.         }
    32.         System.setProperty(ESCAPE_PROPERTY, "false");
    33.         List<String> suites = new ArrayList<String>();
    34.         System.out.println(suites);
    35.         suites.add(sysProperty.getProperty("user.dir") + "/comsevenday/src/main/resources/appxml/mytestng.xml");
    36.         TestNG tng = new TestNG();
    37.         tng.setTestSuites(suites);
    38.         tng.run();
    39.     }
    40. }

    三、集成jenkins

              自己想一想

                操作:略

    总结:

           通过上面主方法调用检查appium服务,并且执行appium服务,上面不足的地方就是生成xml中设备号与udid需要手动,其实也是可以通过自动生成并且赋值给appium执行命令与生存testng.xml中去。暂时就不演示怎么加上去,其实在工作中确实是自动获取设备号生存xml,全部一键执行。


    送大家一句

        学问以勤学为入门,孝养以竭力为真情。

           谋事不求易成,事易成则志存轻慢。


    自动化工具之Appium之main启动_java_04