{"id":20553763,"url":"https://github.com/rylnd/shpec","last_synced_at":"2025-04-05T21:11:27.364Z","repository":{"id":6614050,"uuid":"7857510","full_name":"rylnd/shpec","owner":"rylnd","description":"Test your shell scripts!","archived":false,"fork":false,"pushed_at":"2022-12-19T19:30:07.000Z","size":168,"stargazers_count":381,"open_issues_count":20,"forks_count":25,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-03-29T20:09:57.746Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rylnd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-27T20:21:52.000Z","updated_at":"2025-03-20T11:35:01.000Z","dependencies_parsed_at":"2023-01-11T17:02:08.794Z","dependency_job_id":null,"html_url":"https://github.com/rylnd/shpec","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rylnd%2Fshpec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rylnd%2Fshpec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rylnd%2Fshpec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rylnd%2Fshpec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rylnd","download_url":"https://codeload.github.com/rylnd/shpec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399887,"owners_count":20932880,"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","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":[],"created_at":"2024-11-16T02:44:54.186Z","updated_at":"2025-04-05T21:11:27.298Z","avatar_url":"https://github.com/rylnd.png","language":"Shell","readme":"shpec [![Build Status](https://travis-ci.org/rylnd/shpec.svg?branch=master)](https://travis-ci.org/rylnd/shpec) [![Gitter](https://badges.gitter.im/rylnd/shpec.svg)](https://gitter.im/rylnd/shpec?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n----\n\n*Test your shell scripts!*\n\n\u003cp align='center'\u003e\n  \u003cimg src='https://raw.githubusercontent.com/wiki/rylnd/shpec/images/screenshot.png'\n       alt=\"Screenshot of shpec\" /\u003e\n\u003c/p\u003e\n\n## Using shpec\nThis repo itself is using `shpec`, so feel free to use it as an example.\nHere is the basic structure that you'll want:\n\n    └── shpec\n        └── an_example_shpec.sh\n        └── another_shpec.sh\n\nThen to run your tests:\n\n```bash\nshpec [shpec_files]\n```\n\nIf you'd like your tests to run automatically when they change, we recommend the [entr](\nhttp://entrproject.org/) utility:\n\n```bash\nfind . -name \"*_shpec.sh\" | entr shpec\n```\n\nNote that there are some shell specificities, you'll find more about them in the [Compatibility file](./COMPATIBILITY.md).\n\n### Structuring your Tests\n`shpec` is similar to other *BDD* frameworks like\n[`RSpec`](\nhttps://github.com/rspec/rspec), [`Jasmine`](\nhttps://github.com/jasmine/jasmine), and [`mocha`](\nhttps://github.com/mochajs/mocha).\n\nThe two main constructs are `describe/end` (used to group tests) and `it/end`\n(used to describe an individual test and wrap assertions).\n\n__Note:__ Since your test files will be sourced into `shpec`, you can use any\nshell command that would normally be available in your session.\n\n### Examples\n[shpec's own tests](\nhttps://github.com/rylnd/shpec/tree/master/shpec/shpec_shpec.sh)\nare a great place to start. For more examples, see the [wiki page](\nhttps://github.com/rylnd/shpec/wiki/Examples)\n\n### Matchers\nThe general format of an assertion is:\n\n    assert matcher arguments\n\nwhere `matcher` is one of the following:\n\n#### Binary Matchers\n```bash\nequal         # equality\nunequal       # inequality\ngt            # algebraic '\u003e'\nlt            # algebraic '\u003c'\nglob          # glob match\nno_glob       # lack of glob match\ngrep          # regex match (grep style)\nno_grep       # lack of regex match (grep style)\negrep         # regex match (egrep style)\nno_egrep      # lack of regex match (egrep style)\n```\n\n#### Unary Matchers\n```bash\npresent       # string presence\nblank         # string absence\nfile_present  # file presence\nfile_absent   # file absence\nsymlink       # tests a symlink's target\ntest          # evaluates a test string\n```\n\n#### Custom Matchers\nCustom matchers are loaded from `shpec/matchers/*.sh`.\n\nFor example, here's how you'd create a `still_alive` matcher:\n\n```bash\n# in shpec/matchers/network.sh\nstill_alive() {\n  ping -oc1 \"$1\" \u003e /dev/null 2\u003e\u00261\n  assert equal \"$?\" 0\n}\n```\n\nThen you can use that matcher like any other:\n\n```bash\n# in shpec/network_shpec.sh\ndescribe \"my server\"\n  it \"serves responses\"\n    assert still_alive \"my-site.com\"\n  end\nend\n```\n\n### Stubbing\nYou can stub commands using `stub_command`.\nThis function takes the name of the command you wish to stub. If provided,\nthe second argument will be used as the body of the command. (code that would be evaluated)\nOnce you're done, you can delete it with `unstub_command`.\n\nThe best example is the [shpec test for this feature](\nhttps://github.com/rylnd/shpec/blob/master/shpec/shpec_shpec.sh#L121-L139).\n\u003c!-- beware: keep in sync of line when modifying the shpec --\u003e\n\n## Installation\nyou can either install with curl\n```bash\nsh -c \"`curl -L https://raw.githubusercontent.com/rylnd/shpec/master/install.sh`\"\n```\n\nor with [antigen](https://github.com/zsh-users/antigen) for zsh by\nputting `antigen bundle rylnd/shpec` in your `.zshrc`\n\n## Contributing\nPull requests are always welcome.\n\nIf you've got a test or custom matcher you're particularly proud of,\nplease consider adding it to [the Examples page](\nhttps://github.com/rylnd/shpec/wiki/Examples)!\n\n### Style and code conventions\n\n#### Language: POSIX shell\nThe core `shpec` script and function should work the same in\nany POSIX compliant shell.  You can use `shpec` to test scripts\nthat use non-POSIX features, but you must avoid them when extending\n`shpec` or the main `shpec_shpech.sh` tests.\n\n#### Namespace\nAny variables starting with `_shpec_` are reserved for internal use and\nshould not be used in test cases (except perhaps for test cases of `shpec`\nitself).\n","funding_links":[],"categories":["Shell Script Development"],"sub_categories":["Directory Navigation"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frylnd%2Fshpec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frylnd%2Fshpec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frylnd%2Fshpec/lists"}