Skip to content

experiment: Pytest speed exploration #10910

experiment: Pytest speed exploration

experiment: Pytest speed exploration #10910

Workflow file for this run

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Checks
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
# NOTE: the value of `group` should be chosen carefully,
# otherwise we might end up over- or under-canceling workflow runs
# github.head_ref is only defined for pull request events
# so, if it's not present (i.e. event was triggered by push)
# we use github.ref instead
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
defaults:
run:
# important to make sure that all commands on Windows are run using Bash
# -l: login shell, needed when using Conda
shell: bash -l {0}
env:
# --color=yes needed for colorized output to be shown in GHA logs
# --pyargs watertap is needed to be able to define CLI options in watertap/conftest.py
PYTEST_ADDOPTS: "--color=yes"
PIP_PROGRESS_BAR: "off"
WATERTAP_KERNEL_NAME: watertap-dev
jobs:
code-formatting:
name: Check code is formatted (Black)
# OS and/or Python version don't make a difference, so we choose ubuntu and 3.8 as defaults
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install Black
# unlike the other jobs, we don't need to install WaterTAP and/or all the dev dependencies,
# but we still want to specify the Black version to use in requirements-dev.txt for local development
# so we extract the relevant line and pass it to a simple `pip install`
run: |
black_requirement="$(grep -Eo '"black==[^"]+"' pyproject.toml | tr -d '"')"
pip --no-cache-dir install "$black_requirement"
- name: Run Black to verify that the committed code is formatted
run: |
black --check .
pylint:
name: Code linting (pylint)
runs-on: ubuntu-latest
needs: [code-formatting]
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dev dependencies
run: |
pip install -e ".[dev]"
pip list
- name: Environment summary
uses: ./.github/actions/environment-summary
with:
python-version: '3.11'
os: ubuntu-latest
job-name: pylint
- name: Run pylint
run: |
pylint watertap
tests-pr:
name: Tests (py${{ matrix.python-version }}/${{ matrix.os }})
if: github.event_name == 'pull_request'
runs-on: ${{ matrix.os-version }}
needs: [code-formatting]
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
os:
- linux
- win64
exclude:
- os: win64
python-version: '3.10'
- os: win64
python-version: '3.11'
- os: win64
python-version: '3.13'
include:
- os: linux
os-version: ubuntu-22.04
- os: linux
python-version: '3.12'
coverage: true
- os: win64
os-version: windows-2022
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v4
with:
activate-environment: watertap-dev
python-version: ${{ matrix.python-version }}
miniforge-version: latest
channels: conda-forge
conda-remove-defaults: 'true'
- name: Install dependencies
run: |
echo '::group::Output of "conda install" commands'
conda install --quiet --yes pip setuptools wheel pandoc
echo '::endgroup::'
echo '::group::Output of "pip install" commands'
# Install WaterTAP + dev dependencies from pyproject.toml
pip install -e ".[dev]"
echo '::endgroup::'
echo '::group::Output of "conda install -c conda-forge reaktoro cyipopt" command'
conda install -c conda-forge reaktoro cyipopt
echo '::endgroup::'
echo '::group::Display installed packages'
conda list
pip list
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Environment summary
uses: ./.github/actions/environment-summary
with:
python-version: ${{ matrix.python-version }}
os: ${{ matrix.os }}
job-name: tests
- name: Add coverage report pytest options
if: matrix.coverage
run:
|
echo PYTEST_ADDOPTS="$PYTEST_ADDOPTS --cov --cov-report=xml" >> $GITHUB_ENV
- name: Test with pytest
run: |
pytest --pyargs watertap --idaes-flowsheets --entry-points-group watertap.flowsheets --file-durations
- name: Upload pytest duration reports as job artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: pytest-duration-reports-${{ matrix.os }}-py${{ matrix.python-version }}
path: pytest-duration-reports/*.csv
if-no-files-found: warn
- name: Upload coverage report as job artifact
if: matrix.coverage
uses: actions/upload-artifact@v7
with:
name: coverage-report-${{ matrix.os }}
path: coverage.xml
if-no-files-found: error
- name: Test documentation code
run: |
make -C docs doctest -d
# TODO: this should be moved to a dedicated job/workflow
# until then, we can leave this here as a reminder
- name: Test documentation links
if: 'false'
run: |
make -C docs linkcheck -d
tests-main:
name: Tests (py${{ matrix.python-version }}/${{ matrix.os }})
if: github.event_name == 'push'
runs-on: ${{ matrix.os-version }}
needs: [code-formatting]
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
os:
- linux
- win64
# - macos
include:
- os: linux
os-version: ubuntu-22.04
- os: win64
os-version: windows-2022
# - os: macos
# os-version: macos-10.15
- os: linux
python-version: '3.12'
# limit uploading coverage report for a single Python version in the matrix
coverage: true
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v4
with:
activate-environment: watertap-dev
python-version: ${{ matrix.python-version }}
miniforge-version: latest
channels: conda-forge
conda-remove-defaults: 'true'
- name: Install dependencies
run: |
echo '::group::Output of "conda install" commands'
conda install --quiet --yes pip setuptools wheel pandoc
echo '::endgroup::'
echo '::group::Output of "pip install" commands'
# Install WaterTAP + dev dependencies from pyproject.toml
pip install -e ".[dev]"
echo '::endgroup::'
echo '::group::Output of "conda install -c conda-forge reaktoro cyipopt" command'
conda install -c conda-forge reaktoro cyipopt
echo '::endgroup::'
echo '::group::Display installed packages'
conda list
pip list
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Environment summary
uses: ./.github/actions/environment-summary
with:
python-version: ${{ matrix.python-version }}
os: ${{ matrix.os }}
job-name: tests
- name: Add coverage report pytest options
if: matrix.coverage
run:
|
echo PYTEST_ADDOPTS="$PYTEST_ADDOPTS --cov --cov-report=xml" >> $GITHUB_ENV
- name: Test with pytest
run: |
pytest --pyargs watertap --idaes-flowsheets --entry-points-group watertap.flowsheets --file-durations
- name: Upload pytest duration reports as job artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: pytest-duration-reports-${{ matrix.os }}-py${{ matrix.python-version }}
path: pytest-duration-reports/*.csv
if-no-files-found: warn
- name: Upload coverage report as job artifact
if: matrix.coverage
uses: actions/upload-artifact@v7
with:
name: coverage-report-${{ matrix.os }}
path: coverage.xml
if-no-files-found: error
- name: Test documentation code
run: |
make -C docs doctest -d
# TODO: this should be moved to a dedicated job/workflow
# until then, we can leave this here as a reminder
- name: Test documentation links
if: 'false'
run: |
make -C docs linkcheck -d
upload-coverage:
name: Upload coverage report (Codecov)
needs: [tests-pr, tests-main]
if: always() && (needs.tests-pr.result == 'success' || needs.tests-main.result == 'success')
runs-on: ubuntu-latest
steps:
# the checkout step is needed to have access to codecov.yml
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/download-artifact@v8
with:
pattern: coverage-report-*
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v6
with:
fail_ci_if_error: true
verbose: true
# NOTE: secrets are not available for pull_request workflows
# However, as of 2024-02-10, Codecov is still allowing tokenless upload from PRs
# but does require token for other workflows e.g. merge to `main`
# see https://github.com/codecov/codecov-action/issues/1274#issuecomment-1934437359
token: ${{ secrets.CODECOV_TOKEN }}
user-mode-pytest-pr:
name: pytest (user mode) (py${{ matrix.python-version }}/${{ matrix.os }})
if: github.event_name == 'pull_request'
runs-on: ${{ matrix.os-version }}
needs: [code-formatting]
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
os:
- linux
- win64
exclude:
- os: win64
python-version: '3.10'
- os: win64
python-version: '3.11'
- os: win64
python-version: '3.13'
include:
- os: linux
os-version: ubuntu-22.04
- os: win64
os-version: windows-2022
steps:
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v4
with:
activate-environment: watertap
python-version: ${{ matrix.python-version }}
channels: conda-forge
conda-remove-defaults: 'true'
auto-activate: false
- name: Define install URL (default)
env:
_repo_full_name: watertap-org/watertap
_ref_to_install: main
run: |
echo "_install_url=https://github.com/${_repo_full_name}/archive/${_ref_to_install}.zip" >> $GITHUB_ENV
- name: Define install URL (for PRs)
if: github.event.pull_request
env:
_repo_full_name: ${{ github.event.pull_request.head.repo.full_name }}
_ref_to_install: ${{ github.event.pull_request.head.sha }}
run: |
echo "_install_url=https://github.com/${_repo_full_name}/archive/${_ref_to_install}.zip" >> $GITHUB_ENV
- name: Bootstrap packaging tools and verify installation
run: |
conda install --quiet --yes pip setuptools wheel
python -m pip show setuptools wheel
- name: Install watertap and testing dependencies
run: |
echo '::group::Output of "pip install" commands'
pip install "watertap @ ${_install_url}" pytest
echo '::endgroup::'
echo '::group::Display installed packages'
conda list
pip list
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Run pytest
run: |
pytest --pyargs watertap
user-mode-pytest-main:
name: pytest (user mode) (py${{ matrix.python-version }}/${{ matrix.os }})
if: github.event_name == 'push'
runs-on: ${{ matrix.os-version }}
needs: [code-formatting]
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
os:
- linux
- win64
include:
- os: linux
os-version: ubuntu-22.04
- os: win64
os-version: windows-2022
steps:
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v4
with:
activate-environment: watertap
python-version: ${{ matrix.python-version }}
channels: conda-forge
conda-remove-defaults: 'true'
auto-activate: false
- name: Define install URL (default)
env:
_repo_full_name: watertap-org/watertap
_ref_to_install: main
run: |
echo "_install_url=https://github.com/${_repo_full_name}/archive/${_ref_to_install}.zip" >> $GITHUB_ENV
- name: Define install URL (for PRs)
if: github.event.pull_request
env:
_repo_full_name: ${{ github.event.pull_request.head.repo.full_name }}
_ref_to_install: ${{ github.event.pull_request.head.sha }}
run: |
echo "_install_url=https://github.com/${_repo_full_name}/archive/${_ref_to_install}.zip" >> $GITHUB_ENV
- name: Bootstrap packaging tools and verify installation
run: |
conda install --quiet --yes pip setuptools wheel
python -m pip show setuptools wheel
- name: Install watertap and testing dependencies
run: |
echo '::group::Output of "pip install" commands'
pip install "watertap @ ${_install_url}" pytest
echo '::endgroup::'
echo '::group::Display installed packages'
conda list
pip list
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Run pytest
run: |
pytest --pyargs watertap
notebooks:
name: Test notebooks (py${{ matrix.python-version }}/${{ matrix.os }})
runs-on: ${{ matrix.os-version }}
needs: [code-formatting]
strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
os:
- linux
- win64
include:
- os: linux
os-version: ubuntu-22.04
- os: win64
os-version: windows-2022
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v4
with:
activate-environment: watertap-dev
python-version: ${{ matrix.python-version }}
channels: conda-forge
conda-remove-defaults: 'true'
- name: Install dependencies
run: |
echo '::group::Output of "conda install" commands'
conda install --quiet --yes pip setuptools wheel pandoc reaktoro
echo '::endgroup::'
echo '::group::Output of "pip install" commands'
pip install -e ".[dev]"
echo '::endgroup::'
echo '::group::Display installed packages'
conda list
pip list
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Install Jupyter kernel
run: |
jupyter kernelspec list
python -m ipykernel install --user --name "${{ env.WATERTAP_KERNEL_NAME }}"
jupyter kernelspec list
- name: Environment summary
uses: ./.github/actions/environment-summary
with:
python-version: ${{ matrix.python-version }}
os: ${{ matrix.os }}
job-name: notebooks
- name: Run pytest with nbmake
run: |
find tutorials -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" | grep -v "tutorials/flex_ro/mp_model.ipynb" | xargs pytest --nbmake --nbmake-kernel="${{ env.WATERTAP_KERNEL_NAME }}"