如何配置GitHub Actions实现pytest仅运行PR变更相关测试
配置方案
核心实现逻辑:
- 修正代码检出步骤的浅克隆限制,拉取完整提交历史用于分支diff对比
- 在测试执行前新增文件收集步骤,通过git diff拿到当前PR相对于master分支的所有变更文件
- 按照目录映射规则匹配变更文件对应的pytest测试用例,仅将匹配到的测试路径传入pytest执行
完整修改后的工作流配置
name: Python tests on: pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: # 拉取完整提交历史,支持分支diff对比 fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v3 with: python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | # 存在Python语法错误或未定义名称时直接终止构建 flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # 其余风格问题仅做警告提示 flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Collect changed files and match test cases id: collect-tests run: | # 获取PR相对于master分支的所有变更Python文件 CHANGED_FILES=$(git diff --name-only origin/master...HEAD -- "*.py") TEST_FILES=() for file in $CHANGED_FILES; do # 规则1:变更的是tests目录下的测试文件,直接加入执行列表 if [[ $file == tests/test_*.py ]]; then if [ -f "$file" ]; then TEST_FILES+=("$file") fi fi # 规则2:变更的是utils目录下的源码文件,映射对应test文件 if [[ $file == utils/*.py ]]; then # 提取源码文件名,拼接对应测试文件路径 src_filename=$(basename "$file" .py) test_path="tests/test_${src_filename}.py" if [ -f "$test_path" ]; then TEST_FILES+=("$test_path") fi fi # 可选规则:如果改了公共配置、根目录初始化文件,直接跑全量测试 if [[ $file == utils/__init__.py || $file == requirements.txt ]]; then TEST_FILES=("tests/") break fi done # 去重测试文件列表 UNIQUE_TESTS=($(echo "${TEST_FILES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) # 输出结果,供后续步骤使用 if [ ${#UNIQUE_TESTS[@]} -eq 0 ]; then echo "test_files=" >> $GITHUB_OUTPUT echo "::notice::No matched test cases for changed files, skip pytest." else echo "Matched test cases to run: ${UNIQUE_TESTS[*]}" echo "test_files=${UNIQUE_TESTS[*]}" >> $GITHUB_OUTPUT fi - name: Test with pytest if: steps.collect-tests.outputs.test_files != '' run: | pytest ${{ steps.collect-tests.outputs.test_files }}
规则说明
- 配置完全适配你当前的仓库目录结构:
utils/存源码、tests/存测试,测试文件命名为test_<对应源码文件名>.py - 以你给出的场景为例:PR仅新增
utils/sub.py和tests/test_sub.py时,diff识别到变更后只会匹配tests/test_sub.py传入pytest,原有test_add.py不会被执行 - 如果改动了公共初始化文件
utils/__init__.py或依赖文件requirements.txt,会自动触发全量测试,避免漏测公共逻辑变更 - 没有匹配到任何对应测试用例时,会自动跳过pytest步骤并给出提示,不会导致CI报错
内容的提问来源于stack exchange,提问作者Shivam Singh
相关产品推荐
相关产品推荐

