GitLab Runner Docker环境下Robot Framework+Appium测试连接失败
错误信息
执行测试命令:
$ docker run --network mobile_driver_test_automation_default --rm --mount "type=bind,src=${CI_PROJECT_DIR}/robot/Reports,dst=/app/reports" qa/robot:latest python3 -m robot -d /app/reports /app/Tests/Login.robot
测试失败输出:
Init Page Assertion Design Chaneg Path [ WARN ] Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fdd8c04ea00>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /wd/hub/session
[ WARN ] Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fdd8c04ed60>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /wd/hub/session
[ WARN ] Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fdd8c04eee0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /wd/hub/session
[ WARN ] Keyword 'Capture Page Screenshot' could not be run on failure: No application is open
| FAIL |
MaxRetryError: HTTPConnectionPool(host='appium_server', port=4723): Max retries exceeded with url: /wd/hub/session (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fdd8bff1880>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
相关配置文件
docker-compose.yaml
version: "2.2" services: selenium_hub: image: selenium/hub:3.14.0-curium ports: - 4444:4444 appium_server: image: appium/appium:v1.22.3-p1 depends_on: - selenium_hub network_mode: "service:selenium_hub" volumes: - ./robot/apk:/root/tmp/apk/ environment: - CONNECT_TO_GRID=true - SELENIUM_HOST=selenium_hub - RELAXED_SECURITY=true nexus_emulator: image: budtmo/docker-android-x86-10.0:v1.10-p7 depends_on: - selenium_hub - appium_server volumes: - ./robot/apk:/root/tmp/apk/ ports: - 6080:6080 - 4723:4723 - 5554:5554 - 5555:5555 environment: - DEVICE=Nexus 5 - CONNECT_TO_GRID=true - APPIUM=true - SELENIUM_HOST=selenium_hub - AUTO_RECORD=true
.gitlab-ci.yml
stages: - docker-login - build-robot - setup-test - run-test - docker-down docker-login: stage: docker-login tags: - docker rules: - if: $CI_MERGE_REQUEST_ID when: never - if: $CI_COMMIT_REF_NAME =~ "main" script: - docker login -u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD $ARTIFACTORY_REGISTRY build-robot: stage: build-robot tags: - docker rules: - if: $CI_MERGE_REQUEST_ID when: never - if: $CI_COMMIT_REF_NAME =~ "main" script: - docker build -t qa/robot:latest -f robot/Dockerfile robot setup-test: stage: setup-test tags: - docker rules: - if: $CI_MERGE_REQUEST_ID when: never - if: $CI_COMMIT_REF_NAME =~ "main" script: - docker-compose -f docker-compose.yaml up -d - docker ps run-login-test: stage: run-test tags: - docker rules: - if: $CI_MERGE_REQUEST_ID when: never - if: $CI_COMMIT_REF_NAME =~ "main" script: - docker ps - docker run --network mobile_driver_test_automation_default --rm --mount "type=bind,src=${CI_PROJECT_DIR}/robot/Reports,dst=/app/reports"qa/robot:latest python3 -m robot -d /app/reports /app/Tests/Login.robot artifacts: when: always paths: - robot/Reports/report.html expire_in: 3 day docker-down: stage: docker-down tags: - docker rules: - if: $CI_MERGE_REQUEST_ID when: never - if: $CI_COMMIT_REF_NAME =~ "main" script: - docker-compose -f docker-compose.yaml down
Robot Framework测试脚本(Login.robot)
*** Settings *** Library AppiumLibrary Library Process *** Test Cases *** Init Page Assertion Design Chaneg Path Open Application http://appium_server:4723/wd/hub app=/app/robot/Tests/apk/driver.apk autoGrantPermissions=true platformName=Android deviceName=Nexus 5 appPackage=packageName appActivity=ActivityName Log "app opened succesfully"
Robot镜像Dockerfile
FROM python:3.9 WORKDIR /app COPY . . RUN pip install -r requirements.txt
问题排查与解决方案
1. 核心问题:Appium Server的网络模式导致容器名无法被解析
appium_server服务使用了network_mode: "service:selenium_hub",这意味着它会共享selenium_hub的网络命名空间,不会在docker-compose创建的自定义网络(mobile_driver_test_automation_default)中注册自己的容器名。因此,测试容器无法通过appium_server这个域名找到对应的服务。
2. 解决方案一:修改Appium Server的网络配置
去掉appium_server的network_mode: "service:selenium_hub"配置,让它加入默认的自定义网络,同时保持连接Selenium Grid的配置:
appium_server: image: appium/appium:v1.22.3-p1 depends_on: - selenium_hub # 移除network_mode配置 volumes: - ./robot/apk:/root/tmp/apk/ environment: - CONNECT_TO_GRID=true - SELENIUM_HOST=selenium_hub - RELAXED_SECURITY=true ports: - 4723:4723 # 可选,根据需要保留端口映射
3. 解决方案二:直接使用Selenium Hub的地址连接
如果必须保留network_mode: "service:selenium_hub",那么Appium Server会通过Selenium Hub暴露服务,此时测试脚本中应该连接Selenium Hub的地址,而不是Appium Server:
Open Application http://selenium_hub:4444/wd/hub app=/app/robot/Tests/apk/driver.apk autoGrantPermissions=true platformName=Android deviceName=Nexus 5 appPackage=packageName appActivity=ActivityName
4. 额外检查点
- 确认
setup-test阶段执行后,所有容器(selenium_hub、appium_server、nexus_emulator)都已正常启动,可通过docker ps输出验证。 - 测试容器的
--network参数必须和docker-compose创建的网络一致(mobile_driver_test_automation_default),当前配置已经正确,但注意命令中--mount和qa/robot:latest之间有空格缺失,需要修正:
docker run --network mobile_driver_test_automation_default --rm --mount "type=bind,src=${CI_PROJECT_DIR}/robot/Reports,dst=/app/reports" qa/robot:latest python3 -m robot -d /app/reports /app/Tests/Login.robot
- 确认Android模拟器(nexus_emulator)已经正确连接到Appium Server,可在Appium日志中查看设备连接状态。
内容的提问来源于stack exchange,提问作者Mohammad6pari

