{"id":13495207,"url":"https://github.com/dodie/testing-in-bash","last_synced_at":"2026-01-16T07:02:08.743Z","repository":{"id":65254410,"uuid":"257505458","full_name":"dodie/testing-in-bash","owner":"dodie","description":"Bash test framework comparison","archived":false,"fork":false,"pushed_at":"2024-04-25T07:01:48.000Z","size":96,"stargazers_count":141,"open_issues_count":3,"forks_count":11,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-28T16:38:59.535Z","etag":null,"topics":["bash","bash-testing","bash-unit","bats","comparison","review","shellspec","shunit2","testing"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dodie.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-04-21T06:52:33.000Z","updated_at":"2025-02-19T01:21:32.000Z","dependencies_parsed_at":"2023-01-16T14:53:24.310Z","dependency_job_id":"37a0f946-5476-4ae4-95b5-3a1fbf172b10","html_url":"https://github.com/dodie/testing-in-bash","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dodie/testing-in-bash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dodie%2Ftesting-in-bash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dodie%2Ftesting-in-bash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dodie%2Ftesting-in-bash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dodie%2Ftesting-in-bash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dodie","download_url":"https://codeload.github.com/dodie/testing-in-bash/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dodie%2Ftesting-in-bash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bash","bash-testing","bash-unit","bats","comparison","review","shellspec","shunit2","testing"],"created_at":"2024-07-31T19:01:32.460Z","updated_at":"2026-01-16T07:02:08.730Z","avatar_url":"https://github.com/dodie.png","language":"Shell","readme":"# In search of the best test framework for Bash\n\nThere are [many testing frameworks for Bash](https://stackoverflow.com/questions/1339416/unit-testing-bash-scripts).\nHowever, many of them are not actively maintained, or are used only by a small group of people.\n\nIn this comparision I've included well-established and new testing frameworks that had at least recent release and have more than 50 Stars on GitHub:\n\n- [bashunit](https://github.com/TypedDevs/bashunit), a fast, simple and flexible testing library for your bash scripts \n- [Bats](https://github.com/bats-core/bats-core), a mature testing library with a bit of a custom syntax for more concise tests\n- [shUnit2](https://github.com/kward/shunit2), possibly the oldest Bash test framework around, supporting test files in pure Bash\n- [bash_unit](https://github.com/pgrange/bash_unit), a new and featureful test framework where test cases can be written in pure Bash\n- [ShellSpec](https://github.com/shellspec/shellspec), a BDD style testing framework with its own DSL\n- [shpec](https://github.com/rylnd/shpec), a BDD style testing framework similar to RSpec, Jasmine, and mocha\n\n\n## Test drive\n\nTo start fiddling with any of the test projects just run the `install.sh` to download and extract the particular\ntesting framework to a local directory, then execute `test.sh` to start the suite.\n\n- [bashunit example project and test drive](example-bashunit)  \n- [Bats example project and test drive](example-bats)  \n- [shUnit2 example project and test drive](example-shunit2)\n- [bash_unit example project and test drive](example-bash_unit)\n- [ShellSpec example project and test drive](example-shellspec)\n- [shpec example project and test drive](example-shpec)\n\n\n## Detailed comparision\n\n|                                                                                                                                          | [bashunit](https://github.com/TypedDevs/bashunit)                         | [Bats](https://github.com/bats-core/bats-core)                                                                                | [shUnit2](https://github.com/kward/shunit2)                               | [bash_unit](https://github.com/pgrange/bash_unit)                          | [ShellSpec](https://github.com/shellspec/shellspec)                 | [shpec](https://github.com/rylnd/shpec) |\n|------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|----------------------------------------------------------------------------|---------------------------------------------------------------------|-----------------------------------------|\n| Discover and run all tests\u003cbr/\u003ein the project                                                                                            | ✔️                                                                        | ✔️                                                                                                                             | ❌ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#test-discovery)                                                                              | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#test-discovery)                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#test-discovery)                        | ✔️                                                                  |\n| Run subset of tests or\u003cbr/\u003ea specific test                                                                                               | ✔️                                                                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bats#test-discovery)                                                                                 | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#test-discovery)                                                                              | ✔️                                                                        | ✔️                                                                         | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/rylnd/shpec/issues/31)      |\n| Parallel test execution                                                                                                                  | ✔️                                                                         | ✔️                                                                                                                             | ❌                                                                                                                             | ❌                                                                         | ✔️                                                                         | ❌                                                                   |\n| Skip or ignore tests                                                                                                                     | ✔️                                                                        | ✔️                                                                                                                             | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#skip-tests)                                                                                  | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#skip-tests)                           | ✔️                                                                         | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/rylnd/shpec/issues/57)      |\n| Rich assertion library                                                                                                                   | ✔️                                                                        | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bats#assertions)                                                                                      | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#assertions)                                                                                  | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#assertions)                            | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#assertions)                            | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#assertions)                         |\n| Extensible with custom assertions                                                                                                        | ✔️                                                                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bats#custom-assertions)                                                                              | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#custom-assertions)                                                                          | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#custom-assertions)                    | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#custom-assertions)                     | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#custom-assertions)                  |\n| Before / After                                                                                                                           | ✔️                                                                        | ✔️                                                                                                                             | ⚠ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/kward/shunit2/issues/112)                                                             | ✔️                                                                        | ✔️                                                                         | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/rylnd/shpec/issues/52)      |\n| BeforeAll / AfterAll                                                                                                                     | ✔️                                                                        | ❌ [\u003csup\u003eissue\u003c/sup\u003e](example-bats#test-discovery)                                                                              | ⚠ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/kward/shunit2/issues/112)                                                             | ✔️                                                                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#test-format)                           | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/rylnd/shpec/issues/52)      |\n| Parameterized tests\u003cbr/\u003eand test data                                                                                                    | ✔️                                                                        | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/sstephenson/bats/issues/136)                                                           | ❌                                                                                                                             | ❌                                                                         | ✔️                                                                         | ❌                                                                   |\n| Mocking \\*                                                                                                                               | ✔️                                                                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bats#mocking)                                                                                        | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#mocking)                                                                                     | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#mocking)                              | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#mocking)                               | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#mocking)                            |\n| Isolation between tests \\*\\*                                                                                                             | ✔️                                                                        | ✔️ [\u003csup\u003edoc\u003c/sup\u003e](https://github.com/bats-core/bats-core/wiki/Bats-Evaluation-Process)                                       | ❌                                                                                                                             | ✔️                                                                        | ✔️                                                                         |                                                                     |\n| Nice local report                                                                                                                        | ✔️                                                                        | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bats#report)                                                                                          | ✔️                                                                                                                            | ✔️                                                                        | ✔️                                                                         | ✔️                                                                  |\n| CI compatible report                                                                                                                     | ✔️                                                                          | ✔️ [\u003csup\u003eTAP\u003c/sup\u003e](http://testanything.org/)                                                                                  | ❌ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/kward/shunit2/issues/31)                                                              | ✔️ [\u003csup\u003eTAP\u003c/sup\u003e](http://testanything.org/)                             | ✔️ [\u003csup\u003eTAP\u003c/sup\u003e](http://testanything.org/)                              | ❌                                                                   |\n| Zero Dependency and\u003cbr/\u003eimplemented in Bash \\*\\*\\*                                                                                       | ✔️                                                                        | ✔️                                                                                                                             | ✔️                                                                                                                            | ✔️                                                                        | ✔️                                                                         | ✔️                                                                  |\n| Easy to install \\*\\*\\*\\*                                                                                                                 | ✔️                                                                        | ✔️                                                                                                                             | ✔️                                                                                                                            | ✔️                                                                        | ✔️                                                                         | ✔️                                                                  |\n| Tests written in Bash                                                                                                                    | ✔️                                                                        | ⚠ [\u003csup\u003ealmost\u003c/sup\u003e](example-bats#test-format)                                                                                | ✔️                                                                                                                            | ✔️                                                                        | ❌ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#test-format)                            | ❌ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#test-format)                         |\n| Compatible with the \u003cbr/\u003eUnofficial Bash Strict Mode \\*\\*\\*\\*\\*     | ✔️                                                                         | ✔️| ⚠ [\u003csup\u003e?\u003c/sup\u003e](https://github.com/dodie/testing-in-bash/tree/master/example-bats#unit-testing-scripts-that-set-bash-options) | ✔️                                                                                                                            | ⚠ [\u003csup\u003eissue\u003c/sup\u003e](https://github.com/pgrange/bash_unit/issues/61)      | ✔️                                                                         |                                                                     |\n| Maintained                                                                                                                               | ✔️                                                                        | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bats#activity)                                                                                        | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#activity)                                                                                    | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#activity)                             | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#activity)                              | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#activity)                            |\n| Mature                                                       | ❌ [\u003csup\u003esince 2023\u003c/sup\u003e](https://github.com/TypedDevs/bashunit/releases) | ✔️ [\u003csup\u003esince 2011\u003c/sup\u003e](https://github.com/bats-core/bats-core/releases)                                                    | ✔️ [\u003csup\u003esince 2007\u003c/sup\u003e](https://github.com/kward/shunit2/commits/master?after=0f0a77b6b257f24d2b3ef1b28096fdd154a19f22+10) | ✔️ [\u003csup\u003esince 2016\u003c/sup\u003e](https://github.com/pgrange/bash_unit/releases) | ❌ [\u003csup\u003esince 2019\u003c/sup\u003e](https://github.com/shellspec/shellspec/releases) | ✔️ [\u003csup\u003esince 2013\u003c/sup\u003e](https://github.com/rylnd/shpec/releases) |\n| Good documentation                             | ✔️ [\u003csup\u003e?\u003c/sup\u003e](https://bashunit.typeddevs.com)                         | ⚠ [\u003csup\u003e?\u003c/sup\u003e](example-bats#documentation)                                                                                   | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shunit2#documentation)                                                                              | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-bash_unit#documentation)                        | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shellspec#documentation)                         | ✔️ [\u003csup\u003e?\u003c/sup\u003e](example-shpec#documentation)                      |\n\n\\* **Mocking**:\u003cbr/\u003e\nThe testing framework is compatible with the [common mocking techniques](https://github.com/dodie/testing-in-bash/tree/master/mocking).\n\n\\*\\* **Isolation between tests**:\u003cbr/\u003e\nAliases, custom function definitions, Bash options and variables are not leaking from one test\nto another.\n\n\\*\\*\\* **Zero Dependency and implemented in Bash**:\u003cbr/\u003e\nApart from a few common tools like `coreutils` and `grep`, you don't need anything to use the framework.\u003cbr/\u003e\nThe source code of the framework is itself implemented as Bash scripts. If you are comfortable with Bash, you can read and even modify it.\n\n\\*\\*\\*\\* **Easy to install**:\u003cbr/\u003e\nMany of the frameworks support more than one alternatives on how to set it up quickly. It's possible\nto install it with your favourite package manager and some of them even have an official Docker image.\nPersonally, I try to avoid installing project dependencies globally as much as I can,\nso I just decided to grab a tar.gz file with the latest release from GitHub.\n\n\\*\\*\\*\\*\\* **Compatible with the Unofficial Bash Strict Mode**:\u003cbr/\u003e\nSourcing a script file that use the [Unofficial Bash Strict Mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/) should\nnot break the test framework. Of course, custom assertions and the test code\n[should also work with strict mode](https://github.com/dodie/testing-in-bash/tree/master/strictmode) but that's up for the user.\nAlso, the test framework shouldn't set Bash options as well to ensure that executing sourced functions work similarly to when they are not sourced.\n\n\n## Related posts, other comparisions\n\n- https://medium.com/wemake-services/testing-bash-applications-85512e7fe2de\n- https://stackoverflow.com/questions/1339416/unit-testing-bash-scripts\n- https://www.leadingagile.com/2018/10/unit-testing-shell-scriptspart-one/\n\n\n## Contribution guide\n\nIf you know a testing framework that should be mentioned here or find that there's room for improvement feel free to\nopen an issue or Pull Request. (See [CONTRIBUTING.md](https://github.com/dodie/testing-in-bash/blob/master/CONTRIBUTING.md).)\n","funding_links":[],"categories":["Shell"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdodie%2Ftesting-in-bash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdodie%2Ftesting-in-bash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdodie%2Ftesting-in-bash/lists"}