How to use Python to test your Ethereum Smart Contracts
Photo by David McBee from Pexels
I recently started working on Ethereum Blockchain development. Most of the tools, including the Solidity language, are biased towards JavaScript.
While I managed to get started using truffle
when it came to testing, I found that JavaScript tests were (IMO) unnecessarily too long.
But that is the nature of the language.
I have always been more comfortable with Python than JS. I liked and have used py.test
in my previous projects. So when I had an option to test my smart contracts using py.test
, I definitely was gonna give it a try.
That is when I came across populus
. Turns out it aims to be “truffle for pythonistas” (my words, not the “official” tagline, but they can use it.)
Initially it was a personal project — which was officially adopted by the Ethereum organization (on GitHub), adding credibility to the excellent work done so far.
You can read the official documentation here
Testing
As I mentioned earlier, I came for the chance to use py.test
for testing the smart contracts.
Writing the tests (along with web3.py
) was quite easy.
Running the tests in not populus test
(like truffle test
). As I mentioned earlier, it is via py.test
. So it is py.test <folder_containing_tests>/
.. and this is where I ran into a “glitch.”
Turns out there is a known issue and a solution.
One thing I liked about using py.test
was that I was not required to explicitly start testrpc
.
For truffle test
testrpc or geth
, it is required to be run explicitly or else you get the following error:
$ truffle test Could not connect to your Ethereum client. Please check that your Ethereum client: - is running - is accepting RPC connections (i.e., "--rpc" option is used in geth) - is accessible over the network - is properly configured in your Truffle configuration file (truffle.js)
I’m not saying that there is anything is wrong in that, just that it is nice to omit a step.
Local Chain(s)
One more nice feature populus
has over truffle
is the ability to create local geth
instances.
This can be done easily with populus chain new <chain_name>
This does several of the following things :
- Creates a
genesis.json
(Usually one needs to create this by hand, or copy an existing one from “somewhere” and modify) - Creates one account that has enough balance.
- Creates two scripts : one to create genesis block(
init_chain.sh
) and another to start the “node” (run_chain.sh
)
One benefit of this is that a new developer does not need to understand the complexities of various options in both genesis.json
and the long list of command line options to geth
It just works.
This is useful to semi-experienced developer as well. She can modify the genesis.json
and the scripts as required.
Since there is no “change password” concept, one can not create a “better” password without removing the existing account and recreating a new one. This means you need to modify the run_chain.sh
script, since it mentions an account for the --unlock
parameter. One also needs to modify genesis.json
since the “pre-populated” account is mentioned there under alloc
.
But that is OK, since populus
is meant for the development anyway.
Read the detailed tutorial about using populus to create local chains here.
There is also populus chain reset <chain_name>
but it doesn’t work. I’ve filed an issue here.
Deploying the Contracts
For simple, one-off contracts, there is a command line version : populus deploy
For a slightly complex deployments, especially when one needs to pass arguments to the Contract constructor, one needs to write their own Python code.
This is no different than writing migrations scripts in truffle
land, except there one gets “default” scripts on truffle init
, here we don’t.
Read details here.
Migrations
populus
had this feature in older versions, but it was removed. When asked on Gitter, I was told that there is a plan to “bring them back” See this.
Should I ditch Truffle?
Not yet.
While I wanted to use populus
as the only option, I think it is behind the “maturity” compared to truffle
.
For now, I use truffle
for the project I share with others (since truffle
seems to be more “well known”) but for my “personal” project, I will continue to use populus
(and report issues, discuss on Gitter and send in the PR if/where I can).
Note : You can view my (work-in-progress) code here. It has both truffle
as well as populus
config files. The tests are only in Python. I do have a deployment script in Python.
Originally published at mandarvaze.bitbucket.io on March 20, 2018.