Skip to content

Test coverage

Test coverage #1

Workflow file for this run

name: Test coverage
on:
workflow_dispatch:
inputs:
git_ref:
type: string
description: Git ref of the DuckDB python package
default: refs/heads/main
required: true
duckdb_git_ref:
type: string
description: Git ref of DuckDB
testsuite:
type: choice
description: Testsuite to run ('all' or 'fast')
default: all
required: true
options:
- all
- fast
workflow_call:
inputs:
git_ref:
type: string
description: Git ref of the DuckDB python package
required: true
duckdb_git_ref:
type: string
testsuite:
type: string
description: Testsuite to run ('all' or 'fast')
required: true
default: all
concurrency:
group: coverage-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
generate_coverage_reports:
name: Generate code coverage reports for both Python and C++ code
runs-on: ubuntu-24.04
env: { COVERAGE: 1 }
outputs:
summary_py: ${{ steps.py_coverage.outputs.summary }}
summary_cpp: ${{ steps.cpp_coverage.outputs.summary }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.git_ref }}
fetch-depth: 0
submodules: true
- name: Checkout DuckDB to provided ref
if: ${{ inputs.duckdb_git_ref != '' }}
shell: bash
run: |
cd external/duckdb
git fetch origin
git checkout ${{ inputs.duckdb_git_ref }}
- name: Install Ccache
shell: bash
run: |
sudo apt-get update
sudo apt-get -y install ccache
- name: Install Astral UV and enable the cache
uses: astral-sh/setup-uv@v6
with:
version: "0.7.14"
python-version: 3.9
enable-cache: true
cache-suffix: -${{ github.workflow }}
- name: Run tests with coverage
shell: bash
run: |
if [[ "${{ inputs.testsuite }}" == "all" ]]; then
uv run coverage run -m pytest ./tests --ignore=./tests/stubs
elif [[ "${{ inputs.testsuite }}" == "fast" ]]; then
uv run coverage run -m pytest ./tests/fast
else
echo "Invalid testsuite!"
exit 1
fi
- name: Get Python coverage data
id: py_coverage
shell: bash
run: |
# save HTML report in coverage-python
uv run coverage html -d coverage-python
# save markdown summary in step output
echo "summary<<EOF" >> $GITHUB_OUTPUT
uv run coverage report --format=markdown >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Upload Python coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report-python
path: coverage-python
- name: Get C++ coverage data
id: cpp_coverage
shell: bash
run: |
mkdir coverage-cpp
uv run gcovr \
--gcov-ignore-errors all \
--root "$PWD" \
--filter "${PWD}/src/duckdb_py" \
--exclude '.*/\.cache/.*' \
--gcov-exclude '.*/\.cache/.*' \
--gcov-exclude '.*/external/.*' \
--gcov-exclude '.*/site-packages/.*' \
--exclude-unreachable-branches \
--exclude-throw-branches \
--html --html-details -o coverage-cpp/index.html \
build/coverage/src/duckdb_py \
--print-summary > cpp_summary.txt
# save the summary in the output
echo "summary<<EOF" >> $GITHUB_OUTPUT
cat cpp_summary.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Upload C++ coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report-cpp
path: coverage-cpp
summary:
name: Coverage Summary
runs-on: ubuntu-24.04
needs: [generate_coverage_reports]
env:
SUMMARY_PY: ${{ needs.generate_coverage_reports.outputs.summary_py }}
SUMMARY_CPP: ${{ needs.generate_coverage_reports.outputs.summary_cpp }}
if: always()
steps:
- name: Summarize
shell: bash
run: |
echo "## Coverage Summary" >> $GITHUB_STEP_SUMMARY
echo "### Python Coverage Summary" >> $GITHUB_STEP_SUMMARY
echo "$SUMMARY_PY" >> $GITHUB_STEP_SUMMARY
echo "### C++ Coverage Summary" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$SUMMARY_CPP" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY