nventuro / openzeppelin-test-environment

One-line setup for an awesome testing experience. Under development!

Home Page:http://openzeppelin.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OpenZeppelin Test Environment

NPM Package Build Status

Blazing fast smart contract testing. One-line setup for an awesome testing experience.

  • Near-instant start up: have your code running in under 2s after typing npm test.
  • Test runner agnostic – from the familiarity of Mocha, to parallel tests using Jest or Ava!
  • Non-opinionated: use either @truffle/contract or web3-eth-contract as you see fit.
  • First class support for the OpenZeppelin Test Helpers.
  • Highly configurable: from gas limit and initial balance, to complex custom web3 providers.
  • No global variables, no hacks.

test-environment is the result of our learnings while developing the OpenZeppelin Contracts, combining best practices and the tools we've come to rely on over the years. We think you'll love it!

Quickstart

Install

npm install --save-dev @openzeppelin/test-environment

Usage

Simply require('@openzeppelin/test-environment') in your test files, and it will take care of all Ethereum-related tasks. A local ganache-powered blockchain with unlocked accounts will be spinned up, and all tools will be configured to work with it.

const { accounts, contract } = require('@openzeppelin/test-environment');
const [ tokenHolder ] = accounts;

const ERC20 = contract.fromArtifact('ERC20'); // Loads a compiled contract

async function test() {
  const token = await ERC20.new({ from: tokenHolder });
  const initialBalance = await token.balanceOf(tokenHolder);
}

Note: if you'd rather not rely on truffle contracts and use web3 contract types directly, worry not: you can configure test-environment to use the web3-eth-contract abstraction.

Test runners

test-environment is a testing library, something you use in your tests, as opposed to what actually runs them. For that, you are free to use any regular JavaScript test runner. We recommend picking one of the following:

  • Mocha: simple and straightforward, the easiest way to get started when migrating from truffle test
  • Jest: the most popular runner out there, featuring lightning speed, parallel tests, and extensive guides
  • Ava: a minimalistic runner with parallel tests and support for ES6 and TypeScript

Both Jest and Ava have their own assertions library, but for Mocha, you may want to also use Chai.

Head to our test runners guide to learn more about how to setup each one.

Compiling your contracts

test-environment is not a contract compiler: for that, you'll want to use the OpenZeppelin CLI.

npm install --save-dev @openzeppelin/cli
npx oz compile

Compilation artifacts will be stored in the build/contracts directory, where testing-environment (and most other tools) will read them from.

OpenZeppelin Test Helpers support

testing-environment does not include the Test Helpers library, but it will automatically detect it and configure it if it is installed. Simply require('@openzeppelin/test-helpers') and use it as you already do.

Configuration

The default options are very sensible and should work fine for most testing setups, but you are free to modify these. Simply create a file named test-environment.config.js at the root level of your project: its contents will be automatically loaded.

module.exports = {
  accounts: {
    amount: 10, // Number of unlocked accounts
    ether: 100, // Initial balance of unlocked accounts (in ether)
  },

  contracts: {
    type: 'truffle', // Contract abstraction to use: 'truffle' for @truffle/contract or 'web3' for web3-eth-contract
    defaultGas: 6e6, // Maximum gas for contract calls (when unspecified)
  },

  blockGasLimit: 8e6, // Maximum gas per block
};

Migrating from truffle test

Despite Truffle's design and goals being different from test-environment's (one is an all-out development framework and the other a testing library), it is still quite simple to migrate from a truffle test-based suite. Doing the whole process on the OpenZeppelin Contracts repository took less than thirty minutes!

Because truffle test uses a lightly modified Mocha as a test runner (bundled with Chai for assertions), these two make best choice for a simple migration:

npm install --save-dev mocha chai

Don't forget to make Mocha the entry point of your test suite once you install it:

// in package.json
"scripts": {
-  "test": "npx truffle test"
+  "test": "npx mocha --exit --recursive test"
}

It is now time to modify the test files themselves. The changes are few, but important:

  1. Add require('@openzeppelin/test-environment') to access the variables exported by the library: accounts, contract, web3, etc.
  2. truffle test automagically imports Chai: you will need to require it and set it up manually
  3. Replace all instances of artifacts.require for contract.fromArtifact
  4. Replace all intances of truffle test's contract function with a regular Mocha describe. You can still access the accounts array in accounts

That's it! Let's see how a full migration might look like:

+const { accounts, contract, web3 } = require('@openzeppelin/test-environment');

// Setup Chai for 'expect' or 'should' style assertions (you only need one)
+const { expect } = require('chai');
+require('chai').should();

-const ERC20 = artifacts.require('ERC20');
+const ERC20 = contract.fromAbstraction('ERC20');

-contract('ERC20', function (accounts) {
+describe('ERC20', function () {
  ...
}

You are now ready to start using test-environment by running npm test. Enjoy lightning fast testing!

API

test-environment exposes a number of variables that are used to interact with the local testing blockchain it setups. These are described in detail here:

const { accounts, defaultSender, contract, web3, provider, isHelpersConfigured } = require('@openzeppelin/test-environment');

accounts

accounts: string[]

An array of strings with the addresses of the accounts available for testing. By default, there are 10 unlocked accounts with 100 ETH each, but this can be configured.

const [ sender, receiver ] = accounts;

await myToken.transfer(receiver, 100, { from: sender });

defaultSender

defaultSender: string

A special account that is used by contracts created via contract when no account is specified for a transaction (i.e. there is no explicit from). This account is not included in accounts to prevent accidental bugs during testing: whenever you want an account to make an action (deploy a contract, transfer ownership, etc.) you should be explicit about the sender of the transaction:

const [ owner ] = accounts;

// The depoloyment will be made by 'defaultSender' (not 'owner'!), making it
// the contract's owner
const myContract = await Ownable.new();

// And the following test will fail
expect(await myContract.owner()).to.equal(owner);

contract

contract.fromArtifact: (contract: string) => any;
contract.fromABI: (abi: object, bytecode?: string | undefined) => any;

The contract object is in charge of creating contracts from compilation artifacts. It does this via two functions:

  • fromArtifact looks for a .json file in the build/contracts directory (equivalent to Truffle's artifact.require)
  • fromABI receives an ABI object directly, useful when the full compilation artifacts are not available

They both return instances of either @truffle/contract (by default) or web3-eth-contract, depending on configuration.

const ERC20 = contract.fromArtifact('ERC20');

const myToken = await ERC20.new(initialBalance, initialHolder);

web3

A web3 instance, connected to the local testing blockchain. Useful to access utiltiies like web3.eth.sign, web3.eth.getTransaction, or web3.utils.sha3.

provider

A web3 provider, connected to the local testing blockchain. Used in more advanced scenarios, such as creation of custom web3 or ethers instances.

isHelpersConfigured

isHelpersConfigured: boolean

A boolean indicating if the OpenZeppelin Test Helpers library was autodetected and configured.

License

Released under the MIT License.

About

One-line setup for an awesome testing experience. Under development!

http://openzeppelin.com

License:MIT License


Languages

Language:TypeScript 65.4%Language:JavaScript 33.2%Language:Shell 1.4%