• 在多个docker容器中并行执行app自动化测试


    准备工作

    升级Python版本

    Centos7中自带的Python版本是2.7.5,app自动化是用Python3写的,因此需要升级Centos7的Python版本

    # 切换工作目录到/opt
    cd /opt
    
    # 下载目标Python版本的压缩包
    wget http://npm.taobao.org/mirrors/python/3.8.0/Python-3.8.0.tgz
    
    # 安装解压命令unzip
    pip install -y unzip
    
    # 解压压缩包
    tar -zxvf Python-3.8.0.tgz
    
    # 安装libffi-devel  tk-devel,否则编译和pip install过程中会报ModuleNotFoundError: No module named '_ctypes'的错误
    yum -y install libffi-devel  tk-devel 
    
    # 安装gcc,否则编译时会报错
    yum -y install gcc
    
    # 切换到Python-3.8.0目录
    cd Python-3.8.0
    
    # 生配置
    # 注意这里要加上--prefix能好点。如果不加,安装后的可执行文件默认放在/usr/local/bin
    # 库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc,其他资源默认放在
    # /usr/local/share。比较杂乱。如果加上,会把所有的资源文件都放在指定路径下,卸载
    # 时,只需要删除该目录即可
    ./configure --prefix=/opt/Python-3.8.0
    
    # 编译安装
    make && make install 
    
    # 创建软链接:创建后输入python3就可以进入到python3的环境
    ln -s /opt/Python-3.8.0/bin/python3 /usr/bin/python3
    
    # 配置环境变量
    vim /etc/profile
    在PATH后加上::$PATH:/opt/Python-3.8.0/bin
    source /etc/profile
    

    pip配置国内源

    为了提高pip安装速度,将pip配置为国内镜像源

    # 在家目录下创建.pip目录
    cd ~
    mkdir .pip
    
    # 切换到pip目录并创建pip.conf文件
    cd .pip
    touch pip.conf
    
    #编辑pip.conf,输入以下内容保存
    vim pip.conf
    [global]
    timeout = 100
    index-url =  http://mirrors.aliyun.com/pypi/simple/
    [install]
    trusted-host = mirrors.aliyun.com
    
    # 升级pip
    pip3 install --upgrade pip
    

    安装依赖库

    在本地项目根目录下的命令行中,使用pip freeze将依赖库信息信息输出到requirement.txt文件

    pip freeze >requirements.txt
    

    然后将项目压缩成zip包,通过rz命令上传到Centos7的/work_shop目录下,然后解压

    接着进入到项目目录下,安装依赖库

    启动容器

    在上次已经启动了一个4723端口的appium容器,现在再手动启动一个4725的appium容器,名字命名为appium_2

    docker run --privileged -d -p 4725:4725 --name appium_2 appium/appium
    

    模拟器设置

    利用夜神多开器启动另一个安卓5.1.1的模拟器,设置桥接,静态ip为192.168.0.104

    然后设置模拟器的连接方式为tcpip连接

    C:Userseck
    λ adb cdevices
    List of devices attached
    127.0.0.1:62025 device   #安卓7
    127.0.0.1:62001 device   #安卓5
    
    C:Userseck
    λ adb c-s 127.0.0.1:62001 tcpip 5555
    restarting in TCP mode port: 5555
    

    docker连接模拟器

    docker exec -it appium_1 adb connect 192.168.0.102:6666
    docker exec -it appium_2 adb connect 192.168.0.104:5555
    

    如果能看到这样的输出说明已经都连接上了

    修改python代码

    修改main.py

    main.py里主要是修改device_infos中的信息,比如加入了docker_name,以便BaseDriver初始化时使用它,device_ip是模拟器桥接后得到的静态ip,device_port是给模拟器设置的tcp端口号

    import pytest, os
    import time
    from common.conf_dir import root_dir, logs_dir, html_reports_dir
    from multiprocessing import Pool
    from clean import *
    
    device_infos = [{"docker_name": "appium_1", "platform_version": "7.1.2", "device_ip":"192.168.0.102", "device_port": 6666, "server_port": 4723, "system_port": 8200},
                    {"docker_name": "appium_2", "platform_version": "5.1.1", "device_ip":"192.168.0.104", "device_port": 5555, "server_port": 4725, "system_port": 8201}]
    
    
    cur_time = time.strftime("%Y-%m-%d_%H-%M-%S")
    
    def run_parallel(device_info):
        pytest.main([
            f"--cmdopt={device_info}",
            #"--reruns=1",
            #"--reruns-delay=10",
            "-m", "fail",
            "--junitxml", f"{html_reports_dir}/autotest_report_{cur_time}.xml",
            "--html", f"{html_reports_dir}/autotest_report_{cur_time}.html",
            "--css", f"{html_reports_dir}/assets/style.css",
            "--self-contained-html"])
    
    
    
    if __name__ == "__main__":
        with Pool(2) as pool:
            pool.map(run_parallel, device_infos)
            pool.close()
            pool.join()
    

    修改base_driver.py

    在BaseDriver.py的初始化方法__init__中加入cmd和os.system(cmd),注意不能使用docker logs -f appium_1,因为输出appium server实时日志时,后面的代码就一直卡在那里,所以使用docker appium_1这种方式

    from appium import webdriver
    from .conf_dir import caps_dir
    import yaml
    import os
    
    
    class BaseDriver:
    
        def __init__(self, device_info):
            self.device_info = device_info
            cmd = f"docker {self.device_info['docker_name']}"
            os.system(cmd)
    
    
    
        def base_driver(self, automationName="appium"):
            fs = open(f"{caps_dir}//caps.yml")
            #平台名称、包名、Activity名称、超时时间、是否重置、server_ip、
            desired_caps = yaml.load(fs, Loader=yaml.FullLoader)
            #版本信息
            desired_caps["platform_version"] = self.device_info["platform_version"]
            #设备名称
            desired_caps["deviceName"] = f"{self.device_info['device_ip']}:{self.device_info['device_port']}"
            #系统端口号
            desired_caps["systemPort"] = self.device_info["system_port"]
    
            if automationName != "appium":
                desired_caps["automationName"] = automationName
    
            driver = webdriver.Remote(f"http://127.0.0.1:{self.device_info['server_port']}/wd/hub", desired_capabilities=desired_caps)
            return driver
    

    运行

    切换到/workshop/APP_AutoTest目录后,使用python3运行main.py

    python3 main.py
    


    测试报告

    右下角是我们添加的失败用例的截图,这个报告比较简陋,后面会使用allure优化

    源码下载

    git clone https://github.com/cnhkzyy/appium-app-test.git
    git checkout version11.0
    

    参考文章

    《CentOS7 下升级Python版本》
    《在centos上配置Python pip国内镜像源》
    《安装python3.7出现ModuleNotFoundError: No module named '_ctypes'解决办法》
    《「docker实战篇」python的docker-创建appium容器以及设置appium容器连接安卓模拟器(31)》
    《docker 部署appium》

  • 相关阅读:
    [LeetCode] 137. Single Number II
    [LeetCode] 136. Single Number
    [LeetCode] 678. Valid Parenthesis String
    [LeetCode] 605. Can Place Flowers
    [LeetCode] 419. Battleships in a Board
    [LeetCode] 1002. Find Common Characters
    [LeetCode] 912. Sort an Array
    [LeetCode] 350. Intersection of Two Arrays II
    [LeetCode] 349. Intersection of Two Arrays
    [LeetCode] 820. Short Encoding of Words
  • 原文地址:https://www.cnblogs.com/my_captain/p/12741527.html
Copyright © 2020-2023  润新知