Skip to content

[fix]修了几个问题 #3

[fix]修了几个问题

[fix]修了几个问题 #3

Workflow file for this run

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