• 【Appnium+C#+Winform自动化测试系列】一、获取本机连接的设备、启动多个Appnium和获取本机启动的Appnium


        本系列内容,准备根据所完成的项目为基线,一步一步的把整个设计和实现过程梳理。

    先从基本的一些环境问题入手,梳理清楚关于手机设备和Appnium。因为我们在后面的建立Appnium连接时,需要设备名字和启动的Appnium实例和对应的端口号。

    一、获取手机设备

    获取本机连接的设备,我们可以通过adb命令通过控制台来实现,在控制台中输入命令adb devices可得如下结果:

    既然能

    够如此简单的获取到连接的设备,接下来也就是对控制台文字进行处理分析,最后把需要内容获取出来展示在下拉框里即可.

    对于获取到的结果,我们只取attached后面部分,可通过字符串的截取实现。去掉空格和换行符后,就变成了一连串的字符,由device间隔开的设备名字了,这样只需普通的字符处理即可完成。

    实际代码如下,可供参考:

    /// <summary>
    /// 获取当前机器连接的终端设备
    /// </summary>
    /// <returns></returns>
    public static string[] InitDevices()
    {
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
    p.Start();//启动程序
    //向cmd窗口发送输入信息
    p.StandardInput.WriteLine("adb devices" + "&exit");
    p.StandardInput.WriteLine("adb devices" + "&exit");
    p.StandardInput.AutoFlush = true;
    //p.StandardInput.WriteLine("exit");
    //向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
    //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令

    //获取cmd窗口的输出信息
    string output = p.StandardOutput.ReadToEnd();
    string[] Devices = output.Replace(" ", "").Split(new string[] { "attached" }, StringSplitOptions.RemoveEmptyEntries)[1].Replace(" ", "").Replace(" ", "").Split(new string[] { "device" }, StringSplitOptions.RemoveEmptyEntries);
    p.WaitForExit();//等待程序执行完退出进程
    p.Close();
    return Devices;

    }

    二、如何启动多个Appnium

        按照平常的使用方法,直接双击Appnium程序后点击启动即可启动一个默认端口为4723的Appnium实例。按照这种方法,貌似一台机器只能运行一个Appnium了。

    不过笔者发现,在启动Appnium时,打印出一段代码样的东西:

    通过这段代码,我发现Appnium的启动貌似是根据主要程序和一些配置来完成实例启动的。既然这样,那应该是可以通过修改IP、端口、平台和版本来控制启动的Appnium实例了。如果我想启动多个的话,

    应该是可以通过配置端口号来运行多个Appnium了。果然,直接复制命令和配置文件的绝对路径,在控制台中执行,然后再观察对应的node程序,真的出现了!经过后期验证,这个通过命令实例话的

    Appnium是可以运行的。

    以此可得,通过对端口作为参数,启动Appnium实例的函数就这样实现了:

    /// <summary>
    /// 启动Appnium实例
    /// </summary>
    /// <param name="Port">启动Appnium端口</param>
    public static void BootAppnium(string Port)
    {
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
    p.Start();//启动程序

    //向cmd窗口发送输入信息
    string command = @"D:Appium ode.exe D:Appium ode_modulesappiumlibservermain.js --address 127.0.0.1 --port " + Port + " --platform-name Android --platform-version 19 --automation-name Appium --language zh_CN --log-no-color" + "&exit";
    p.StandardInput.WriteLine(command);
    // p.StandardInput.WriteLine("netstat -aon|findstr "127.0.0.1:47"" + "&exit");
    p.StandardInput.AutoFlush = true;
    p.EnableRaisingEvents = true;

    p.Close();

    }

    三、获取本机启动的Appnium

        知道了如何启动多个Appnium后,那获取本机启动的Appnium也就易如反掌了。我们可以通过获取到node.exe程序的PID值,然后根据PID值来获取对应的端口值了,当然我们在启动端口的时候,最好是预先

    设定好一些范围,免得出现端口被占用的问题.

    首先来获取node.exe的PID值:

    C:Userseech>tasklist /v |findstr "node"
    node.exe 6076 Console 9 78,948 K Unknown ZEECH_LEEeech 0:00:03 暂缺

    其中6076即对应的PID值,因为PID值是当前系统唯一的,所以可通过PID值获取到Appnium启动的端口号了

    C:Userseech>netstat -ano |findstr "6076"
    TCP 127.0.0.1:4723 0.0.0.0:0 LISTENING 6076

    代码如下:

    public static string getnodePID()
    {
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
    p.Start();//启动程序

    //向cmd窗口发送输入信息
    p.StandardInput.WriteLine("tasklist /v |findstr "node.exe"" + "&exit");
    // p.StandardInput.WriteLine("netstat -aon|findstr "127.0.0.1:472"" + "&exit");
    p.StandardInput.AutoFlush = true;
    //p.StandardInput.WriteLine("exit");
    //向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
    //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令

    //获取cmd窗口的输出信息
    string output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();//等待程序执行完退出进程
    p.Close();
    string nodePID = (((output.Replace(" ", "").Replace(" ", "").Split(new string[] { "node.exe", "Console" }, StringSplitOptions.RemoveEmptyEntries))))[2].ToString();

    return nodePID;
    }

    /// <summary>
    /// 获取当前机器运行的Appnium
    /// </summary>
    /// <returns></returns>
    public static string [] InitAppnium()
    {
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
    p.Start();//启动程序

    //向cmd窗口发送输入信息
    p.StandardInput.WriteLine("netstat -aon|findstr ""+ getnodePID()+""" + "&exit");
    // p.StandardInput.WriteLine("netstat -aon|findstr "127.0.0.1:472"" + "&exit");
    p.StandardInput.AutoFlush = true;
    //p.StandardInput.WriteLine("exit");
    //向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
    //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令

    //获取cmd窗口的输出信息
    string output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();//等待程序执行完退出进程
    p.Close();
    string[] Appniuma = (((output.Replace(" ", "").Replace(" ", "").Replace("0.0.0.0:0", "||0.0.0.0:0").Split(new string[] { "TCP", "6076" }, StringSplitOptions.RemoveEmptyEntries))));
    List<string> Appnium=new List<string>();
    for (int i = 0; i < Appniuma.Count(); i++)
    {
    if (i>1)
    {
    Appnium.Add(Appniuma[i]);
    }
    }
    return Appnium.ToArray();
    }

    注意:这种字符串截取的过程可能会出现一些bug.例如,在某些情况下,该PID值恰好是某个端口号的部分,那也会诶筛选出来,最完美的做法是只匹配PID值,这样处理一下就可以避免这种情况了.

    当然,可能在其他的处理过程中同意会出现筛选不精确的情况,需要多次调试分析尽量做到精准.Windows下,可下载一个AWK插件,可以对列进行筛选处理会方便很多.在处理替换时,可能读者会发

    现Replace("0.0.0.0:0", "||0.0.0.0:0"),其实这里的目的是隔开监听状体下的端口号,防止混乱.

    四、销毁Appnium实例

        销毁与创建过程互为逆过程,有了以上知识,处理起来就非常简单了。只需要kill 实例程序node.exe即可.

    直接上代码:

    /// <summary>
    /// 销毁Appnium实例
    /// </summary>
    public static void ExitAppnium()
    {
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
    p.Start();//启动程序

    //向cmd窗口发送输入信息
    p.StandardInput.WriteLine(@"taskkill /f /t /im node.exe" + "&exit");

    p.StandardInput.AutoFlush = true;
    p.EnableRaisingEvents = true;

    p.Close();

    }

    五、总结

    经过以上的梳理,在对环境的操作,需要用到大量的Windows命令。如果想实现一个完整的Windows平台自动化测试,需要对cmd命令比较熟悉。同时要实现一个功能,最

    快速便捷的方法就是去弄懂其原理。任何事情在明白原理的情况下,处理起来都是得心应手,代码只是一个桥梁而已,相信以上的代码写出来后都会觉得非常简单,可以说

    几乎全是一些字符串的处理。在测试的过程中,往往就需要对获取的结果进行处理分析,如何精确的获取到需要的信息将是测试是否成功的关键了。

        谢谢大家,我已经迫不及待的构思下一篇博文了!

  • 相关阅读:
    18、排序算法-快速排序
    centos7.x 端口映射
    SpringBoot多环境分离resources和lib进行打包
    Java枚举储存的一种索引实现方式
    Maven项目pom文件设置JDK版本
    Java提取URL某个参数的值
    使用正则替换script及其内容
    Oracle设置主键自增
    Maven配置ojdbc14-10.2.0.4.0.jar
    使用maven生成可执行jar包(包含依赖)
  • 原文地址:https://www.cnblogs.com/Zeech-Lee/p/7080747.html
Copyright © 2020-2023  润新知