4

I have the following test code snippet in my brownie project:

from hypothesis import settings, given, strategies as st
from brownie import *
import brownie

st_buy_amount_eth = st.integers(min_value=int(Wei("1 gwei")), max_value=int(Wei("10 ether")))

@given(buy_amount=st_buy_amount_eth)
@settings(max_examples=20)
def test_buy_lgt_atleast_for(lgt, accounts, buy_amount):
    print(web3.eth.blockNumber)
    token_amount = buy_amount_to_tokens(buy_amount)  # hard-coded function to verify the math
    if token_amount >= 1:
        tx = lgt.buyLgtAtLeastFor(1, 99999999999, accounts[3], {'from': accounts[2], 'value': buy_amount})
        assert tx.return_value == token_amount
        assert lgt.balanceOf(accounts[3]) == token_amount
    else:
        with brownie.reverts("dev: not enough eth to buy tokens"):
            liquidLgt.buyLgtAtLeast(1, 99999999999, {'from': accounts[2], 'value': buy_amount})

When running the tests with brownie test -s the print output I get is one block higher for each example with hypothesis and I get inconsistent results errors from hypothesis.

Is there a way to set it up so hypothesis will properly reset the chain for each example? That would be awesome, I really hope to get hypothesis to work with brownie!

1 Answer 1

2

You need to import @given from Brownie, not directly from hypothesis:

from brownie.test import given

This is required because Brownie handles isolation via a fixture, but function scoped fixtures only execute once per test (not once per run). From the hypothesis documentation:

... each fixture will run once for the whole function, not once per example.

Brownie solves this by wrapping the test in a function that performs the chain rewind. You can see it handled here in the source code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.