• Appium 自动测试,读书打卡(日志)


    1.准备工作

    1.1了解Appium 自动测试

       Appium 官方链接:https://appium.io/docs/en/about-appium/intro/。 

    1.2软件安装

      1.JDK

      2.Android SDK 

          下载链接:https://www.androiddevtools.cn/

          在配置环境变量时,遇到以下问题。

        (1)在配置Android SDK 环境时,发现没有找到adb.exe文件,后来查找资料,发现是没有platforms-tools。如下图所示。

                   

          (2)上网搜索可能原因,有人说可能是platform-tools在安装时被误删,打开 Android SDK Manager看看platform-tools是否被误删,发现果然被误删了。

                 

           (3)安装platform-tools。

               

         (4)配置环境变量。

             

         (5)配置系统环境变量。

               

           (6)在命令行测试Android SDK 环境安装成功。

               

    参考博客链接:https://www.csdn.net/tags/MtjaggzsNTc4MjktYmxvZwO0O0OO0O0O.html。

      3.Appium 

         下载链接:https://github.com/appium/appium-desktop/releases/download/v1.22.3/Appium.Server.GUI-windows-1.22.3.exe

          下载完成后操作

      (1)双击Appium进行安装,安装完成后,出现以下界面。将Host设置为127.0.0.1,Port设置为4723,如果没有配置JDK或者ANDROID_HOME环境变量,需要点击“Edit Configurations”处。

                 

             (2)如果忘记了是否配置了环境,可以点击“Edit Configurations”进行查看,由于我是环境都配置完成了,所以这里会自动填写上。

                 

             (3)开启服务,进入到服务界面。看到欢迎你,Appium的客户端就算完成了。

               

      4.夜神模拟器

         下载链接:https://www.yeshen.com/

    1.2说明

          本项目只用于技术讨论。

    2.需求分析

           手机上的读书软件,自动完成读书并打卡。这里需要先找到读书软件,然后点击读书软件,在读书软件中找到需要阅读的书籍,点击需要阅读的书籍,每隔固定时间滑动屏幕进行翻页,设置固定阅读总时长,到达总时长后,结束阅读。在当前页面中找到页码和总页码,读出来这两个量。进行读书打卡。

    3.技术原型

      1.appium读app

      2.appium点击屏幕

      3.appium滑动屏幕

      4.识别固定位置上的数字

    4.实验

    4.1Appium连接安卓模拟器

    4.1.1实验目的

    了解Appium是如何和安卓模拟器连接的。

    4.1.2实验内容

    4.1.2.1准备工作

    1.进入模拟器中的设置,找到安卓版本号位置,多次点击。进入开发者模式。

     2.多次点击后,会提示进入到开发者模式。

     3.查看Android SDK的adb版本。

    4.进入模拟器bin目录下,执行nox_adb.exe version,查看adb版本。发现两者的版本不一致。如果版本不一致,需要把Android SDK下的adb版本复制到模拟器bin目录下。并把Android SDK下的adb重新命名为nox_adb。

     5.当把Android SDK下的adb重新命名为nox_adb后,复制到模拟器bin目录下后,访问被拒绝。

     

     6.然后我把原来模拟器bin目录下nox_adb.exe删除。就能复制过去。

     7.再次查看模拟器下的adb版本,发现和Android SDK下的adb版本版本一致。

     

     8.连接模拟器,发现无法连接。

     

    解决无法连接问题。

    参考链接: https://blog.csdn.net/DaisyCold/article/details/111477842 。

    (1)查看别人博客显示我少复制了两个文件。把Android SDK安装目录下画红框位置的两个文件也复制到模拟器bin目录下。

    (2)在模拟器bin目录下替换复制过来的文件。

     

     (3)再次查看adb版本,发现两个版本一致了。

     

     (4)再次连接,连接成功。

     

    4.1.2.2创建Maven项目

    1.点击file下创建新的Maven项目。

     2.选择创建一个简单的工程。

     

     3.填写信息。

     

     4点击完成后报错。显示无效的工程描述,信息如下。

     

     

    5.查找原因,说创建Maven时不能选择新的工作空间,需要选择默认的工作空间。选择默认的工作空间后,创建成功。

     

    4.2.1.3安装Maven

    1.下载链接:https://maven.apache.org/download.cgi 。

     2.配置环境变量。

     

     

     参考链接:https://www.runoob.com/maven/maven-setup.html

     3.测试maven环境是否配置成功,输入mvn -version,显示版本信息,表示配置成功。

    4.1.2.4Maven安装Java-client

    Java-client连接:https://mvnrepository.com/ 。

    1.打开Maven Repository,搜素Appium。找到Java Client。

     2.点击Java Client,复制依赖。

     3.在项目中的pom.xml文件中复制依赖。

    4.eclipase配置Maven。如下图所示。找到eclipse中Windown下的preferences,第一步在Maven下找到Installations并点击,第二步点击Add,第三步选择Maven的安装路径。

     

     5.编写测试代码。

    import org.openqa.selenium.remote.DesiredCapabilities;
    
    import io.appium.java_client.android.AndroidDriver;
    
    public class TestApp1 {
        public static void main(String[] args) throws MalformedURLException, InterruptedException {
            DesiredCapabilities capabilities = new DesiredCapabilities();
            // 模拟器类型
    //        capabilities.setCapability("deviceName", "Android Emulator");
            capabilities.setCapability("deviceName", "device");
            // 自动化测试引擎
            capabilities.setCapability("automationName", "Appium");
            // 手机操作系统Android
            capabilities.setCapability("platformName", "Android");
            // 手机操作系统版本号
            capabilities.setCapability("platformVersion", "7.1.2");
            // app包名
            capabilities.setCapability("appPackage", "com.android.settings");
            // app中启动的Activity名称
            capabilities.setCapability("appActivity", ".Settings");
    
            AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
    
            driver.quit();
        }
    }

    4.1.2.5解决程序错误

    使用代码测试能否启动模拟器中的设置,目前报错信息如下。

    4.1.2.5.1问题一

    1.猜测是代码中的包名或者其他信息填写错误,检查一遍代码,排查了这个可能性。然后又针对报错信息,一条一条的看。先解决第一个问题。

     2.查找原因,网上好多说是需要添加依赖,然后就添加了以下的依赖。参考链接:https://blog.csdn.net/zhizhengguan/article/details/103312010 。

    4.1.2.5.2问题二

    1.解决完问题一后,下面解决问题二。如下图所示。

     2.寻找解决办法,跟着添加了一堆依赖,也还是报错。

    <!--  错误依赖-->
    <!--  <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency> 
        <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>22.0</version>
    </dependency> -->

     3.不知道该怎么办了,就查看了Appium,发现这里也有一些信息,而且有以下几个问题,好像是缺少一些东西。

     

     4.我其实并不知道缺少的是什么,我在我电脑上搜索是否真的没有这个文件。然后就发现有这个文件。

     

     5.我以为是目录不对,按照提示的目录找了一下,还是存在缺少的apk。到这里我卡主了,我不知道问题出在了哪里。

     6.然后我又看了一下是否还存在其他问题,解决又找到了新的问题。

    7.通过查看别人解决方案,发现build-tools/目录下应该有“apksigner.jar”文件但是我电脑上没有。

    8.我上网想下个“apksigner.jar”,但是我找了半天不是找不到,就是要花钱,所以我放弃这个想法了。

    9.然后我看到一个博客中的解决方法,里面是复制build-tools下的apksigner.jar,我记得昨天android SDK里面缺少东西时,在SDK Manager.exe中安装过platform-tools。

     

    10.然后我想着在SDK Manager.exe中是不是也可以找到build-tools,打开SDK Manager.exe后,真的找到了,然后下载。

    4.1.2.5实验结果

    运行java程序,打开了设置。

    4.2 Appium点击出现的代码问题

    1.在调试代码时,这里出现了报错。这里是不支持这两个参数。

     2.查找资料,需要把坐标以point对象的形式放到Tap方法中才可以。

    参考链接:https://blog.csdn.net/hccgk/article/details/103169057/ 。

    4.3 Appium滑动出现的代码问题

    1.想使用swipe方法实现互动效果,但是编写以下代码,然后报错,如下图

     

     2.看来swipe已经不能使用了。

    4.4 Appium定位元素出现的问题

    1.使用Appium Inspector获取设置中WLAN选项的ID时,出现以下问题,没有找到WLAN选项的ID,只能找到WLAN选项的xpath,如下图所示。

    2.在查阅了一些资料说resource-id是选择元素的ID,但是经过我的实验,其他的元素也是这个ID。比如蓝牙的ID。

     3.又对比了其他元素的其他属性,发现只有Text属性不一样。

    4.查找原因,是因为上面是查看的布局ID。需要查看选择中标签的ID。

     5.写完正确ID后,编写代码,报没有findElementById()的方法,尝试了其他的定位属性,也没有。

     6.上网搜索好久也没有找到解决办法,猜测是不是版本的问题。然后降低版本。降低版本后AndroidDriver又不兼容。

     

    7.把java-client改成7.6.0版本。

     8.报以下的错误,不能创建远程会话。

     9.查看日志。发现以下三处问题。

     

     

     10.搜索原因,看到有一个说降低Appium版本。我尝试降低了Appium版本。结果真的好了。

    4.5 Appium识别元素出现的问题

    1.网上搜索资料,一开始找到的是使用getText()方法,但是我在获取WLAN的值时获取不到。

    2.我尝试了其他几种获取属性值的方法,发现只有getAttribute(“className”)方法可以获取到值。

    3.又查找资料,看到有一个获取界面资源代码的方法,可以获取到界面的代码。

    driver.getPageSource()//获取到界面代码

    4.实在找不到啥方法可以获取到属性值的方法,我想了一下界面代码都有了,要是我按照id先找到所需属性所在行,然后再取出所需值就可以。按照以下代码,把界面代码按行分割,然后在每行中匹配所需id。

    String resource_origin = driver.getPageSource();//获取到界面代码
            String[] resources = resource_origin.split("\n");
            for (String str : resources) {
                int intIndex = str.indexOf(wifi_id);
                if (intIndex != -1) {
                    System.out.println("找到:  " + str);
                }
    
            }

    5.先找到所需代码所在行,运行程序看一下效果,才发现,原来这个id不是唯一的,同时也明白了为啥一开始使用getText()获取不到值的。因为ID不唯一,而第一个匹配上的ID中的内容就是空,所以一直获取不到。

    6.怀疑其他软件的ID唯一,打开微信读书,查看ID,发现ID是唯一的。

    7.后来使用微信读书获取所需ID的文本内容。

    5.实现

    5.1出现的问题

    1.微信读书中没有ID,选用了xpath来找到书籍。

    2.微信读书获取不了页码,点击页码时,会全选,不能单独选择页码,也就获取不了ID或者xpath。

    3. 获取界面代码,查看页面是以什么形式存在界面中的。

    4.查看页面代码,没有发现里面包含页码信息。

     5.再找了一圈之后,我发现这可能是一张图片,但是又不像图片。然后我放弃了使用属性获取内容,打算换技术路线,使用图片识别技术。

     5.2获取页码思路

    使用图片识别图中文字,需要经过以下两个步骤,第一步图片分割。第二步识别图中的文字。

    5.2.1识别图片问题

    5.2.1.1使用百度API

    1.添加以下代码的依赖。

          <dependency>
                <groupId>com.baidu.aip</groupId>
                <artifactId>java-sdk</artifactId>
                <version>4.8.0</version>
           </dependency>

    2.注册登录百度智能云,创建一个应用,创建完需要等待三十分钟。

     3.复制以下代码。(未完成,因为有的包不能导入,然后放弃了这个方法)

    /**
     * @describe 识别图片上的文字
     * 官方文档:https://ai.baidu.com/ai-doc/OCR/Ikibizxql
     */
    public class Word {
        // 设置APPID/AK/SK
        public static final String appId = "你的 App ID";
        public static final String apiKey = "你的 Api Key";
        public static final String secretKey = "你的 Api Key";
        public static final AipOcr client = new AipOcr(appId, apiKey, secretKey);
     
        /*
         * 文字识别方法
         */
        public static String imgOcr(String imgpath)
        {
            // 传入可选参数调用接口
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("language_type", "CHN_ENG");
            options.put("detect_direction", "true");
            options.put("detect_language", "true");
            options.put("probability", "true");
            // 参数为本地路径
            JSONObject res = client.basicGeneral(imgpath, options);
            //解析json
            JSONArray wordsResult = (JSONArray)res.get("words_result");
            String ocrStr = "\n";
            StringBuffer sb=new StringBuffer();
            for(Object obj : wordsResult)
            {
                JSONObject jo = (JSONObject)obj;
                sb.append(jo.getString("words") + "\n");
            }
            return sb.toString();
        }
     
        public static void main(String[] args) throws AWTException, IOException {
            String s = StartApp.imgOcr("C:\\Users\\Administrator\\Desktop\\sw_image\\a.png");
            System.out.println(s);
        }
    

    5.2.1.2使用软件包识别图片文字

    1.运行程序后,出现以下界面。

    2.配置环境变量后,在命令行中输入tesseract后,出现以下信息则代表环境变量配置完成。

     

     3.运行程序后,还是报原来的错误。这里找了好久问题。又重新安装了Tesseract-OCR 。

     4.最终发现了问题。这里有两个原因导致的报错,一是安装目录中不能有非法字符(在我第一次安装时,安装路径中多了空格)。二是在安装时,没有安装语言包(第一次安装时没有勾选语言包),导致识别不了。

     5.2完善项目问题

    5.2.1设定每页读书间隔

    1.在确定需要设置两个固定时间后,先设置每页阅读40s,先尝试阅读120s,但是运行程序时,发现没有获取到页码,一开始以为机器没有睡醒,多运行几次还是这样。然后找到截图,发现截图也不正确。如下图所示。后来一直摁撤回,还原到昨晚好使的代码,但是运行程序还是获取不到页码,截图还是下面截图。

    2.想着可能是模拟器有问题,重新打开模拟器,再次运行程序,发现读书界面也没有打开(就像网不好,一直显示加载)。后来又运行了几次,可以打开微信读书了,但是截图还是上门的截图。

    3.我感觉我代码被猫吃了,吓的我把电脑关机重启,所有软件都关闭重新打开。

    4.我猜测是网络不好,换成手机的网络,运行程序后,还是上面截图的效果。

    5.我把网络关闭,运行程序,也能打开模拟器,并且截图是上面的截图。

    6.我不知道这是什么原因导致的,我又猜测是模拟器坏了,卸载模拟器,重新安装,运行程序,但是不能创建一个新的远程会话。

     

     7.查看是否是两个版本的adb不一致。果然是两个版本不一致,但是我已经把Android SDK下的adb版本复制到模拟器bin目录下啊。

     

     8.我感觉可能是自己脑子坏了,再重新替换一下。再次查看版本,这次版本一致了。

    9.运行程序报错。 

     10.在命令行查看是否连接。

     11.启动Appium,运行程序。发现截图还是花的图片。

    12.排除了是模拟器的原因,难道是因为微信读书还没有结束就开始截图吗,但是程序执行不应该是从上到下嘛?设定的是先滑动界面,等到一段时间然后再截图啊,而且昨天为啥好好的啊,这里也没有牵扯网络异步啊。

    13.我突然又想到是不是真的是等待时间的问题,抛开项目,只打开微信,查看截图是否会改变。

    14.发现截图这次真的变了,而且裁剪图片效果也是对的。所以问题可能真的出在等待时间上。

    14.上网搜索“appium等待页面渲染完成执行方法”,发现有三种等待方式,都试了一下,发现生成的图片还是错误的图片。而在每次查看截图时,突然发现了以下的效果,从截图中可以看出,当前页面的文字应该是被截到了,但是却多了书架界面,两个界面重合在一起了。

     15.修改noReset,本来想修改成false,目的是测试截图是否正确,却发现设置成true时,没有加双引号,加上双引号后,运行程序,程序可以正确截图并获取页码了。

     16.然后把滑动代码加上后,截图还是显示的两个图片的混合。所以这里猜测是或许是滑动和截图在时间上冲突了。

     

     17.把等待时间加大,并且添加以下等待渲染需要阅读的内容,运行程序,查看效果。

    //    等待元素出现
        public static void waitElement(final AndroidDriver driver) {
    //        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
            WebDriverWait web = new WebDriverWait(driver, 10);
            WebElement webElement = web.until(new ExpectedCondition<WebElement>() {
                public WebElement apply(WebDriver input) {
                    return driver.findElementByXPath(
                            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout\r\n");
                }
            });
    //        webElement.click();
        }

    18.在多次运行中,有时截图是正确的,能获取到页码,但是有时就不能获取到正确截图。

    19到目前位置,做不下去了。

    5.2.2获取正确截图

    1.等待足够长的时间后,再截图,但是发现截图后的效果还是花的图片。

    2.使用Thread.sleep()来阻塞页面,等滑动完微信读书后才开始截图。但是运行的效果是个1中一样的效果。

    3.使用回调函数。运行程序后,还是和1中一样的效果。

        public static void waitElement(final AndroidDriver driver) {
    //        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
            WebDriverWait web = new WebDriverWait(driver, 10);
            WebElement webElement = web.until(new ExpectedCondition<WebElement>() {
                public WebElement apply(WebDriver input) {
                    return driver.findElementByXPath(
                            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout\r\n");
                }
            });
    //        webElement.click();
        }

     4.后来,我把滑动页面的方法去掉,查看截图是否正常。运行程序后发现截图是正常的,但是添加上滑动代码,截图就不正确了。我实在搞不明白这是为啥。添加滑动界面代码生成的图如下图左边第一张和第二张所示,去掉滑动界面代码生成的图如下图左边第三张和第四张所示。

     5.我猜测这个原因可能已经和时间没有关系,或许是别的原因啥的,但是我也不知道啥原因。

    5.2.3微信打卡

    1.当获取到页码后,需要把页码发到微信固定的群里,然后自动实现打卡,但是在打卡时,程序一直运行报错。

     2.这里发现是因为微信读书和微信的包名还有启动页acitivity 不一样,即微信和微信读书的这两个参数是不一样的。

     3.获取微信driver单独写一个方法。

    //    获取微信driver
        public static AndroidDriver getWechatDriver() throws Exception {
            DesiredCapabilities capabilities = new DesiredCapabilities();
            // 模拟器类型
            // capabilities.setCapability("deviceName", "Android Emulator");
            capabilities.setCapability("deviceName", "device");
            // 自动化测试引擎
            capabilities.setCapability("automationName", "Appium");
            // 手机操作系统Android
            capabilities.setCapability("platformName", "Android");
            // 手机操作系统版本号
            capabilities.setCapability("platformVersion", "7.1.2");
            // app包名
            capabilities.setCapability("appPackage", "com.tencent.mm");
            // app中启动的 Activity名称
            capabilities.setCapability("appActivity", ".ui.LauncherUI");
            capabilities.setCapability("automationName", "uiautomator2");
            // noReset设置
            capabilities.setCapability("noReset", "true");
            // 设置appium可以输入中文
            capabilities.setCapability("unicodeKeyboard", "true");
            AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
            return driver;
        }

    6.PSP

     

     

  • 相关阅读:
    cobbler default system 网络安装时主机的menu上只有一个local选项
    tcpdump使用方法
    cobbler 修改 distro_signatures.json
    wireshark in text mode: tshark
    Mac OSX使用隐藏文件夹
    sql中多条件进行排序的问题
    Linux查看打日志文件
    XML Parser Error on line 39: 必须声明元素类型 "domainObjectRenamingRule"。
    Access denied for user '密码'@'192.18.0.0' (using password: YES)
    springboot之DevTools热部署的简单原理解析
  • 原文地址:https://www.cnblogs.com/ping2yingshi/p/16155697.html
Copyright © 2020-2023  润新知