[fix]修了几个问题 #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Python测试 | |
| on: | |
| push: | |
| branches: [ "main", "master" ] | |
| paths: | |
| - 'exercises/**' | |
| - 'tests/**' | |
| - 'requirements.txt' | |
| # 允许手动触发 | |
| workflow_dispatch: | |
| inputs: | |
| reason: | |
| description: '运行原因' | |
| required: false | |
| default: '手动测试' | |
| jobs: | |
| # 确保测试只在非原始仓库运行 | |
| test: | |
| # 添加条件,只在非原始仓库所有者时运行 | |
| if: github.repository_owner != 'PythonTrainingCamp' | |
| name: Python ${{ matrix.python-version }} on ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest] | |
| python-version: ["3.8", "3.9", "3.10"] | |
| steps: | |
| - name: 输出调试信息 | |
| run: | | |
| echo "当前仓库: ${{ github.repository }}" | |
| echo "仓库所有者: ${{ github.repository_owner }}" | |
| echo "推送者: ${{ github.actor }}" | |
| echo "原始仓库所有者: PythonTrainingCamp" | |
| shell: bash | |
| - uses: actions/checkout@v3 | |
| with: | |
| fetch-depth: 0 # 获取完整历史以便比较更改 | |
| - name: 设置 Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: 'pip' | |
| - name: 安装依赖 | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install flake8 pytest pytest-cov | |
| python -m pip install -r requirements.txt | |
| shell: bash | |
| - name: 代码质量检查 | |
| run: | | |
| # 仅检查exercises目录中提交的Python文件 | |
| flake8 exercises --count --select=E9,F63,F7,F82 --show-source --statistics | |
| shell: bash | |
| - name: 识别修改的文件 | |
| id: changed-files | |
| uses: tj-actions/changed-files@v35 | |
| with: | |
| files: exercises/**/*.py | |
| - name: 运行针对变更文件的测试 (Linux) | |
| if: steps.changed-files.outputs.any_changed == 'true' && runner.os == 'Linux' | |
| run: | | |
| echo "🔎 检测到修改的文件:" | |
| for file in ${{ steps.changed-files.outputs.all_changed_files }}; do | |
| echo " 📝 $file 已修改" | |
| # 从文件路径提取测试文件名 | |
| filename=$(basename "$file") | |
| test_file="tests/test_${filename}" | |
| if [ -f "$test_file" ]; then | |
| echo " 🧪 运行测试: $test_file" | |
| python -m pytest "$test_file" -v | |
| else | |
| echo " ❓ 找不到对应的测试文件: $test_file" | |
| fi | |
| done | |
| shell: bash | |
| - name: 运行针对变更文件的测试 (Windows) | |
| if: steps.changed-files.outputs.any_changed == 'true' && runner.os == 'Windows' | |
| run: | | |
| echo "🔎 检测到修改的文件:" | |
| foreach($file in "${{ steps.changed-files.outputs.all_changed_files }}".Split()) { | |
| echo " 📝 $file 已修改" | |
| # 从文件路径提取测试文件名 | |
| $filename = Split-Path $file -Leaf | |
| $test_file = "tests/test_$filename" | |
| if (Test-Path $test_file) { | |
| echo " 🧪 运行测试: $test_file" | |
| python -m pytest $test_file -v | |
| } else { | |
| echo " ❓ 找不到对应的测试文件: $test_file" | |
| } | |
| } | |
| shell: pwsh | |
| - name: 运行所有测试并生成覆盖率报告 | |
| run: | | |
| python -m pytest --cov=exercises tests/ --cov-report=xml -v | tee pytest-output.txt | |
| shell: bash | |
| - name: 生成测试报告摘要 (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| echo "### 测试结果总结" >> $GITHUB_STEP_SUMMARY | |
| if [ -f pytest-output.txt ]; then | |
| passed=$(grep -c "PASSED" pytest-output.txt || echo "0") | |
| failed=$(grep -c "FAILED" pytest-output.txt || echo "0") | |
| echo "通过的测试: $passed" >> $GITHUB_STEP_SUMMARY | |
| echo "失败的测试: $failed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "[警告] 未找到测试输出文件" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [ -f coverage.xml ]; then | |
| coverage=$(grep -o "line-rate=\"[0-9.]*\"" coverage.xml | head -1 | grep -o "[0-9.]*" || echo "0") | |
| if [ ! -z "$coverage" ]; then | |
| coverage=$(printf "%.1f" $(echo "$coverage * 100" | bc)) | |
| if (( $(echo "$coverage > 80" | bc -l) )); then | |
| echo "测试覆盖率: ${coverage}% (优秀)" >> $GITHUB_STEP_SUMMARY | |
| elif (( $(echo "$coverage > 60" | bc -l) )); then | |
| echo "测试覆盖率: ${coverage}% (良好)" >> $GITHUB_STEP_SUMMARY | |
| elif (( $(echo "$coverage > 40" | bc -l) )); then | |
| echo "测试覆盖率: ${coverage}% (一般)" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "测试覆盖率: ${coverage}% (需要改进)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "测试覆盖率: 未知" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "测试覆盖率: 未生成报告" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 练习完成情况" >> $GITHUB_STEP_SUMMARY | |
| total=0 | |
| passed=0 | |
| for file in exercises/*.py; do | |
| if [ -f "$file" ]; then | |
| total=$((total+1)) | |
| filename=$(basename "$file") | |
| test_file="tests/test_${filename}" | |
| if [ -f "$test_file" ]; then | |
| if python -m pytest "$test_file" -v > /dev/null 2>&1; then | |
| passed=$((passed+1)) | |
| echo "- [通过] $filename" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "- [未通过] $filename" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "- [无测试] $filename" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| fi | |
| done | |
| # 计算完成度 | |
| if [ $total -ne 0 ]; then | |
| completion=$(echo "scale=1; $passed * 100 / $total" | bc) | |
| # 创建进度条 | |
| progress_bar="" | |
| bar_length=20 | |
| filled_length=$(echo "scale=0; $bar_length * $passed / $total" | bc) | |
| # 确保filled_length是整数 | |
| filled_length=${filled_length%.*} | |
| # 防止除零错误 | |
| if [ -z "$filled_length" ]; then | |
| filled_length=0 | |
| fi | |
| # 构建进度条 | |
| for ((i=0; i<$bar_length; i++)); do | |
| if [ $i -lt $filled_length ]; then | |
| progress_bar="${progress_bar}#" | |
| else | |
| progress_bar="${progress_bar}-" | |
| fi | |
| done | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 训练营学习进度" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 根据完成百分比选择不同的评价 | |
| if (( $(echo "$completion > 90" | bc -l) )); then | |
| echo "[优秀] $progress_bar $completion%" >> $GITHUB_STEP_SUMMARY | |
| echo "恭喜,您已经完成了绝大部分练习,表现非常出色!" >> $GITHUB_STEP_SUMMARY | |
| elif (( $(echo "$completion > 70" | bc -l) )); then | |
| echo "[良好] $progress_bar $completion%" >> $GITHUB_STEP_SUMMARY | |
| echo "表现良好,您已完成大部分练习,继续保持!" >> $GITHUB_STEP_SUMMARY | |
| elif (( $(echo "$completion > 50" | bc -l) )); then | |
| echo "[中等] $progress_bar $completion%" >> $GITHUB_STEP_SUMMARY | |
| echo "已经完成一半以上的练习,继续加油!" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "[初级] $progress_bar $completion%" >> $GITHUB_STEP_SUMMARY | |
| echo "您已经开始学习,后续需要继续练习。" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # 显示具体数字 | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "已完成: $passed / $total 个练习" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| shell: bash | |
| - name: 生成测试报告摘要 (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| echo "### 测试结果总结" >> $env:GITHUB_STEP_SUMMARY | |
| if (Test-Path pytest-output.txt) { | |
| $content = Get-Content pytest-output.txt | |
| $passed = ($content | Select-String "PASSED" -AllMatches).Matches.Count | |
| $failed = ($content | Select-String "FAILED" -AllMatches).Matches.Count | |
| echo "通过的测试: $passed" >> $env:GITHUB_STEP_SUMMARY | |
| echo "失败的测试: $failed" >> $env:GITHUB_STEP_SUMMARY | |
| } else { | |
| echo "[警告] 未找到测试输出文件" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| if (Test-Path coverage.xml) { | |
| $xml = [xml](Get-Content coverage.xml) | |
| $coverage = [float]$xml.coverage.LineRate * 100 | |
| $coverage = [math]::Round($coverage, 1) | |
| if ($coverage -gt 80) { | |
| echo "测试覆盖率: ${coverage}% (优秀)" >> $env:GITHUB_STEP_SUMMARY | |
| } elseif ($coverage -gt 60) { | |
| echo "测试覆盖率: ${coverage}% (良好)" >> $env:GITHUB_STEP_SUMMARY | |
| } elseif ($coverage -gt 40) { | |
| echo "测试覆盖率: ${coverage}% (一般)" >> $env:GITHUB_STEP_SUMMARY | |
| } else { | |
| echo "测试覆盖率: ${coverage}% (需要改进)" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| } else { | |
| echo "测试覆盖率: 未生成报告" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| echo "" >> $env:GITHUB_STEP_SUMMARY | |
| echo "### 练习完成情况" >> $env:GITHUB_STEP_SUMMARY | |
| $total = 0 | |
| $passed = 0 | |
| Get-ChildItem exercises -Filter *.py | ForEach-Object { | |
| $total++ | |
| $filename = $_.Name | |
| $test_file = "tests/test_$filename" | |
| if (Test-Path $test_file) { | |
| $result = python -m pytest $test_file -v 2>&1 | |
| if ($LASTEXITCODE -eq 0) { | |
| $passed++ | |
| echo "- [通过] $filename" >> $env:GITHUB_STEP_SUMMARY | |
| } else { | |
| echo "- [未通过] $filename" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| } else { | |
| echo "- [无测试] $filename" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| } | |
| # 计算完成度 | |
| if ($total -ne 0) { | |
| $completion = [math]::Round(($passed * 100 / $total), 1) | |
| # 创建进度条 | |
| $progress_bar = "" | |
| $bar_length = 20 | |
| $filled_length = [math]::Floor($bar_length * $passed / $total) | |
| # 构建进度条 | |
| for ($i=0; $i -lt $bar_length; $i++) { | |
| if ($i -lt $filled_length) { | |
| $progress_bar = "$progress_bar#" | |
| } else { | |
| $progress_bar = "$progress_bar-" | |
| } | |
| } | |
| echo "" >> $env:GITHUB_STEP_SUMMARY | |
| echo "## 训练营学习进度" >> $env:GITHUB_STEP_SUMMARY | |
| echo "" >> $env:GITHUB_STEP_SUMMARY | |
| # 根据完成百分比选择不同的评价 | |
| if ($completion -gt 90) { | |
| echo "[优秀] $progress_bar $completion%" >> $env:GITHUB_STEP_SUMMARY | |
| echo "恭喜,您已经完成了绝大部分练习,表现非常出色!" >> $env:GITHUB_STEP_SUMMARY | |
| } elseif ($completion -gt 70) { | |
| echo "[良好] $progress_bar $completion%" >> $env:GITHUB_STEP_SUMMARY | |
| echo "表现良好,您已完成大部分练习,继续保持!" >> $env:GITHUB_STEP_SUMMARY | |
| } elseif ($completion -gt 50) { | |
| echo "[中等] $progress_bar $completion%" >> $env:GITHUB_STEP_SUMMARY | |
| echo "已经完成一半以上的练习,继续加油!" >> $env:GITHUB_STEP_SUMMARY | |
| } else { | |
| echo "[初级] $progress_bar $completion%" >> $env:GITHUB_STEP_SUMMARY | |
| echo "您已经开始学习,后续需要继续练习。" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| # 显示具体数字 | |
| echo "" >> $env:GITHUB_STEP_SUMMARY | |
| echo "已完成: $passed / $total 个练习" >> $env:GITHUB_STEP_SUMMARY | |
| } | |
| shell: pwsh | |
| - name: 上传覆盖率报告 | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./coverage.xml | |
| fail_ci_if_error: false |