在多个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》

原文地址:https://www.cnblogs.com/my_captain/p/12741527.html