diff --git a/README.md b/README.md index d3128241..64023b21 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ for a Python package. - Allows package slug (use `_` instead of `-`) - Licenses supported: MIT, BSD 3 Clause, ISC License, Apache Software License 2.0, and GPL 3 - Documentation engines: mkdocs, sphinx, jupyter-boook - - Test library: pytest + - Test library: pytest, hypothesis - Auto format code tool: blue and black - Initial integration with git - Support to conda (as base environment) and poetry as packaging and dependency management diff --git a/docs/guide.md b/docs/guide.md index 5208cb1c..d34858f2 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -29,3 +29,11 @@ most popular system compilers to suit your needs and preferences for developing Python packages. If you think we should add more options, you can submit your suggestion as a issue at https://github.com/osl-incubator/scicookie/issues/new/choose. + +## Test Library + +There are several test library options available to development of Python packages. SciCookie support the following: + +- [**Pytest**](https://docs.pytest.org/en/): is a popular testing framework for Python. It simplifies the process of writing and running tests by providing a concise syntax and powerful features. With Pytest, you can automatically discover and collect test cases, use fixtures for test setup and resource management, and write test functions with assert statements to check expected outcomes. It offers various options for test execution, including running specific tests, parallel execution, and generating test reports. Pytest also has a thriving ecosystem of plugins that extend its capabilities, such as code coverage analysis and test parameterization. Overall, Pytest is widely adopted for its simplicity, flexibility, and community support, making it an effective tool for ensuring the quality and reliability of Python code. You can check documentation [here](https://docs.pytest.org/en/) + +- [**Hypothesis**](https://hypothesis.readthedocs.io/): is a property-based testing library for Python. It focuses on generating diverse input data and exploring different scenarios to thoroughly test code. Instead of relying on specific examples, Hypothesis allows you to define general properties that your code should satisfy. It automatically generates random inputs, including edge cases, to uncover potential bugs and unexpected behaviors. Hypothesis integrates well with popular testing frameworks like Pytest and promotes comprehensive testing to improve code reliability. You can check documentation [here](https://hypothesis.readthedocs.io/) diff --git a/src/scicookie/cookiecutter.json b/src/scicookie/cookiecutter.json index 67ecda5c..748039a4 100644 --- a/src/scicookie/cookiecutter.json +++ b/src/scicookie/cookiecutter.json @@ -58,6 +58,7 @@ "use_pre_commit": "yes", "use_pydocstyle": "yes", "use_pytest": "yes", + "use_hypothesis": "yes", "use_shellcheck": "yes", "use_vulture": "yes", "use_containers": [ diff --git a/src/scicookie/profiles/base.yaml b/src/scicookie/profiles/base.yaml index 048bfe21..75ea35ea 100644 --- a/src/scicookie/profiles/base.yaml +++ b/src/scicookie/profiles/base.yaml @@ -122,6 +122,7 @@ use_tools: - pre-commit - pydocstyle - pytest + - hypothesis - shellcheck - vulture enabled: false diff --git a/src/scicookie/{{cookiecutter.project_slug}}/Makefile b/src/scicookie/{{cookiecutter.project_slug}}/Makefile index 7c5dcc7c..9278a788 100644 --- a/src/scicookie/{{cookiecutter.project_slug}}/Makefile +++ b/src/scicookie/{{cookiecutter.project_slug}}/Makefile @@ -60,11 +60,15 @@ clean: ## remove build artifacts, compiled files, and cache lint: pre-commit run --all-files -{% if cookiecutter.use_pytest %} -.PHONY:test +.PHONY: test test: ## run tests quickly with the default Python + {%- if cookiecutter.use_pytest == "yes" %} pytest -{% endif %} + {%- elif cookiecutter.use_hypothesis == "yes" %} + python -m unittest discover + {%- else %} + @echo "No test library selected." + {%- endif %} {% if cookiecutter.documentation_engine == 'mkdocs' -%} .PHONY:docs-build diff --git a/src/scicookie/{{cookiecutter.project_slug}}/build-system/poetry-pyproject.toml b/src/scicookie/{{cookiecutter.project_slug}}/build-system/poetry-pyproject.toml index ce675a96..8cdb9392 100644 --- a/src/scicookie/{{cookiecutter.project_slug}}/build-system/poetry-pyproject.toml +++ b/src/scicookie/{{cookiecutter.project_slug}}/build-system/poetry-pyproject.toml @@ -21,6 +21,9 @@ pytest = "^7.3.2" pytest-cov = "^4.1.0" {% endif %} {%- endif -%}{#- end of use_pytest -#} +{%- if cookiecutter.use_hypothesis == "yes" -%} +hypothesis = "^6.0" +{% endif %} {%- if cookiecutter.use_coverage == "yes" -%} coverage = "^7.2.7" {% endif %} diff --git a/src/scicookie/{{cookiecutter.project_slug}}/docs/contributing.md b/src/scicookie/{{cookiecutter.project_slug}}/docs/contributing.md index 2d8ae6d2..dbc0c828 100644 --- a/src/scicookie/{{cookiecutter.project_slug}}/docs/contributing.md +++ b/src/scicookie/{{cookiecutter.project_slug}}/docs/contributing.md @@ -131,10 +131,16 @@ Before you submit a pull request, check that it meets these guidelines: ## Tips To run a subset of tests:: - +{% if cookiecutter.use_pytest == "yes" -%} ``` $ pytest tests.test_{{ cookiecutter.package_slug }} ``` +{%- endif %} +{% if cookiecutter.use_hypothesis == "yes" -%} +``` +python -m unittest discover +``` +{%- endif %} ## Release diff --git a/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.package_slug}}.py b/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.package_slug}}.py new file mode 100644 index 00000000..ea6d3dcb --- /dev/null +++ b/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.package_slug}}.py @@ -0,0 +1,52 @@ +""" +Tests for {{ cookiecutter.package_slug }} package. +""" +{% if cookiecutter.use_pytest == "yes" -%} +import pytest +{% endif -%} +{% if cookiecutter.use_hypothesis == "yes" -%} +from hypothesis import given +from hypothesis import strategies as st +{% endif -%} +{% if cookiecutter.use_pytest == "yes" %} + +@pytest.fixture +def response_pytest(): + """Sample pytest fixture. + + See more at: + http://doc.pytest.org/en/latest/fixture.html + """ +{% endif -%} +{% if cookiecutter.use_hypothesis == "yes" %} + +@pytest.fixture +def response_hypothesis(): + """Sample pytest fixture. + + See more at: + https://hypothesis.readthedocs.io/en/latest/quickstart.html + """ +{% endif -%} + +{%- if cookiecutter.use_pytest == "yes" and +cookiecutter.use_hypothesis == "yes" %} + +@given(st.text()) +def test_content_hypothesis1(): + """Sample pytest test function with the + pytest fixture and hypothesis as arguments. + """ + # Test code using the response fixture and + # hypothesis_argument + + +@given(st.text()) +def test_content_hypothesis2(): + """Sample pytest test function with the hypothesis + fixture as an argument. + """ + # Test code using the response fixture and + # hypothesis_argument +{% endif -%} +{#- keep this line at the end of the file -#} diff --git a/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.project_slug}}.py b/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.project_slug}}.py deleted file mode 100644 index 4c2dd0e4..00000000 --- a/src/scicookie/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.project_slug}}.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Tests for `{{ cookiecutter.project_slug }}` package.""" - -import pytest - - -@pytest.fixture -def response(): - """Sample pytest fixture. - - See more at: http://doc.pytest.org/en/latest/fixture.html - """ - - -def test_content(response): - """Sample pytest test function with the pytest fixture as an argument."""