欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于appium的app自动化测试框架

程序员文章站 2022-07-01 23:39:54
接下来我们可以启动appium软件,直接启动服务appium-server。 ......
基于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包目录
基于appium的app自动化测试框架
如果提示aapt命令不是内部命令,说明aapt的环境变量配置有问题。
基于appium的app自动化测试框架
可以直接到android-sdk-windows的安装目录下找到aapt程序,在地址栏中输入cmd,然后在执行上面操作,就可以了。

如果执行脚本出现“no such element: unable to locate element: {"method":"css selector","selector":"#i1"}
(session info: webview=39.0.0.0)”原因是不明未解决。一般是在模拟机上会出现这种定位问题,真机没有。
基于appium的app自动化测试框架
成功的结果是这样的,截图如下:

基于appium的app自动化测试框架
2.获取app入口appactivity的值
还是在上面的信息中往下找找到如下图的位置,其中name的值就是appactivity的参数值
基于appium的app自动化测试框架

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

基于appium的app自动化测试框架

 

然后,通过以上方法获取关于app模块信息,我们可以尝试写一下脚本驱动appium-server来帮我连接到设备上的app软件。脚本命令如下:
基于appium的app自动化测试框架
脚本完成后,右键执行一下,会发现appium在不停的刷日志(确保appium和脚本在同一网段即可,不一定在同一台电脑)

这样就证明code-client和appium已经建立了联系,然后我们就可以通过写脚本命令操作设备上的软件了。
如果我们要操作手机上自带的软件/功能,没有办法获取apk包怎么办呢?
答:进入cmd命令行中输入adb logcat |findstr  start  ,然后操作设备上的功能/软件,在打出的日志中查找第一个start,在其后cmp=后面就是报名apppackage和appactivity
基于appium的app自动化测试框架
基于appium的app自动化测试框架

 

===============================================================================
二、搭建自动化测试框架
1、整体思路:创建基础类实现设备驱动的获取连接
2、创建页面类实现页面中所有的功能元素可被获取调用(代码驱动编写测试用例)
3、创建测试脚本(测试类),编写测试方法调用测试用例
4、创建服务控制类,通过参数配置的方式连接不同的设备
5、创建框架的启动脚本
具体代码如下:
1.创建基础类实现设备驱动的获取连接
1)编写基础类,实例化封装后的appium框架(即pyapp)	
2.创建页面类实现页面中所有的功能元素可被获取调用(代码驱动编写测试用例)
2)编写登录页面类,实现登录页面的功能操作
基于appium的app自动化测试框架
3)编写单个页面功能的测试方法
基于appium的app自动化测试框架
4)逐一编写测试功能页面类的相关功能



3.创建测试脚本(测试类),编写测试方法调用测试用例
基于appium的app自动化测试框架

 

4.创建服务控制类,通过参数配置的方式连接不同的设备
1)新建yml文件编写测试设备的详细信息
基于appium的app自动化测试框架

 

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()方法。