|
| 1 | +# Guide to Web3's tests and CI |
| 2 | + |
| 3 | +Web3 is used in Node.js and browser contexts to interact with a wide variety of clients. Its tests |
| 4 | +try to cover as much of this domain as possible. |
| 5 | + |
| 6 | +If you're looking for a fixture, test pattern or common execution context to validate a change, you should be able find it in the existing test suite. (Caveats include Parity / Quorum clients and MetaMask specific tests.) |
| 7 | + |
| 8 | +## Required Tests |
| 9 | + |
| 10 | +These should pass for PRs to merge: |
| 11 | + |
| 12 | +| Test type | npm command | Example | Description | CI Only | |
| 13 | +| --------- | --------------- | ------ | ----------- | ----- | |
| 14 | +| unit | test | [eth.accounts.sign.js][1] | For discrete pieces of logic | |
| 15 | +| integration | test:e2e:clients | [e2e.contract.events.js][2] | Tests using geth and ganache-cli, (insta-mining and interval mining.) Easy to write and good for modeling complex use-cases | |
| 16 | +| browser | test:e2e:browsers | | The integration tests run in a headless browser using web3.min.js (browserified, vs. ganache-cli) | |
| 17 | +| typescript | dtslint | -- | TS type definitions tests | |
| 18 | +| dependencies | depcheck | -- | Verifies every dependency is listed correctly in the module package | |
| 19 | +| bundle | test:e2e:min | [e2e.minified.js][3] | Verifies minified bundle loads in a headless browser *without* being webpacked / browserified | :white_check_mark: | |
| 20 | +| cdn | test:e2e:cdn | [e2e.cdn.sh][4]| Visual inspection check: publishes an (un-webpacked) site that uses web3.min.js at http://sudden-playground.surge.sh/ | :white_check_mark: | |
| 21 | +| windows | -- | [e2e.windows.sh][5] | Verifies Web3 installs on Windows OS / Node 12 and can connect to Infura over wss and https | :white_check_mark: | |
| 22 | + |
| 23 | + |
| 24 | +## Optional Tests |
| 25 | + |
| 26 | +CI also has tests that install Web3's state at an arbitrary commit in an external real-world project and run *their* unit tests with it. This strategy is borrowed from ethereum/solidity which checks latest Solidity against OpenZeppelin and others to keep abreast of how local changes might affect critical projects downstream from them. |
| 27 | + |
| 28 | +Examples include: |
| 29 | ++ [e2e.mosaic.sh][8]: ~300 unit tests for [a Solidity project built with Buidler & @truffle/contract][9] |
| 30 | ++ [e2e.ganache.core.sh][9]: ~600 unit tests for [a widely used JS testrpc][11] |
| 31 | + |
| 32 | +These tests are "allowed failures". They're: |
| 33 | ++ a pre-publication sanity check that discovers how Web3 performs in the wild |
| 34 | ++ useful for catching problems which are difficult to anticipate |
| 35 | ++ exposed to failure for reasons outside of Web3's control, ex: when fixes here surface bugs in the target. |
| 36 | + |
| 37 | +## Implementation Details |
| 38 | + |
| 39 | +**Code coverage** |
| 40 | + |
| 41 | +Coverage is measured by aggregating the results of tests run in the `unit_and_e2e_clients` |
| 42 | +CI job. |
| 43 | + |
| 44 | +**Tests which use an Ethereum client** |
| 45 | + |
| 46 | +The npm script `test:e2e:clients` greps all tests with an `[ @E2E ]` tag |
| 47 | +in their mocha test description and runs them against: |
| 48 | ++ ganache-cli |
| 49 | ++ geth 1.9.13 (POA, single instance, instamining) |
| 50 | ++ geth 1.9.13 (POA, single instance, mining at 2s intervals) |
| 51 | + |
| 52 | +These tests are grouped in files prefixed by "e2e", ex: `test/e2e.method.call.js`. |
| 53 | + |
| 54 | +Additionally, there are conventional unit tests postfixed `.ganache.js` which spin up a ganache |
| 55 | +server programatically within mocha. This pattern is useful if you want to |
| 56 | +control client configuration for a specific case, test against multiple independent providers, etc. |
| 57 | + |
| 58 | +**"Real world" tests** |
| 59 | + |
| 60 | +The tests which install Web3's current state in an external real-world project and |
| 61 | +run their unit tests accomplish this by publishing the monorepo to an ephemeral private |
| 62 | +npm registry which is spun up in CI using [verdaccio][14]. (Implementation details can |
| 63 | +be seen in [scripts/e2e.npm.publish.sh][15]) |
| 64 | + |
| 65 | +The real world target is then cloned and npm or yarn are used to replace its existing |
| 66 | +Web3 version with the version published to the the private registry. A simple example can be seen at |
| 67 | +[scripts/e2e.ganache.core.sh][10]. |
| 68 | + |
| 69 | +In practice, complex projects can have many versions of Web3 nested in their dependency tree. |
| 70 | +It's important to coerce all of them to the virtually published package's version for the test to be valid. |
| 71 | +This can be done with [scripts/js/resolutions.js][18] which modifies the target's |
| 72 | +`package.json` to take advantage of Yarn's [selective dependency resolutions][17]. |
| 73 | +An example of its use can be seen at [scripts/e2e.mosaic.sh][8]. |
| 74 | + |
| 75 | +[14]: https://verdaccio.org/docs/en/installation |
| 76 | +[15]: https://github.com/ethereum/web3.js/blob/1.x/scripts/e2e.npm.publish.sh |
| 77 | +[17]: https://classic.yarnpkg.com/en/docs/selective-version-resolutions/ |
| 78 | +[18]: https://github.com/ethereum/web3.js/blob/1.x/scripts/js/resolutions.js |
| 79 | + |
| 80 | +[8]: https://github.com/ethereum/web3.js/blob/1.x/scripts/e2e.mosaic.sh |
| 81 | +[9]: https://github.com/cgewecke/mosaic-1 |
| 82 | +[10]: https://github.com/ethereum/web3.js/blob/1.x/scripts/e2e.ganache.core.sh |
| 83 | +[11]: https://github.com/trufflesuite/ganache-core |
| 84 | + |
| 85 | +[1]: https://github.com/ethereum/web3.js/blob/1.x/test/eth.accounts.sign.js |
| 86 | +[2]: https://github.com/ethereum/web3.js/blob/1.x/test/e2e.contract.events.js |
| 87 | +[3]: https://github.com/ethereum/web3.js/blob/1.x/test/e2e.minified.js |
| 88 | +[4]: https://github.com/ethereum/web3.js/blob/1.x/scripts/e2e.cdn.sh |
| 89 | +[5]: https://github.com/ethereum/web3.js/blob/1.x/scripts/e2e.windows.sh |
0 commit comments