zoukankan      html  css  js  c++  java
  • 基于appium的app自动化测试框架

    基于appium框架的app自动化测试
    App自动化测试主要难点在于环境的搭建,appium完全是基于selenium进行的扩展,所以app测试框架也是基于web测试框架开发的
    一、设备连接
    (即构建基础的测试环境,保证可以驱动设备进行操作)
    0.准备测试环境
    1)安装jdk配置java_home环境变量;
    2)安装Android SDK(安卓软件开发包)(adb、appt )
    3)安装nodejs,并通过npm安装appium
    1.获取app包名appPackage
    在cmd命令行中输入aapt  dump badging +apk包目录
    
    如果提示aapt命令不是内部命令,说明aapt的环境变量配置有问题。
    
    可以直接到android-sdk-windows的安装目录下找到aapt程序,在地址栏中输入cmd,然后在执行上面操作,就可以了。
    
    如果执行脚本出现“no such element: Unable to locate element: {"method":"css selector","selector":"#i1"}
    (Session info: webview=39.0.0.0)”原因是不明未解决。一般是在模拟机上会出现这种定位问题,真机没有。
    成功的结果是这样的,截图如下:
    
    
    2.获取app入口appActivity的值
    还是在上面的信息中往下找找到如下图的位置,其中name的值就是appActivity的参数值
    

     接下来我们可以启动appium软件,直接启动服务appium-server。

    然后,通过以上方法获取关于app模块信息,我们可以尝试写一下脚本驱动appium-server来帮我连接到设备上的app软件。脚本命令如下:
    
    脚本完成后,右键执行一下,会发现appium在不停的刷日志(确保appium和脚本在同一网段即可,不一定在同一台电脑)
    
    这样就证明code-client和appium已经建立了联系,然后我们就可以通过写脚本命令操作设备上的软件了。
    如果我们要操作手机上自带的软件/功能,没有办法获取apk包怎么办呢?
    答:进入cmd命令行中输入adb logcat |findStr  START  ,然后操作设备上的功能/软件,在打出的日志中查找第一个START,在其后cmp=后面就是报名appPackage和appActivity
    
    ===============================================================================
    二、搭建自动化测试框架
    1、整体思路:创建基础类实现设备驱动的获取连接
    2、创建页面类实现页面中所有的功能元素可被获取调用(代码驱动编写测试用例)
    3、创建测试脚本(测试类),编写测试方法调用测试用例
    4、创建服务控制类,通过参数配置的方式连接不同的设备
    5、创建框架的启动脚本
    具体代码如下:
    1.创建基础类实现设备驱动的获取连接
    1)编写基础类,实例化封装后的appium框架(即Pyapp)	
    2.创建页面类实现页面中所有的功能元素可被获取调用(代码驱动编写测试用例)
    2)编写登录页面类,实现登录页面的功能操作
    
    3)编写单个页面功能的测试方法
    
    4)逐一编写测试功能页面类的相关功能
    
    
    
    3.创建测试脚本(测试类),编写测试方法调用测试用例
    
    4.创建服务控制类,通过参数配置的方式连接不同的设备
    1)新建yml文件编写测试设备的详细信息
    
    2)创建服务控制类:服务控制类:appium服务的停止、启动、监听;设备驱动的连接启动
    class Controller(object):
        #读取设备配置文件中的设备信息进行初始化
        def __init__(self):
            # 通过读取yml文件获取 配置信息
            self.conf = Tool().app_data
            # 拆分包的信息
            self.tester = self.conf.get('tester')
            # 拆分手机的信息
            self.devices = self.conf.get('devices')
            # 手机的类型
            self.device_type = self.conf.get('device_type')
            # 唯一手机
            self.device = self.devices.get(self.device_type)[0]
            # 手机名称
            self.deviceName = self.device.get('name')
        #启动appium服务,由于我们是代码驱动,就不能使用手工开启appium
        def start_server(self):
            device = self.devices.get(self.device_type)[0]
            ip = device.get('ip')
            port = device.get('port')
            deviceName = device.get('deviceName')
            log = os.path.join(LOGPATH, device.get('name') + '.log')
            cmd = 'appium -a {ip} -p {port} -U {deviceName} -g {log}'.format(
                ip=ip, port=port, deviceName=deviceName, log=log)
            logger.debug('启动服务的命令:%s'%cmd)
            # 执行命令 netstat -ano | findstr  9036 --  netstat -nlpt |grep 9036
            subprocess.Popen(cmd, stdout=open(log, 'a+'), stderr=subprocess.PIPE, shell=True)
        #监听appium服务是否启动成功
        def test_server(self):
            port = self.devices.get(self.device_type)[0].get('port')
            while True:
                #在cmd命令行中执行netstat -ano |findstr 端口,监听服务是否启动成功
                res = subprocess.getoutput("netstat -ano | findstr %s" % port)
                if 'LISTENING' in res:
                    logger.debug(res)
                    logger.info("服务启动成功")
                    break
                else:
                    time.sleep(3)
                    logger.debug('三秒后重试')
            return True
        #开启手机启动的连接
        def start_driver(self):
            # 包信息 和 手机信息 合并
            self.tester.update(self.device)
            ip = self.tester.get('ip')
            port = self.tester.get('port')
            driver = webdriver.Remote('http://{ip}:{port}/wd/hub'.format(ip=ip,port=port),self.tester)
            # 像对列中put生成的drvier
            driver_queue.put(driver)
        #关闭appium服务
        def kill_server(self):
            res = subprocess.getoutput("taskkill /F /IM node.exe /t")
            logger.debug('kill server :%s'%res)
    if __name__ == '__main__':
        contorller = Controller()
        contorller.kill_server()
        contorller.start_server()
        if contorller.test_server():
            contorller.start_driver()
    
    5.创建框架的启动脚本
    主要负责启动appium服务、启动设备驱动连接设备、执行测试用例、生成测试报告。
    
    详细代码:
    class Main(object):
        def __init__(self):
            self.controller = Controller()
            self.deviceName = self.controller.deviceName
    
        def run(self):
            self.controller.start_server()
            if self.controller.test_server():
                self.controller.start_driver()
                suite = unittest.TestSuite()
                cases = unittest.defaultTestLoader.discover(APPCASE)
                for case in cases:
                    suite.addTest(case)
                f = open(APPREPORT.format('{}.html'.format(self.deviceName)), 'wb')
                runner = HTMLTestRunner(f, verbosity=1, title=u'测试报告', description=u'用例执行情况:')
                runner.run(suite)
                f.flush()
                f.close()
    
    
    if __name__ == '__main__':
        m = Main()
        m.run()
    
    ==============================================================================
    
    三、编写测试用例过程中常见的问题:
    1.如果运行以上脚本后,提示“无法与计算机取得联系”
    
    一般原因有两个(1.appium未开启,2.appium服务和脚本服务不在一个网段内。)
    2. 有时候联系两次运行脚本会出现“A new session could not be created. Details”
    
    原因是:appium-server和code-client已经连接,无法再去连接。这里我们可以将appium-server服务关闭然后在新建一个appium-server。在执行脚本就好了。
    
    
    主要原因是selenium的版本问题,可是使用set_value()代替send_keys()方法。
    

      

  • 相关阅读:
    数据存储大小端验证
    Python之路【第二十三篇】爬虫
    Python之路【第二十篇】Tornado框架
    Python之路【第二十二篇】CMDB项目
    Python之路【第二十一篇】Django ORM详解
    Python之路【第二十篇】其他WEB框架
    Python之路【第十九篇】自定义分页实现(模块化)
    Python之路【第十八篇】Django小项目webQQ实现
    Python之路【第十八篇】Django小项目简单BBS论坛部分内容知识点
    Python之路【第十七篇】Django进阶篇
  • 原文地址:https://www.cnblogs.com/yunyuan01/p/9962807.html
Copyright © 2011-2022 走看看