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.