Skip to content

Commit

Permalink
Add pytests, and remove explicit workflow testing (#430)
Browse files Browse the repository at this point in the history
* Add pytests, and remove explicit workflow testing

* Don't test something we can't test in CI.

* Add dependency.

* Update tests/test_package_creation.py

Remove extra spaces.

---------

Co-authored-by: Drew Oldag <[email protected]>
  • Loading branch information
delucchi-cmu and drewoldag authored Feb 16, 2024
1 parent b22e735 commit d395883
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 107 deletions.
115 changes: 10 additions & 105 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,121 +5,26 @@ on:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: 45 6 * * *
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
tests:
name: ${{ matrix.copier_config.name }} - Python ${{ matrix.python-version }}
build:

runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
python-version: ['3.9', '3.10', '3.11']
copier_config:
- name: Base example
package_name: example_package # The default package_name
extra_flags: ''
foldername: base_example
- name: No example module
package_name: 'drewtonian' # Same module name provided in `extra_flags` on the next line.
extra_flags: >-
--data project_name=new_science
--data package_name=drewtonian
--data author_name=Drew
--data [email protected]
--data project_license=BSD
--data mypy_type_checking=basic
--data create_example_module=no
--data include_notebooks=no
foldername: 'black_w_o_example_module'
- name: Example module
package_name: 'drewtonian' # Same module name provided in `extra_flags` on the next line.
extra_flags: >-
--data project_name=new_science
--data package_name=drewtonian
--data author_name=Drew
--data [email protected]
--data project_license=BSD
--data mypy_type_checking=basic
--data create_example_module=yes
--data include_notebooks=no
foldername: 'black_w_example_module'
- name: No sphinx docs
package_name: 'drewtonian'
extra_flags: >-
--data project_name=new_science
--data package_name=drewtonian
--data include_docs=no
--data include_notebooks=no
foldername: 'no_sphinx_docs'
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:

- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
- uses: actions/checkout@main
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}

- name: Install Python dependencies
- name: Install dependencies
run: |
sudo apt-get update
python -m pip install --upgrade pip
python -m pip install copier mypy
- name: Generate package
run: |
copier copy --vcs-ref HEAD --defaults ${{ matrix.copier_config.extra_flags }} ./ ../test/${{ matrix.copier_config.foldername }}
cd ../test/${{ matrix.copier_config.foldername }}
cat .copier-answers.yml
- name: Build package
run: |
cd ../test/${{ matrix.copier_config.foldername }}
git config --global user.email "[email protected]"
git config --global user.name "Test Name"
git init --initial-branch=main
git add src
git commit -m initial
pip install .[dev]
- name: black checks
uses: psf/black@stable
with:
src: "../test/${{ matrix.copier_config.foldername }}/src"

- name: mypy checks basic
if: ${{ contains(matrix.copier_config.extra_flags, 'mypy_type_checking=basic') && !contains(matrix.copier_config.extra_flags, 'create_example_module=no') }}
run: |
cd "../test/${{ matrix.copier_config.foldername }}"
mypy src tests
- name: mypy checks strict
if: ${{ contains(matrix.copier_config.extra_flags, 'mypy_type_checking=strict') && !contains(matrix.copier_config.extra_flags, 'create_example_module=no') }}
run: |
cd "../test/${{ matrix.copier_config.foldername }}"
mypy --strict src tests
- name: Install notebook requirements
if: ${{ !contains(matrix.copier_config.extra_flags, 'include_notebooks=no') }}
run: |
sudo apt-get install pandoc
pip install -r ../test/${{ matrix.copier_config.foldername }}/docs/requirements.txt
cat ../test/${{ matrix.copier_config.foldername }}/docs/requirements.txt
- name: Build docs
if: ${{ !contains(matrix.copier_config.extra_flags, 'include_docs=no') }}
run: |
cd ../test/${{ matrix.copier_config.foldername }}
sphinx-build -T -E -b html -d docs/build/doctrees ./docs docs/build/html
- name: Tests
if: ${{ !contains(matrix.copier_config.extra_flags, 'create_example_module=no') }}
pip install -e .[dev]
- name: Run unit tests with pytest / pytest-copie
run: |
cd ../test/${{ matrix.copier_config.foldername }}
python -m pytest --cov=${{ matrix.copier_config.package_name }} --cov-report=xml
python -m pytest
41 changes: 41 additions & 0 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This workflow will run daily at 06:45.
# It will install Python dependencies and run tests with a variety of Python versions.
# See documentation for help debugging smoke test issues:
# https://lincc-ppt.readthedocs.io/en/latest/practices/ci_testing.html#version-culprit

name: Unit test smoke test

on:

# Runs this workflow automatically
schedule:
- cron: 45 6 * * *

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@main
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@main
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update
python -m pip install --upgrade pip
pip install -e .[dev]
- name: List dependencies
run: |
pip list
- name: Run unit tests with pytest / pytest-copie
run: |
python -m pytest
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dev = [
"black", # Used to format code
"pre-commit", # Used to run checks prior to committing code
"pytest", # Used to run tests
"pylint", # test pylint in unit tests
"pytest-copie", # Used to create hydrated copier projects for testing
"tox", # Used to run tests in multiple environments
]
Expand Down
81 changes: 79 additions & 2 deletions tests/test_package_creation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest
import subprocess

import pytest


def successfully_created_project(result):
"""Basic assertions that indicate the copier was able to create a project"""
Expand Down Expand Up @@ -55,6 +57,22 @@ def unit_tests_in_project_run_successfully(result, package_name="example_package
return pytest_results.returncode == 0


def docs_build_successfully(result):
"""Test that we can build the doc tree.
!!! NOTE - This doesn't currently work because we need to `pip install` the hydrated
project before running the tests. And we don't have a way to create a temporary
virtual environment for the project.
"""

sphinx_results = subprocess.run(
["make", "html"],
cwd=(result.project_dir / "docs"),
)

return sphinx_results.returncode == 0


def github_workflows_are_valid(result):
"""Test to ensure that the GitHub workflows are valid"""
workflows_results = subprocess.run(
Expand Down Expand Up @@ -160,13 +178,22 @@ def test_code_style_combinations(copie, enforce_style):
assert black_runs_successfully(result)


def test_smoke_test_notification(copie):
@pytest.mark.parametrize(
"notification",
[
[],
["slack"],
["email"],
["email", "slack"],
],
)
def test_smoke_test_notification(copie, notification):
"""Confirm we can generate a "smoke_test.yaml" file, with all
notification mechanisms selected."""

# provide a dictionary of the non-default answers to use
extra_answers = {
"failure_notification": ["email", "slack"],
"failure_notification": notification,
}

# run copier to hydrate a temporary project
Expand All @@ -177,6 +204,56 @@ def test_smoke_test_notification(copie):
assert black_runs_successfully(result)


@pytest.mark.parametrize(
"doc_answers",
[
{
"include_docs": True,
"include_notebooks": True,
},
{
"include_docs": True,
"include_notebooks": False,
},
],
)
def test_doc_combinations(copie, doc_answers):
"""Confirm the docs directory is well-formed, when including docs."""

# run copier to hydrate a temporary project
result = copie.copy(extra_answers=doc_answers)

assert successfully_created_project(result)
assert directory_structure_is_correct(result)
assert black_runs_successfully(result)
assert (result.project_dir / "docs").is_dir()


@pytest.mark.parametrize(
"doc_answers",
[
{
"include_docs": False,
"include_notebooks": False,
},
{
"include_docs": False,
"include_notebooks": True,
},
],
)
def test_doc_combinations_no_docs(copie, doc_answers):
"""Confirm there is no 'docs' directory, if not including docs."""

# run copier to hydrate a temporary project
result = copie.copy(extra_answers=doc_answers)

assert successfully_created_project(result)
assert directory_structure_is_correct(result)
assert black_runs_successfully(result)
assert not (result.project_dir / "docs").is_dir()


def test_github_workflows_schema(copie):
"""Confirm the current GitHub workflows have valid schemas."""
extra_answers = {
Expand Down

0 comments on commit d395883

Please sign in to comment.