diff --git a/.github/workflows/test-install.yml b/.github/workflows/test-install.yml new file mode 100644 index 0000000..0837f6d --- /dev/null +++ b/.github/workflows/test-install.yml @@ -0,0 +1,52 @@ +name: Test Install Script + +on: + push: + branches: [ dev, master, github_ci_docker_test ] + pull_request: + branches: [ dev, master, github_ci_docker_test ] + +jobs: + test-install: + strategy: + matrix: + ubuntu_version: [18.04, 20.04, 22.04, 24.04] + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run tests in Docker container + run: | + docker run --rm \ + -v ${{ github.workspace }}:${{ github.workspace }} \ + -w ${{ github.workspace }} \ + ubuntu:${{ matrix.ubuntu_version }} \ + bash -c " + set -u && + export DEBIAN_FRONTEND=noninteractive && + # Set timezone to avoid tzdata interactive prompt + ln -sf /usr/share/zoneinfo/UTC /etc/localtime && + apt update && + apt install -y locales && + locale-gen en_US.UTF-8 && + export LANG=en_US.UTF-8 && + export LC_ALL=en_US.UTF-8 && + apt update && apt install -y sudo python3 python3-pip python3-venv python3-yaml python3-distro wget && + python3 -m venv /tmp/test_env && + source /tmp/test_env/bin/activate && + pip install --upgrade pip && + pip install pyyaml distro && + cd tests && + PYTHONIOENCODING=utf-8 python3 -u test_runner.py + " + - name: Upload test reports + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-reports-ubuntu-${{ matrix.ubuntu_version }} + path: | + tests/test_report.json + tests/test_report.html + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index fd20fdd..3bcfd2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ - *.pyc +tests/test_local \ No newline at end of file diff --git a/README.md b/README.md index b3aaa32..57907b0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - 一键安装:ROS(支持ROS和ROS2,树莓派Jetson) [贡献@小鱼](https://github.com/fishros) - 一键安装:VsCode(支持amd64和arm64) [贡献@小鱼](https://github.com/fishros) - 一键安装:github桌面版(小鱼常用的github客户端) [贡献@小鱼](https://github.com/fishros) -- 一键安装:nodejs开发环境(通过nodejs可以预览小鱼官网噢 [贡献@小鱼](https://github.com/fishros) +- 一键安装:nodejs开发环境(通过nodejs可以预览小鱼官网噢) [贡献@小鱼](https://github.com/fishros) - 一键配置:rosdep(小鱼的rosdepc,又快又好用) [贡献@小鱼](https://github.com/fishros) - 一键配置:ROS环境(快速更新ROS环境设置,自动生成环境选择) [贡献@小鱼](https://github.com/fishros) - 一键配置:系统源(更换系统源,支持全版本Ubuntu系统) [贡献@小鱼](https://github.com/fishros) diff --git a/install.py b/install.py index a9d8623..1885b8f 100644 --- a/install.py +++ b/install.py @@ -74,7 +74,7 @@ def main(): # 使用量统计 - CmdTask("wget https://fishros.org.cn/forum/topic/1733 -O /tmp/t1733 -q --timeout 10 && rm -rf /tmp/t1733").run() + CmdTask("wget https://fishros.org.cn/forum/topic/1733 -O /tmp/t1733 -q --no-check-certificate --timeout 10 && rm -rf /tmp/t1733").run() PrintUtils.print_success(tr.tr("已为您切换语言至当前所在国家语言:")+tr.lang) if tr.country != 'CN': @@ -121,11 +121,15 @@ def main(): else: download_tools(code,tools,url_prefix) run_tool_file(tools[code]['tool'].replace("/",".")) - config_helper.gen_config_file() - PrintUtils.print_delay(tr.tr("欢迎加入机器人学习交流QQ群:438144612(入群口令:一键安装)"),0.05) - PrintUtils.print_delay(tr.tr("鱼香小铺正式开业,最低499可入手一台能建图会导航的移动机器人,淘宝搜店:鱼香ROS 或打开链接查看:https://item.taobao.com/item.htm?id=696573635888"),0.001) - PrintUtils.print_delay(tr.tr("如在使用过程中遇到问题,请打开:https://fishros.org.cn/forum 进行反馈"),0.001) + # 检查是否在 GitHub Actions 环境中运行或使用了测试配置文件 + # 如果是,则跳过生成配置文件和后续的打印操作,因为这些操作需要用户输入 + if os.environ.get('GITHUB_ACTIONS') != 'true' and os.environ.get('FISH_INSTALL_CONFIG') is None: + config_helper.gen_config_file() + + PrintUtils.print_delay(tr.tr("欢迎加入机器人学习交流QQ群:438144612(入群口令:一键安装)"),0.05) + PrintUtils.print_delay(tr.tr("鱼香小铺正式开业,最低499可入手一台能建图会导航的移动机器人,淘宝搜店:鱼香ROS 或打开链接查看:https://item.taobao.com/item.htm?id=696573635888"),0.001) + PrintUtils.print_delay(tr.tr("如在使用过程中遇到问题,请打开:https://fishros.org.cn/forum 进行反馈"),0.001) if __name__=='__main__': run_exc = [] diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..8212475 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,64 @@ +# 自动化测试说明 + +本目录包含用于自动化测试 `FishROS Install` 项目的脚本和配置文件。 + +## 文件说明 + +- `test_runner.py`: 主测试运行器,负责执行所有测试用例并生成报告。 +- `fish_install_test.yaml`: 测试配置文件,定义了不同系统版本下的测试用例。 +- `generate_report.py`: 用于生成 HTML 格式的测试报告。 +- `test_report.json`: 测试运行后生成的 JSON 格式报告。 +- `test_report.html`: 测试运行后生成的 HTML 格式报告。 + +## 运行测试 + +在项目根目录下执行以下命令来运行测试: + +```bash +cd tests +python3 test_runner.py +``` + +### 指定目标系统版本 + +可以通过 `--target-os-version` 参数指定要测试的 Ubuntu 版本代号: + +```bash +python3 test_runner.py --target-os-version focal +``` + +## 测试配置文件 + +`fish_install_test.yaml` 文件定义了测试用例。每个测试用例包含以下信息: + +- `name`: 测试用例名称。 +- `target_os_version`: 目标系统版本代号 (可选,如果不指定则适用于所有系统)。 +- `chooses`: 一个列表,包含在安装过程中需要自动选择的选项。 + +### 配置文件易错点提醒 + +1. `chooses` 列表中的 `choose` 值必须与 `install.py` 中 `tools` 字典的键值对应。 +2. `target_os_version` 必须是有效的 Ubuntu 版本代号(如 `bionic`, `focal`, `jammy` 等),目前仅支持ubuntu系列。 +3. `desc` 字段虽然不是必须的,但建议填写以方便理解。 +4. 在添加新的测试用例时,确保 `chooses` 中的选项序列能够完整地执行一个安装流程,避免因选项不当导致测试中断。 + +## 自动化测试与用户实际安装的区别 + +自动化测试与用户实际安装在以下方面有所不同: + +1. **配置文件**: 自动化测试使用 `FISH_INSTALL_CONFIG` 环境变量指定的配置文件,而用户实际安装时会交互式地选择选项并生成配置文件。 +2. **环境变量**: 自动化测试会设置特定的环境变量(如 `FISH_INSTALL_CONFIG`),而用户实际安装时不会。 +3. **跳过某些步骤**: 在自动化测试环境中,会跳过一些需要用户交互的步骤,例如生成配置文件的确认提示。 +4. **GitHub Actions**: 在 GitHub Actions 中运行时,会进一步跳过一些步骤以适应 CI/CD 环境。 + +## 工作原理 + +1. `test_runner.py` 会读取 `fish_install_test.yaml` 文件,加载所有适用于当前系统版本的测试用例。 +2. 对于每个测试用例,`test_runner.py` 会创建一个临时的 `fish_install.yaml` 配置文件,其中包含该测试用例的 `chooses` 信息。 +3. 然后,`test_runner.py` 会运行 `../install.py` 脚本,并通过环境变量 `FISH_INSTALL_CONFIG` 指定使用临时配置文件。 +4. `install.py` 会根据配置文件中的选项自动执行安装过程,无需人工干预。 +5. 测试运行结束后,`test_runner.py` 会生成 JSON 和 HTML 格式的测试报告。 + +## GitHub Actions 集成 + +本测试套件已集成到 GitHub Actions 中,每次推送代码时都会自动运行。工作流文件位于 `.github/workflows/test-install.yml`。 \ No newline at end of file diff --git a/tests/fish_install_test.yaml b/tests/fish_install_test.yaml new file mode 100644 index 0000000..5e4ede6 --- /dev/null +++ b/tests/fish_install_test.yaml @@ -0,0 +1,56 @@ +# 测试配置文件,用于 GitHub Actions 自动化测试 +# 格式: +# - name: "测试用例名称" +# target_os_version: "目标系统版本代号" (可选,如果不指定则适用于所有系统) +# chooses: [{choose: <选项ID>, desc: <选项描述>}] + +# 为不同的 Ubuntu 版本定义具体的测试配置 +# Ubuntu 18.04 (bionic) - Melodic +- name: "Install_ROS_bionic" + target_os_version: "bionic" + chooses: + - { choose: 1, desc: "一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)" } + - { choose: 2, desc: "不更换系统源再继续安装" } + - { choose: 4, desc: "ROS官方源" } + - { choose: 1, desc: "支持的第一个ros版本" } + - { choose: 2, desc: "基础版(小)" } + +# Ubuntu 20.04 (focal) - Noetic 或 Foxy +- name: "Install_ROS_focal_noetic" + target_os_version: "focal" + chooses: + - { choose: 1, desc: "一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)" } + - { choose: 2, desc: "不更换系统源再继续安装" } + - { choose: 4, desc: "ROS官方源" } + - { choose: 1, desc: "支持的第一个ros版本" } + - { choose: 2, desc: "基础版(小)" } + +# - name: "Install_ROS_focal_foxy" +# target_os_version: "focal" +# chooses: +# - { choose: 1, desc: "一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)" } +# - { choose: 2, desc: "不更换系统源再继续安装" } +# - { choose: 4, desc: "ROS官方源" } +# - { choose: 1, desc: "支持的第一个ros版本" } +# - { choose: 2, desc: "基础版(小)" } + +# Ubuntu 22.04 (jammy) - Humble +- name: "Install_ROS_jammy" + target_os_version: "jammy" + chooses: + - { choose: 1, desc: "一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)" } + - { choose: 2, desc: "不更换系统源再继续安装" } + - { choose: 4, desc: "ROS官方源" } + - { choose: 1, desc: "支持的第一个ros版本" } + - { choose: 2, desc: "基础版(小)" } + +# Ubuntu 24.04 (noble) - Jazzy +- name: "Install_ROS_noble" + target_os_version: "noble" + chooses: + - { choose: 1, desc: "一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)" } + - { choose: 2, desc: "不更换系统源再继续安装" } + - { choose: 4, desc: "ROS官方源" } + - { choose: 1, desc: "支持的第一个ros版本" } + - { choose: 2, desc: "基础版(小)" } + diff --git a/tests/generate_report.py b/tests/generate_report.py new file mode 100644 index 0000000..ad77730 --- /dev/null +++ b/tests/generate_report.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import json +import time +import os + +def generate_html_report(report, output_file): + """生成HTML格式的测试报告""" + html_content = """ + + +
+ + +生成时间: """ + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + """
+总计: """ + str(report["summary"]["total"]) + """
+通过: """ + str(report["summary"]["passed"]) + """
+失败: """ + str(report["summary"]["failed"]) + """
+生成时间: """ + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + """
+总计: """ + str(report["summary"]["total"]) + """
+通过: """ + str(report["summary"]["passed"]) + """
+失败: """ + str(report["summary"]["failed"]) + """
+