Blazing Fast Contracts Testing
Two things are unavoidable in the life of a software developer – death and writing tests. Certainly, due to advances in technology, it soon might be possible to escape death, but tests are here to stay. While developers recognize the value and importance of tests, not many find it easy to write them.
In the Ethereum world, having a full test suite for smart contracts is an absolute necessity, because a critical bug may lead to funds lost forever.
The famous OpenZeppelin Contracts library has 2273 tests, and it takes 21 minutes to run them. When it takes so long to run a test suite, it becomes a developer experience issue. Even if you want to run only one test in your entire suite, bootstrap time can be as high as 30 seconds, sabotaging your productivity on every run. Forced breaks during development caused by long tests interrupt the flow and decrease productivity.
Not only does a test library need to be fast but the developer experience is crucial for creating and maintaining a comprehensive test suite. If you don’t enjoy writing tests, you’ll inevitably fail to maintain them.
We’ve spent 3 years and countless hours writing tests for the OpenZeppelin Contracts library. We are excited to present the result of what we have learned, our best practices, and the use of the best industry tools – OpenZeppelin Test Environment! This library provides blazing fast smart contracts testing with a developer experience we actually enjoy on a daily basis. We use it to power tests for Contracts and SDK.
Test Environment and Truffle Test Script run side by side with 4x speed
We have managed to drop our Contracts tests suite CI time from 21 minutes to 12 minutes and bootstrap time from 50 seconds to 5 seconds.
Test Environment is a library, not a framework. Unlike other frameworks that manage the entire testing flow, you are free to use any test runner such as Mocha, Jest, or Ava. You decide when and how to run it. You can use either @truffle/contract or web3-eth-contract contract abstraction. We now have a highly configurable and agnostic library to match our needs.
Compile, test, and deploy smart contracts with OpenZeppelin. This is the last piece of the OpenZeppelin development stack. OpenZeppelin Contracts provides the building blocks for writing your contracts, while the CLI allows you to create, upgrade, and interact with them. Test Environment is the last piece of the puzzle, allowing you to test your contracts.
Install
npm install --save-dev @openzeppelin/test-environment
Usage
Simply require the @openzeppelin/test-environment
package in your test files, and it will take care of all Ethereum-related tasks. A local ganache-powered blockchain with unlocked accounts will be spun up, and all tools will be configured to work with it.
For example, integration with Mocha is super easy, and Test Environment also plays nicely with the assertions from the Test Helpers library.
With Mocha
const { accounts, contract, web3 } = require('@openzeppelin/test-environment');
const { BN, balance, ether } = require('@openzeppelin/test-helpers');
const { expect } = require('chai');
const GLDToken = contract.fromArtifact('GLDToken');
describe('GLDToken', function() {
const [sender, receiver] = accounts;
const initialSupply = new BN(100);
beforeEach(async function() {
this.token = await GLDToken.new(initialSupply);
});
describe('total supply', function() {
it('returns the total amount of tokens', async function() {
expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply);
});
});
it('sends ether successfully between accounts', async function() {
const tracker = await balance.tracker(receiver, 'ether');
await web3.eth.sendTransaction({ from: sender, to: receiver, value: ether('10') });
expect(await tracker.delta()).be.bignumber.equal('10');
});
});
As you can see, writing tests with Test Environment looks and feels like a familiar Mocha test experience.
What about real production level examples?
We migrated all the tests at OpenZeppelin Contracts and SDK to use Test Environment. Check them out to see the full potential of Test Environment!