Tests on testnet are buggy when using `Contract.at`
See original GitHub issueEnvironment information
brownie
Version: 1.14.6ganache-cli
Version: N/Asolc
Version: N/A- Python Version: 3.9.5
- OS: OSX
What was wrong?
When running tests on a live network like kovan, brownie attempts to “tear down” instances with the close
function and calls _remove_contract
from a list it gathers:
for contract in [x for v in self._containers.values() for x in v._contracts]
This can bring in duplicates, so when brownie del
s them, it runs into a keyerror since it will have already deleted it.
Here is a full output:
patrick@iMac: [~/code/nft-mix - (main)] $ brownie test --network kovan -s
Brownie v1.14.6 - Python development framework for Ethereum
================================================================================= test session starts ==================================================================================
platform darwin -- Python 3.9.5, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /Library/Frameworks/Python.framework/Versions/3.9/bin/python3
cachedir: .pytest_cache
hypothesis profile 'brownie-verbose' -> verbosity=2, deadline=None, max_examples=50, stateful_step_count=10, report_multiple_bugs=False, database=DirectoryBasedExampleDatabase(PosixPath('/Users/patrick/.brownie/hypothesis'))
rootdir: /Users/patrick/code/nft-mix
plugins: eth-brownie-1.14.6, web3-5.18.0, xdist-1.34.0, forked-1.3.0, hypothesis-6.10.0, flaky-3.7.0
collected 3 items
tests/integration/test_advanced_int.py::test_can_create_advanced_collectible_integration PASSED
============================================================================= 1 passed, 2 skipped in 8.72s =============================================================================
File "/Users/patrick/code/brownie/brownie/_cli/__main__.py", line 64, in main
importlib.import_module(f"brownie._cli.{cmd}").main()
File "/Users/patrick/code/brownie/brownie/_cli/test.py", line 61, in main
return_code = pytest.main(pytest_args, ["pytest-brownie"])
File "pytest-6.2.3-py3.9.egg/_pytest/config/__init__.py", line 162, in main
ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
File "pluggy/hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "pluggy/manager.py", line 93, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "pluggy/manager.py", line 84, in <lambda>
self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
File "pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "pytest-6.2.3-py3.9.egg/_pytest/main.py", line 316, in pytest_cmdline_main
return wrap_session(config, _main)
File "pytest-6.2.3-py3.9.egg/_pytest/main.py", line 311, in wrap_session
config._ensure_unconfigure()
File "pytest-6.2.3-py3.9.egg/_pytest/config/__init__.py", line 987, in _ensure_unconfigure
self.hook.pytest_unconfigure(config=self)
File "pluggy/hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "pluggy/manager.py", line 93, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "pluggy/manager.py", line 84, in <lambda>
self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
File "pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "/Users/patrick/code/brownie/brownie/test/managers/base.py", line 263, in pytest_unconfigure
project.close(raises=False)
File "/Users/patrick/code/brownie/brownie/project/main.py", line 469, in close
_remove_contract(contract)
File "/Users/patrick/code/brownie/brownie/network/state.py", line 563, in _remove_contract
del _contract_map[contract.address]
KeyError: '0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9'
Please include information like:
Fix
This can be fixed easily by changing that one line to:
for contract in list(set([x for v in self._containers.values() for x in v._contracts])):
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (7 by maintainers)
Top Results From Across the Web
How Effective are Smart Contract Analysis Tools? ...
The resulting buggy smart contracts are then analyzed using the static analysis tools being evaluated, and the results are inspected for those ...
Read more >Testing | CosmWasm Documentation
At some point in Smart Contract development, everyone will arrive at tests. Tests are what give you and your protocol sleep at night...
Read more >Getting started with smart contract in Bug Bounty
A successful test confirms that we can move arbitrary token balances to and from the contracts. Start by funding 2 accounts through the...
Read more >How to Test a Smart Contract with Remix | by mbvissers.eth
Easy testing without deploying to a testnet. ... Remix has got to be one of the most well-known IDEs for smart contract development...
Read more >Mutation Testing for Ethereum Smart Contract
Smart contract is a special program that manages digital assets on blockchain. It is difficult to recover the loss if users make transactions...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I’ve gone deep down the brownie hole on this, and I think I see a few easy wins. Let me know what you think.
I just used
from_abi
instead ofat