Test cases for Curve pools.
forked
: Tests designed for use in a forked mainnetfixtures
: Pytest fixturespools
: Tests for pool contractstoken
: Tests for LP token contractszaps
: Tests for deposit contracts
conftest.py
: Base configuration file for the test suite.simulation.py
: A python model of the math used within Curve's contracts. Used for testing expected outcomes with actual results.
- Tests are organized by general category, then split between unitary and integration tests.
- Common tests for all pools are located in
tests/pools/common
, for zaps intests/zaps/common
. - Common metapool tests are located at
tests/pools/meta
, for zaps intests/zaps/meta
. - Valid pool names are the names of the subdirectories within
contracts/pools
. - For pool templates, prepend
template-
to the subdirectory names withincontracts/pool-templates
. For example, the base template istemplate-base
.
To run the entire suite:
brownie test
Note that this executes over 10,000 tests and may take a significant amount of time to finish.
The test suite is divided into several logical categories. Tests may be filtered using one or more flags:
--pool <POOL NAME>
: only run tests against a specific pool--integration
: only run integration tests (tests within anintegration/
subdirectory)--unitary
: only run unit tests (tests NOT found in anintegration/
subdirectory)
For example, to only run the unit tests for 3pool:
brownie test --pool 3pool --unitary
To run the test suite against a forked mainnet:
brownie test --network mainnet-fork
In this mode, the actual underlying and wrapped coins are used for testing. Note that forked mode can be very slow, especially if you are running against a public node.
Test fixtures are located within the tests/fixtures
subdirectory. New fixtures should be added here instead of within the base conftest.py
.
All fixtures are documented within the fixtures subdirectory readme.
We use the following custom markers to parametrize common tests across different pools:
Exclude one or more pools from the given test.
@pytest.mark.skip_pool("compound", "usdt", "y")
def test_only_some_pools(swap):
...
Only run the given test against one or more pools specified in the marker.
@pytest.mark.target_pool("ren", "sbtc")
def test_btc_pools(swap):
...
Exclude specific pool types from the given test.
@pytest.mark.skip_pool_type("meta", "eth")
def test_not_metapools(swap):
...
The available pool types are: arate
, crate
, eth
, meta
.
By default, the pool type is base
.
Only run the given test against pools that involve lending.
@pytest.mark.lending
def test_underlying(swap):
...
Only run the given test against pools that use a deposit contract.
@pytest.mark.zap
def test_deposits(zap):
...
Parametrizes each of the given arguments with a range of numbers equal to the total number of coins for the given pool. When multiple arguments are given, each argument has a unique value for every generated test.
For example, itercoins("send", "recv")
with a pool of 3 coins will parametrize with the sequence [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
.
If underlying
is set as True
, the upper bound of iteration corresponds to the true number of underlying coins. This is useful when testing metapools.
@pytest.mark.itercoins("send", "recv"):
def test_swap(accounts, swap, send, recv):
swap.exchange(send, recv, 0, 0, {'from': accounts[0]})