readme update

pull/5370/head
aniket-engg 5 years ago committed by Aniket
parent 7b7a0e4111
commit efd007faa8
  1. 173
      remix-tests/README.md

@ -1,79 +1,148 @@
Remix-Tests ## Remix-Tests
--- `remix-tests` is a tool to test Solidity smart contracts. It works underneath Remix IDE plugin "Solidity Unit Testing" which is used to write and run test cases for a contract. Tests are written in Solidity itself. `remix-tests` can be used as CLI and a library too.
> Tests for the Ethereum tool suite [Remix](https://github.com/ethereum/remix)
### Installation ### Installation
As a dependency inside file:
`npm install --save remix-tests`
As a dev dependency:
`npm install --save-dev remix-tests`
As a global NPM module to use as CLI:
`npm -g install remix-tests` `npm -g install remix-tests`
### Test structure ### Test structure
remix-tests provides and injects a built-in assert library for testing purpose.
#### Assert library
| Available functions | Supported types |
| ------------- | ------------- |
| `Assert.ok()` | `bool` |
| `Assert.equal()` | `uint`, `int`, `bool`, `address`, `bytes32`, `string` |
| `Assert.notEqual()` | `uint`, `int`, `bool`, `address`, `bytes32`, `string` |
| `Assert.greaterThan()` | `uint`, `int` |
| `Assert.lesserThan()` | `uint`, `int` |
#### Available special functions:
Apart from above, library provides some special functions as:
* `beforeEach()` - runs before each test
* `beforeAll()` - runs before all tests
* `afterEach()` - runs after each test
* `afterAll()` - runs after all tests
#### Use a different sender `msg.sender`
It is quite common that a contract need to be tested in different situation.
Especially being able to set before hand the sender account (`msg.sender`) used for a specific tests suite enable quite a lot a new test use cases.
please checkout this [test contract](https://github.com/ethereum/remix/blob/master/remix-tests/tests/various_sender/sender_test.sol) for an example.
Note that `TestsAccounts` is filled with all the accounts available in `web3.eth.accounts()`.
### How to use
#### Command Line
* To run all files inside `examples` directory
```
$ remix-tests examples/
```
* To run single test file named `simple_storage_test.sol` inside `examples` directory
```
$ remix-tests examples/simple_storage_test.sol
```
**NOTE:** remix-tests will assume that name of tests file ends with `"_test.sol"`. e.g `simple_storage_test.sol`
**Example:**
Consider for a simple storage contract named `simple_storage.sol`:
Example test file:
```Javascript ```Javascript
pragma solidity ^0.4.7; pragma solidity >=0.4.22 <0.7.0;
contract SimpleStorage {
uint public storedData;
constructor() public {
storedData = 100;
}
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint retVal) {
return storedData;
}
}
```
test file `simple_storage_test.sol` can be as:
```Javascript
pragma solidity >=0.4.22 <0.7.0;
import "remix_tests.sol"; // injected by remix-tests import "remix_tests.sol"; // injected by remix-tests
import "./simple_storage.sol"; import "./simple_storage.sol";
contract MyTest { contract MyTest {
SimpleStorage foo; SimpleStorage foo;
uint i = 0;
function beforeAll() { function beforeEach() public {
foo = new SimpleStorage(); foo = new SimpleStorage();
} }
function beforeEach() { function initialValueShouldBe100() public returns (bool) {
if (i == 1) { return Assert.equal(foo.get(), 100, "initial value is not correct");
foo.set(200);
}
i += 1;
} }
function initialValueShouldBe100() public { function valueIsSet200() public returns (bool) {
Assert.equal(foo.get(), 100, "initial value is not correct"); foo.set(200);
return Assert.equal(foo.get(), 200, "value is not 200");
} }
function initialValueShouldBe200() public constant returns { function valueIsNotSet200() public returns (bool) {
return Assert.equal(foo.get(), 200, "initial value is not correct"); return Assert.notEqual(foo.get(), 200, "value is 200");
} }
} }
``` ```
See also: example [Su Squares contract](https://github.com/su-squares/ethereum-contract/tree/e542f37d4f8f6c7b07d90a6554424268384a4186) and [https://travis-ci.org/su-squares/ethereum-contract/builds/446186067](Travis build) that uses remix-tests for continuous integration testing. Running `simple_storage_test.sol` file will output as:
Available special functions:
* `beforeEach()` - runs before each test
* `beforeAll()` - runs before all tests
#### Assert library
| Available functions | Supported types |
| ------------- | ------------- |
| `Assert.ok()` | `bool` |
| `Assert.equal()` | `uint`, `int`, `bool`, `address`, `bytes32`, `string` |
| `Assert.notEqual()` | `uint`, `int`, `bool`, `address`, `bytes32`, `string` |
| `Assert.greaterThan()` | `uint`, `int` |
| `Assert.lesserThan()` | `uint`, `int` |
#### Use a different sender `msg.sender` ```
◼ MyTest
It is quite common that a contract need to be tested in different situation. [19:15:02] payload method is eth_gasPrice
Especially being able to set before hand the sender account (`msg.sender`) used for a specific tests suite enable quite a lot a new test use cases. [19:15:02] payload method is eth_sendTransaction
please checkout https://github.com/ethereum/remix/blob/master/remix-tests/tests/various_sender/sender_test.sol for an example. [19:15:02] payload method is eth_getTransactionReceipt
note that `TestsAccounts` is filled with all the accounts available in `web3.eth.accounts()`. [19:15:02] payload method is eth_gasPrice
[19:15:02] payload method is eth_sendTransaction
### Command Line [19:15:02] payload method is eth_getTransactionReceipt
✓ Initial value should be100
Remix-Tests will assume the tests will files whose name end with `"_test.sol"`. e.g `simple_storage_test.sol` [19:15:02] payload method is eth_gasPrice
[19:15:02] payload method is eth_sendTransaction
[19:15:02] payload method is eth_getTransactionReceipt
[19:15:02] payload method is eth_gasPrice
[19:15:02] payload method is eth_sendTransaction
[19:15:02] payload method is eth_getTransactionReceipt
✓ Value is set200
[19:15:02] payload method is eth_gasPrice
[19:15:02] payload method is eth_sendTransaction
[19:15:02] payload method is eth_getTransactionReceipt
[19:15:02] payload method is eth_gasPrice
[19:15:02] payload method is eth_sendTransaction
[19:15:02] payload method is eth_getTransactionReceipt
✓ Value is not set200
```
Usage: :point_right: remix-test can also be used for continuous integration testing. See example [Su Squares contract](https://github.com/su-squares/ethereum-contract/tree/e542f37d4f8f6c7b07d90a6554424268384a4186) and [Travis build](https://travis-ci.org/su-squares/ethereum-contract/builds/446186067)
* A directory with tests files `remix-tests examples/` ///// TODO
* A test file `remix-tests examples/simple_storage_test.sol`
### Library #### Library
Importing the library: Importing the library:
```Javascript ```Javascript
@ -82,12 +151,12 @@ const RemixTests = require('remix-tests');
Running a single test object: Running a single test object:
```Javascript ```Javascript
remixTests.runTest(contractName, contractObj, testCallback, resultsCallback) remixTests.runTest(testName, testObj, testCallback, resultsCallback)
``` ```
params: **Params:**
`testName` - `string` name of the test * `testName` - `string` name of the test
`testObj` - web3.js 1.0 contract instance of the test * `testObj` - web3.js 1.0 contract instance of the test
`testCallback(object)` - called each time there is a test event. 3 possible type of objects: * `testCallback(object)` - called each time there is a test event. 3 possible type of objects:
* `{ type: 'contract', value: '<TestName>', filename: '<test_filename.sol>' }` * `{ type: 'contract', value: '<TestName>', filename: '<test_filename.sol>' }`
* `{ type: 'testPass', value: '<name of testing function>', time: <time taken>, context: '<TestName>'}` * `{ type: 'testPass', value: '<name of testing function>', time: <time taken>, context: '<TestName>'}`
* `{ type: 'testFailure', value: '<name of testing function>', time: <time taken>, context: '<TestName>', errMsg: '<message in the Assert>' }` * `{ type: 'testFailure', value: '<name of testing function>', time: <time taken>, context: '<TestName>', errMsg: '<message in the Assert>' }`

Loading…
Cancel
Save