Part 5: Edge Cases Tests¶
Test a Modifier “throw” Exception¶
In the contract we used a modifier, to enforce a pre-condition on the donate
function:
A donation should not be of value 0, otherwise the modifier will throw
. We wanted this modifier
to make sure that the donations counter will not increment for zero donations:
modifier nonZeroValue() { if (!(msg.value > 0)) throw; _; }
function donate(uint usd_rate) public payable nonZeroValue {...}
Edit the tests file:
$ nano tests/test_donator.py
And add the following test to the bottom of the file:
import pytest
from ethereum.tester import TransactionFailed
def test_modifier(chain):
donator, deploy_tx_hash = chain.provider.get_or_deploy_contract('Donator')
with pytest.raises(TransactionFailed):
donator.transact({'value':0}).donate(4)
defaultUsdRate = donator.call().defaultUsdRate()
assert defaultUsdRate == 350
Simple test. Note the py.test syntax for expected exceptions: with pytest.raises(...)
.
The test transaction is of 0 value:
donator.transact({'value':0}).donate(4)
So the modifier should throw
.
Since the transaction should fail, the defaultUsdRate
should remain the same, with the original initialisation
of the constructor
function Donator() {
defaultUsdRate = 350;
}
And ignore the test transaction with .donate(4)
.
Run the tests:
$ py.test --disable-pytest-warnings
===================================== test session starts ===============
platform linux -- Python 3.5.2, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
rootdir: /home/mary/projects/donations, inifile:
plugins: populus-1.8.0, hypothesis-3.14.0
collected 4 items
tests/test_donator.py ....
========================= 4 passed, 20 warnings in 1.07 seconds =========
Works, all 4 tests passed.
Fallback Function¶
At the moment, Populus does not have a builtin option to call fallback function.
To run it, you can send a simple transaction with Web3, or even better: write another function that you can test,
and let the fallback
only call this function
Interim Summary¶
- Working Contract
- All tests pass
The next step is to deploy the contract to a persisetent chain.