{"id":30040091,"url":"https://github.com/bccp/runtests","last_synced_at":"2025-08-07T01:56:34.296Z","repository":{"id":57443468,"uuid":"64977808","full_name":"bccp/runtests","owner":"bccp","description":"Running pytest tests with incremental builds and optional MPI support","archived":false,"fork":false,"pushed_at":"2020-06-23T01:19:25.000Z","size":143,"stargazers_count":3,"open_issues_count":4,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-25T14:45:43.453Z","etag":null,"topics":["mpi","pytest","python","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bccp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-05T01:11:17.000Z","updated_at":"2020-06-23T01:19:29.000Z","dependencies_parsed_at":"2022-09-14T16:40:12.517Z","dependency_job_id":null,"html_url":"https://github.com/bccp/runtests","commit_stats":null,"previous_names":["rainwoodman/runtests","rainwoodman/mpi4py_test"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/bccp/runtests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bccp%2Fruntests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bccp%2Fruntests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bccp%2Fruntests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bccp%2Fruntests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bccp","download_url":"https://codeload.github.com/bccp/runtests/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bccp%2Fruntests/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269185774,"owners_count":24374634,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-06T02:00:09.910Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mpi","pytest","python","unit-testing"],"created_at":"2025-08-07T01:56:26.772Z","updated_at":"2025-08-07T01:56:34.283Z","avatar_url":"https://github.com/bccp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# runtests\n\n[![Build Status](https://travis-ci.org/bccp/runtests.svg?branch=master)](https://travis-ci.org/bccp/runtests)\n\nA simple tools for incrementally building packages, then testing against installed version.\n\nThe idea came from runtests.py in numpy and scipy projects:\n\n- incremental build is fast: encouraging developers to test frequently;\n- existing installation of the software package is not overwritten;\n- binaries are properly compiled -- and optionally in debug mode.\n\nTesting of MPI application is also supported via the `[mpi]` feature.\nWe use runtests in `nbodykit` and a variety of packages.\n\n## Project setup\n\nFollow traditional pytest setup. Then vendor run-tests.py or run-mpitests.py into the project root directory.\n\n1. For MPI Projects, copy `run-testsmpi.py` to `run-tests.py`.\n\n2. For nonMPI Projects, copy `run-tests.py` to `run-tests.py`.\n\n3. Edit the file, change the package module name.\n\n\n## Usage\n\n### Regular Projects vendored from `run-tests.py`\n\n*All pytest arguments are passed through.* For example, '-v', '-x' `--pdb`.\n\n1. Running tests the usual way\n    ```\n        python run-tests.py\n    ```\n\n2. Running a specific test `test_core.py::test_basic_function`\n    ```\n        python run-tests.py test_core.py::test_basic_function\n    ```\n\n### MPI Projects, vendored from `run-mpitests.py`\n\n*All pytest arguments are passed through.*\n\nMPI Tests always stop at the first error; because MPI is not fault tolerant [1].\n\n[1] : https://www.open-mpi.org/faq/?category=ft#ft-future\n\n1. Running tests with 4 MPI ranks\n    ```\n        python run-tests.py\n    ```\n\n2. Running tests with 1 MPI rank\n    ```\n        python run-tests.py --single\n    ```\n\n3. Running tests with a customized MPI launcher\n    ```\n        python run-tests.py --mpirun=\"mpirun -np 4\"\n    ```\n\n## Defining MPI UnitTests: \n\nThis feature may belong to a different package; it resides here for now before we can\nfind a reasonable refactoring of the package.\n\n### MPITest decorator\n\n`MPITest` decorator allows testing with different MPI communicator sizes.\n\nExample:\n```\n    from runtests.mpi import MPITest\n\n    @MPITest(size=[1, 2, 3, 4])\n    def test_myfunction(comm):\n        result = myfunction(comm)\n        assert result # or ....\n```\n\n### MPITestFixture\n\nYou can combine `MPITestFixture` with other pytest fixtures or decorators, what you can't with the `MPITest` decorator.\n\nExample: Parameter variation with `pytest.mark.parametrize`\n\n```python\nfrom runtests.mpi import MPITestFixture\nimport pytest\n\ncomm = MPITestFixture([1,2,3, 4,10], scope='function')\n\n@pytest.mark.parametrize(\"msg\",[\"hello\",\"world\"])\ndef test_y(msg, comm):\n    print(msg, comm.Get_rank())\n```\n\nExample: Parameter variation with `pytest.fixture`\n```python\nfrom runtests.mpi import MPITestFixture\nimport pytest\n\ncomm = MPITestFixture([1,2,3,4], scope='function')\n\n@pytest.fixture(params=[\"hello\",\"world\"])\ndef x(request):\n    return request.param\n\ndef test_x(x, comm):\n    print(x, comm.Get_rank())\n```\n\n\n## Tricks\n\n\n1. Launching pdb on the first error\n\n    ```\n        # non MPI\n        python run-tests.py --pdb\n\n\n        # MPI on a single rank\n        python run-mpitests.py --single --pdb\n\n        # MPI but one debugger per rank.\n        python run-mpitests.py --mpirun='mpirun -n 4 xterm -e' --pdb\n\n        # shortcut for MPI but one debugger per rank\n        python run-mpitests.py --xterm --pdb\n    ```\n\n2. Launchging a shell with the module ready to be imported. The shell will start in\n   an empty directory where runtests would have ran the tests.\n\n    ```\n        python run-tests.py --shell\n    ```\n\n3. Testing runtests itself requires an installed version of runtests.\n   This is because the example scripts we use for testing runtests,\n   refuses to import from the source code directory.\n\n4. setup.py works (or fails) like 'make'. Therefore sometimes it is useful to purge the\n   build/ directory manually by adding '--clean-build' argument.\n\n5. Install pytest-profiling and get support to profiling.\n\n6. Adding commandline arguments via conftest.py is not supported. (Issue #14)\n   If this is a global behavior of the tester, then consider subclassing `Tester` in run-tests.py instead. \n\n## Contribute\n\nTesting runtests itself requires an installed version of runtests.\nThis is because runtests refuses to import from the source code directory.\n\nAlso be aware that some of the tests are supposed to fail.\n\nFollow the example in `travis.yaml` for running the tests locally. In the long\nrun we may want to refactor it into a shell script.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbccp%2Fruntests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbccp%2Fruntests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbccp%2Fruntests/lists"}