• 【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命令比较熟悉。同时要实现一个功能,最

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

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

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

  • 相关阅读:
    Atitit sumdoc t5 final file list \sumdoc t5 final\sumdoc t511 \sumdoc t5 final\sumdoc t511.zip \sum
    上课流程法如何上好第一节课(1) 目录 1. 目录 1 1.1. 销售自己 1 1.2. 销售课程 1 1.3. 学习方法 1 1.4. 制定规章 2 2. 销售自己自我介绍 2 2.1.
    Atitit 重复文件清理工具 按照文件名 目录 1. 原理, 1 1.1. If base filex exist dele other files 1 1.2. Get getStartIdex
    Atitit sumdoc index 2019 v6 t56 .docx Atitit sumdoc index s99 目录 1. Zip ver 1 1.1. C:\Users\Adminis
    Atitit lucence es solr的各种query 与sql运算符的对比 目录 1.1. 等于运算 TermQuery 1 1.2. 范围运算 1 1.3. 大小运算 1 1.4. Wi
    Atitit 程序设计概论 艾提拉著作 目录 1. 界面ui设计 1 2. 编程语言部分 1 3. 面向对象的程序设计 1 4. 算法章节 数据结构 1 5. 第21章 标准库 2 5.1. 文件i
    Atitit 命令行执行sql 跨语言 目录 1.1. 无需输入密码,那就不要p参数即可 1 1.2. 4.使用mysql命令执行 1 1.3. 5.mysql命令执行sql,并将查询结果保存到
    Atitit java播放 wav MIXER 混响器编程 目录 1.1. MIXER 混响器编程 1 1.2. 得到系统中一共有多少个混音器设备: 1 1.3. 接口摘要 1 1.4. 调节音量
    Atitit object 和class的理解 目录 1.1. 发现很多Object的方法都是相同的,他们被重复地放在一个个对象当中,太浪费了。 1 1.2. 那我们怎么把这些Object给创建起来
    Atitit 数据库的历史与未来 目录 1.1. 两个对于数据库强需求的行业。电信 金融 1 1.2. 艾提拉分析 对数据库强需求行业金融 1 2. 数据库历史 2 2.1. ,上个世纪50,6
  • 原文地址:https://www.cnblogs.com/Zeech-Lee/p/7080747.html
Copyright © 2020-2023  润新知