{"id":13879799,"url":"https://github.com/paraspec/paraspec","last_synced_at":"2025-04-09T17:26:05.648Z","repository":{"id":32815761,"uuid":"141737191","full_name":"paraspec/paraspec","owner":"paraspec","description":"Parallel RSpec test runner","archived":false,"fork":false,"pushed_at":"2023-11-02T21:34:40.000Z","size":123,"stargazers_count":83,"open_issues_count":14,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-02T11:39:52.900Z","etag":null,"topics":["parallel","rspec"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/paraspec.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-20T16:58:00.000Z","updated_at":"2024-04-25T05:05:08.000Z","dependencies_parsed_at":"2024-09-25T00:34:31.440Z","dependency_job_id":null,"html_url":"https://github.com/paraspec/paraspec","commit_stats":{"total_commits":153,"total_committers":4,"mean_commits":38.25,"dds":0.02614379084967322,"last_synced_commit":"1ccc2e9192c3e0c81855264318955b17ab4940e5"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paraspec%2Fparaspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paraspec%2Fparaspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paraspec%2Fparaspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paraspec%2Fparaspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paraspec","download_url":"https://codeload.github.com/paraspec/paraspec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248076110,"owners_count":21043713,"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":["parallel","rspec"],"created_at":"2024-08-06T08:02:33.810Z","updated_at":"2025-04-09T17:26:05.626Z","avatar_url":"https://github.com/paraspec.png","language":"Ruby","readme":"# Paraspec\n\nParaspec is a parallel RSpec test runner.\n\nIt is built with a producer/consumer architecture. A master process loads\nthe entire test suite and sets up a queue to feed the tests to the workers.\nEach worker requests a test from the master, runs it, reports the results\nback to the master and requests the next test until there are no more left.\n\nThis producer/consumer architecture enables a number of features:\n\n1. The worker load is naturally balanced. If a worker happens to come across\na slow test, the other workers keep chugging away at the remaining tests.\n2. Tests defined in a single file can be executed by multiple workers,\nsince paraspec operates on a test by test basis and not on a file by file basis.\n3. Standard output and error streams can be[*] captured and grouped on a\ntest by test basis, avoiding interleaving output of different tests together.\nThis output capture can be performed for output generated by C extensions\nas well as plain Ruby code.\n4. Test results are seamlessly integrated by the master, such that\na parallel run produces a single progress bar with\n[Fuubar](https://github.com/thekompanee/fuubar) across all workers.\n5. Test grouping: paraspec can[**] group the tests by file, top level example\ngroup, bottom level example group and individually by examples.\nLarger groupings reduce overhead but limit concurrency.\nSmaller groupings have more overhead but higher concurrency.\n6. Paraspec is naturally resilient to worker failure. If a worker dies\nfor any reason the remaining tests get automatically redistributed among\nthe remaining workers. It is also possible, in theory, to provision\nadditional workers when a test run is already in progress, though this feature\nis not currently on the roadmap.\n\n[*] This feature is not yet implemented.\n\n[**] Currently only grouping by bottom level example group is implemented.\n\n## Performance\n\nHow much of a difference does paraspec make? The answer, as one might\nexpect, varies greatly with the test suite being run as well as available\nhardware. Here are some examples:\n\n| Example | Hardware | Sequential | Paraspec (c=2) | Paraspec (c=4) |\n|---------|------------|----------------|----------------|----------|\n| [MongoDB Ruby Driver](https://docs.mongodb.com/ruby-driver/current/) test suite | Travis CI | 16 minutes | 13 minutes | 10-11 minutes |\n| [MongoDB Ruby Driver](https://docs.mongodb.com/ruby-driver/current/) test suite | 14-core workstation | 15 minutes | | 4 minutes |\n\n[Exampe Travis build](https://travis-ci.org/p-mongo/mongo-ruby-driver-paraspec/builds/411986888)\n\nEven on Travis, which is likely limited to a single core, using 4x concurrency\nreduces the runtime by 5 minutes. On a developer workstation which doesn't\ndownload binaries on every test run the speedup is closer to linear.\nWaiting 4 minutes instead of 15 for a complete test suite means the engineers\ncan actually run the complete test suite as part of their normal workflow,\ninstead of sending the code to a CI platform and context switching to\na different project.\n\n## Usage\n\nAdd paraspec to your Gemfile:\n\n    gem 'paraspec'\n\nThis is necessary because paraspec has its own dependencies and loads\nthe application being tested into its environment, hence both paraspec's\nand application's dependencies need to exist in the same Bundler environment.\n\nThen, for a test suite with no external dependencies, using paraspec is\ntrivially easy. Just run:\n\n    paraspec\n\nTo specify concurrency manually:\n\n    paraspec -c 4\n\nTo pass options to rspec, for example to filter examples to run:\n\n    paraspec -- -e 'My test'\n    paraspec -- spec/my_spec.rb\n\nFor a test suite with external dependencies, paraspec sets the\n`TEST_ENV_NUMBER` environment variable to an integer starting from 1\ncorresponding to the worker number, like\n[parallel_tests](https://github.com/grosser/parallel_tests) does.\nThe test suite can then configure itself differently in each worker.\n\nBy default the master process doesn't have `TEST_ENV_NUMBER` set.\nTo have that set to `1` use `--master-is-1` option to paraspec:\n\n    paraspec --master-is-1\n\n## Advanced Usage\n\n### Formatters\n\nParaspec works with any RSpec formatter, and supports multiple formatters\njust like RSpec does. If your test suite is big enough for parallel execution\nto make a difference, chances are the default progress and documentation\nformatters aren't too useful for dealing with its output.\n\nI recommend [Fuubar](https://github.com/thekompanee/fuubar) and\n[RSpec JUnit Formatter](https://github.com/sj26/rspec_junit_formatter)\nconfigured at the same time. Fuubar produces a very nice looking progress bar\nplus it prints failures and exceptions to the terminal as soon as they\noccur. JUnit output, passed through a JUnit XML to HTML converter like\n[junit2html](https://gitlab.com/inorton/junit2html), is much handier\nthan going through terminal output when a run produces 100 or 1000\nfailing tests.\n\n### Debugging\n\nParaspec offers several debugging aids. For interactive debugging use the\nterminal option:\n\n    paraspec -T\n\nThis option makes paraspec stay attached to the terminal it was\nlaunched in, making it possible to insert e.g. `byebug` calls in supervisor,\nmaster or worker code as well as anywhere in the test suite being executed\nand have byebug work. Setting this option also removes internal timeouts\non interprocess waits and sets concurrency to 1, however concurrency\ncan be reset with a subsequent `-c` option:\n\n    paraspec -T -c 2\n\nParaspec can produce copious debugging output in several facilities.\nThe debugging output is turned on with `-d`/`--debug` option:\n\n    paraspec -d state   # supervisor, master, worker state transitions\n    paraspec -d ipc     # IPC requests and responses\n    paraspec -d perf    # timing \u0026 performance information\n\n### Executing Tests Together\n\nIt is possible to specify that a group of tests should be executed in the\nsame worker rather than distributed. This is useful when the setup for\nthe tests is expensive and therefore is done once with multiple tests\ndefined on the result.\n\nThe grouping is defined by specifying `{group: true}` paraspec option on\na `describe` or a `context` block as follows:\n\n    describe 'Run these together', paraspec: {group: true} do\n      before(:all) do\n        # expensive setup\n      end\n      \n      it 'does something' do\n        # ...\n      end\n      \n      it 'does something else' do\n        # ...\n      end\n      \n      after(:all) do\n        # teardown\n      end\n    end\n\n## Caveats\n\nThe master and workers need to all define the same example groups and\nexamples, otherwise a worker may retrieve an example group from the master\nthat it is unable to run. RSpec provides a way to define tests conditionally\nvia `if:` and `unless:` options on contexts and examples, and if this\nfunctionality is used it is important to make sure that all workers are\nconfigured identically (especially if such conditional configuration is\ndependent on external resources such as a network server).\n\nParaspec will check workers' example groups and examples for equality\nwith master and will raise an error if there is a mismatch.\n\n## Known Issues\n\nAborting a test run with Ctrl-C can leave the workers still running.\n\n## Bugs \u0026 Patches\n\nPlease report via issues and pull requests.\n\n## License\n\nMIT\n\n## See Also\n\n[Knapsack](https://docs.knapsackpro.com/ruby/knapsack#step-for-rspec)\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparaspec%2Fparaspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparaspec%2Fparaspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparaspec%2Fparaspec/lists"}