{"id":13421658,"url":"https://github.com/PaulRBerg/prb-test","last_synced_at":"2025-03-15T10:31:16.355Z","repository":{"id":45725626,"uuid":"513491801","full_name":"PaulRBerg/prb-test","owner":"PaulRBerg","description":"Modern collection of testing assertions and logging utilities for Solidity","archived":false,"fork":false,"pushed_at":"2024-12-26T16:08:50.000Z","size":2711,"stargazers_count":182,"open_issues_count":3,"forks_count":15,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-10T19:14:35.149Z","etag":null,"topics":["assertions","blockchain","ethereum","foundry","smart-contracts","solidity","testing"],"latest_commit_sha":null,"homepage":"","language":"Solidity","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/PaulRBerg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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},"funding":{"custom":"https://3cities.xyz/#/pay?c=CAESFAKY9DMuOFdjE4Wzl2YyUFipPiSfIgICATICCAJaFURvbmF0aW9uIHRvIFBhdWwgQmVyZw","github":"PaulRBerg"}},"created_at":"2022-07-13T11:20:07.000Z","updated_at":"2024-12-26T16:08:53.000Z","dependencies_parsed_at":"2023-02-04T01:16:00.415Z","dependency_job_id":"5c25d090-8fbf-4a17-b15f-610fa63c8d9a","html_url":"https://github.com/PaulRBerg/prb-test","commit_stats":{"total_commits":93,"total_committers":5,"mean_commits":18.6,"dds":"0.21505376344086025","last_synced_commit":"3da0913545a06514522e840d0b96a2013fb5d297"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaulRBerg","download_url":"https://codeload.github.com/PaulRBerg/prb-test/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243718919,"owners_count":20336590,"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":["assertions","blockchain","ethereum","foundry","smart-contracts","solidity","testing"],"created_at":"2024-07-30T23:00:27.771Z","updated_at":"2025-03-15T10:31:16.349Z","avatar_url":"https://github.com/PaulRBerg.png","language":"Solidity","readme":"# PRBTest [![Github Actions][gha-badge]][gha] [![Coverage][codecov-badge]][codecov] [![Foundry][foundry-badge]][foundry] [![License: MIT][license-badge]][license]\n\n[gha]: https://github.com/PaulRBerg/prb-test/actions\n[gha-badge]: https://github.com/PaulRBerg/prb-test/actions/workflows/ci.yml/badge.svg\n[codecov]: https://codecov.io/gh/PaulRBerg/prb-test\n[codecov-badge]: https://codecov.io/gh/PaulRBerg/prb-test/branch/main/graph/badge.svg?token=T46OSU33QB\n[foundry]: https://getfoundry.sh/\n[foundry-badge]: https://img.shields.io/badge/Built%20with-Foundry-FFDB1C.svg\n[license]: https://opensource.org/licenses/MIT\n[license-badge]: https://img.shields.io/badge/License-MIT-blue.svg\n\nPRBTest is a modern collection of testing assertions and logging utilities for Solidity, and is meant to be a drop-in\nreplacement for DSTest.\n\n- Feature-packed: assertions for equalities, inequalities, approximate equalities, numerical comparisons, and more\n- Type-rich: every assertion has overloads for `address`, `bytes`, `bytes32`, `int256`, `string` and `uint256`\n- Versioned releases so that you don't accidentally pull the latest version and break your test suites\n- Meant to be used with Foundry, but can also be used with Hardhat\n- Complementary to Forge Std\n- Designed for Solidity \u003e=0.8.0\n- Thoroughly tested\n\n## Install\n\n### Template\n\nIf you're starting a project from scratch, the easiest way to install PRBTest is to use my [Foundry\ntemplate][my-foundry-template], since it comes pre-configured with PRBTest.\n\n### Node.js\n\nThis is the recommended approach.\n\nInstall PRBTest using your favorite package manager, e.g., with Bun:\n\n```shell\nbun add @prb/test\n```\n\nThen, if you are using Foundry, you need to add this to your `remappings.txt` file:\n\n```text\n@prb/test/=node_modules/@prb/test/src/\n```\n\n### Git Submodules\n\nThis installation method is not recommended, but it is available for those who prefer it.\n\nFirst, install the submodule using Forge:\n\n```shell\nforge install --no-commit PaulRBerg/prb-test@release-v0\n```\n\nYour `.gitmodules` file should now contain the following entry:\n\n```toml\n[submodule \"lib/prb-test\"]\n  branch = \"release-v0\"\n  path = \"lib/prb-test\"\n  url = \"https://github.com/PaulRBerg/prb-test\"\n```\n\nFinally, add this to your `remappings.txt` file:\n\n```text\n@prb/test/=lib/prb-test/\n```\n\n## Usage\n\nOnce installed, all you need to do is import `PRBTest` and inherit from it in your test contract. `PRBTest` comes with a\npre-instantiated [cheatcodes](https://book.getfoundry.sh/cheatcodes/) environment accessible via the `vm` property. It\nalso has support for logs.\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity \u003e=0.8.0;\n\nimport { PRBTest } from \"@prb/test/PRBTest.sol\";\n\ncontract MyTest is PRBTest {\n  function testExample() external {\n    vm.warp(block.timestamp + 100);\n    emit Log(\"Hello World\");\n    assertTrue(true);\n  }\n}\n```\n\n### Assertions\n\nAll assertions have overloads with an additional `err` argument, so that you can pass custom error messages.\n\n| Name             | Argument Types                                                                           |\n| ---------------- | ---------------------------------------------------------------------------------------- |\n| `assertTrue`     | `bool`                                                                                   |\n| `assertFalse`    | `bool`                                                                                   |\n| `assertEq`       | `address`, `bytes`, `bytes32`, `int256`, `string`, `uint256` and their array equivalents |\n| `assertNotEq`    | `address`, `bytes`, `bytes32`, `int256`, `string`, `uint256` and their array equivalents |\n| `assertAlmostEq` | `int256` and `uint256`                                                                   |\n| `assertGt`       | `int256` and `uint256`                                                                   |\n| `assertGte`      | `int256` and `uint256`                                                                   |\n| `assertLt`       | `int256` and `uint256`                                                                   |\n| `assertLte`      | `int256` and `uint256`                                                                   |\n| `assertContains` | `address[]`, `bytes32[]`, `int256[]`, `string[]`, and `uint256[]`                        |\n\n### Forge Std\n\nPRBTest can be used alongside all testing utilities from [forge-std][forge-std], except for their [Test][forge-std-test]\ncontract.\n\nHere's an example for how to use PRBTest with `StdCheats` and `stdError`:\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity \u003e=0.8.0;\n\nimport { PRBTest } from \"@prb/test/PRBTest.sol\";\nimport { StdCheats } from \"forge-std/StdCheats.sol\";\nimport { stdError } from \"forge-std/Test.sol\";\n\ncontract MyTest is PRBTest, StdCheats {\n  function testArithmeticOverflow() external {\n    uint256 a = type(uint256).max;\n    uint256 b = 1;\n    vm.expectRevert(stdError.arithmeticError);\n    a + b;\n  }\n}\n```\n\n## Why Choose PRBTest Over DSTest?\n\n[DSTest][ds-test] is great. I have used it for a while, and I like it a lot. But, with time, I slowly came to realize\nthat there's a lot of room for improvement.\n\n### 1. Missing Features and Tests\n\nDSTest is incomplete. Some commonly needed assertions, like equality assertions for arrays, `assertEq(bool,bool)` and\n`assertNotEq`, are missing from DSTest. PRBTest fills these gaps, and then some.\n\nAlso, the DSTest testing assertions are not themselves tested. Whereas the PRBTest testing assertions are tested, and in\nfact they are quite thoroughly tested. All other things being equal, this should give you more confidence that your\ntests do what you intend them to do.\n\n### 2. No Release Versioning\n\nDSTest doesn't version its releases, which makes it difficult to future-proof consumer repos. It's quite easy to\naccidentally update your git submodules and thus break your test suites. For\n[some users](https://github.com/dapphub/ds-test/issues/32), this is a real pain.\n\nPRBTest is versioned via tags and branches and all changes are tracked in a [CHANGELOG](./CHANGELOG.md) file. I maintain\nredundant branches for each release because git submodules\n[don't support tags](https://stackoverflow.com/q/1777854/3873510).\n\nI will strive to follow the [semver](https://semver.org/) versioning scheme, though I won't do this before the v1.0\nrelease, and it might not always be feasible.\n\n### 3. Path Dependence\n\nAs one of the maintainers of DSTest said [here](https://github.com/dapphub/ds-test/pull/21#issuecomment-903668033),\nupdating DSTest is painful to orchestrate. The reasons for this are twofold:\n\n1. Every DappTools project uses it as a git submodule.\n2. DSTest releases have not been versioned.\n\nSo any significant change in DSTest might wreak havoc downstream.\n\nThis issue has led to a \"balkanization\" of DSTest forks and extensions. See, for instance, Solmate's\n[DSTestPlus][ds-test-plus] and Forge Std's [Test][forge-std-test]. Also see the discussions in this\n[PR](https://github.com/foundry-rs/forge-std/pull/38), in which the PR author ended up making the PR against `forge-std`\nrather than `ds-test` because he feared that his PR won't be merged.\n\n### 4. Lack of Backward Compatibility with Node.js\n\nIt is my firm conviction that Foundry is the future of Ethereum smart contract development. Solidity code is best tested\nin Solidity itself.\n\nBut, due to various historical reasons, the Ethereum ecosystem has for a long time relied upon JavaScript for testing\nsmart contracts. Refactoring a code base from Hardhat or Truffle to Foundry takes time, and it may not always be\npossible to do it in one fell swoop. Thus, to ensure backward compatibility, PRBTest is available as a Node.js package\nin the npm package registry.\n\nFor more details about this, see this discussion [here](https://github.com/dapphub/ds-test/issues/35).\n\n## Contributing\n\nFeel free to dive in! [Open](https://github.com/PaulRBerg/prb-test/issues/new) an issue,\n[start](https://github.com/PaulRBerg/prb-test/discussions/new) a discussion or submit a PR.\n\n### Pre Requisites\n\nYou will need the following software on your machine:\n\n- [Git](https://git-scm.com/downloads)\n- [Foundry](https://github.com/foundry-rs/foundry)\n- [Node.Js](https://nodejs.org/en/download/)\n- [Bun](https://bun.sh)\n\nIn addition, familiarity with [Solidity](https://soliditylang.org/) is requisite.\n\n### Set Up\n\nClone this repository including submodules:\n\n```sh\n$ git clone --recurse-submodules -j8 git@github.com:PaulRBerg/prb-test.git\n```\n\nThen, inside the project's directory, run this to install the Node.js dependencies:\n\n```sh\n$ bun install\n```\n\nNow you can start making changes.\n\n### Syntax Highlighting\n\nYou will need the following VSCode extensions:\n\n- [hardhat-solidity](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity)\n\n## Acknowledgements\n\nThese contracts were inspired by or directly modified from the following sources:\n\n- [dapphub/ds-test](https://github.com/dapphub/ds-test/)\n- [foundry-rs/forge-std](https://github.com/foundry-rs/forge-std/)\n\n## License\n\nThis project is licensed under MIT.\n\n\u003c!-- Links --\u003e\n\n[ds-test]: https://github.com/dapphub/ds-test\n[ds-test-plus]:\n  https://github.com/Rari-Capital/solmate/blob/03e425421b24c4f75e4a3209b019b367847b7708/src/test/utils/DSTestPlus.sol\n[forge-std]: https://github.com/foundry-rs/forge-std\n[forge-std-test]: https://github.com/foundry-rs/forge-std/blob/c19dfd2f2a88a461216b0dd1f4961e1a85dcad46/src/Test.sol\n[my-foundry-template]: https://github.com/paulrberg/foundry-template\n","funding_links":["https://3cities.xyz/#/pay?c=CAESFAKY9DMuOFdjE4Wzl2YyUFipPiSfIgICATICCAJaFURvbmF0aW9uIHRvIFBhdWwgQmVyZw","https://github.com/sponsors/PaulRBerg"],"categories":["Software Development"],"sub_categories":["Testing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPaulRBerg%2Fprb-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPaulRBerg%2Fprb-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPaulRBerg%2Fprb-test/lists"}