Package: algopytest-framework
AlgoPytest — Framework for Testing Algorand Smart Contracts using PyTestAlgoPytestis a Pytest plugin framework which hides away all of the complexity and repetitiveness that comes with testing Algorand Smart Contracts.A lot of boilerplate code is necessary in order to setup a suitable test environment.AlgoPytesttakes care of all that. It handles deploying the smart contract, creating and funding any necessary user accounts and then using those accounts to interact with the smart contract itself. Additionally, each test is a run in a freshly deployed smart contract, facilitating a clean slate which prevents any stateful interference from any previously run tests.Getting StartedThe most relevant information needed for getting off the ground are:Read-The-Docs documentationInstallationSimplified UsageDemosThis project's Read-The-Docs page is especially useful, since it lists and describes all of the available methods and fixtures provided to you byAlgoPytest.InstallationPrerequisitesPython 3 andpipInstall the Algorandsandbox.Installing AlgoPytestpipinstallalgopytest-frameworkSimplified UsageMake sure the sandbox is up and running. Preferably use a local network for your testing such asdev.# Spin up the `dev` network./sandboxupdevSet any necessary environment variables.# The path to your sandbox so that AlgoPytest may interact with the sandboxexportSANDBOX_DIR=/path/to/installation/of/sandbox/# The address in your `sandbox` which was allocated the initial fundsexportINITIAL_FUNDS_ACCOUNT=4BJAN3J32NDMZJWU3DPIPGCPBQIUTXL3UB2LEG5Z3CFPRJZOOZC2GH5DMQList of environment variables recognized byAlgoPytest:documentation.Create aconftest.pyfile in your Pytesttestsdirectory and define a fixture deploying a smart contract as so:# File: conftest.pyimportpytestfromalgopytestimportcreate_app# Load the smart contracts from this project. The path to find these# imports can be set by the environment variable `$PYTHONPATH`.# e.g. `export PYTHONPATH=.../smart-contract-project/assets`fromapproval_programimportapproval_programfromclear_programimportclear_program# NOTE: It is critical to `yield` the `app_id` so that the clean up is properly performed.# The `owner` is an automatically available AlgoPytest defined fixture@pytest.fixturedefsmart_contract_id(owner):withcreate_app(owner,approval_program=diploma_program(),clear_program=clear_program(),local_bytes=1,local_ints=1,global_bytes=1,)asapp_id:yieldapp_idNow, any Pytest tests you write automatically have access to the standardAlgoPytestfixtures as well as your definedsmart_contract_id. Additionally, you can import and utilize the various helper functions that ship with the framework.List of available fixtures:documentationProvided helper functions:documentationA simple test to make sure that the creator of the smart contract can update the application is provided below. It uses theAlgoPytestfixtureowner, your definedsmart_contract_idfixture and the helper functionupdate_app.# File: test_behavior.pydeftest_update_from_owner(owner,smart_contract_id):update_app(owner,smart_contract_id)DemosThisAlgoPytestproject includesdemosof Algorand Smart Contract projects that utilize this package to implement their test suite. These demo projects give examples of how a real-world project may useAlgoPytestfor its testing. They provide greater context for how to integrateAlgoPytestinto your project. The tests and theinitializationcode of the demos may be found within their respectivetestsdirectory. Therein, you will see how the fixtures are used to extensively stress test the Smart Contract code and life-cycle.For example, a semi-involved test in one of the demos,algo-diploma, showcasesAlgoPytestutilizing the power of Pytest fixtures:@pytest.fixturedefowner_in(owner,smart_contract_id):"""Create an ``owner`` fixture that has already opted in to ``smart_contract_id``."""opt_in_app(owner,smart_contract_id)# The test runs hereyieldowner# Clean up by closing out of the applicationclose_out_app(owner,smart_contract_id)@pytest.fixturedefuser1_in(user1,smart_contract_id):"""Create a ``user1`` fixture that has already opted in to ``smart_contract_id``."""opt_in_app(user1,smart_contract_id)# The test runs hereyielduser1# Clean up by closing out of the applicationclose_out_app(user1,smart_contract_id)deftest_issue_diploma(owner_in,user1_in,smart_contract_id):diploma_metadata="Damian Barabonkov :: MIT :: BSc Computer Science and Engineering :: 2020"# The application arguments and account to be passed in to# the smart contract as it expectsapp_args=['issue_diploma',diploma_metadata]accounts=[user1_in.address]# Issue the `diploma_metadata` to the recipient `user1`call_app(owner_in,smart_contract_id,app_args=app_args,accounts=accounts)Original source may be foundhere.Detailed UsageRefer to thePytest Documentation Referencesbelow for more specific explanations of key Pytest topics. These topics are essential to understand in order to useAlgoPytesteffectively.AlgoPytest SetupFirstly, you must follow the Pytest directory structure. Essentially, all tests will be found within atestsdirectory in the root of your project.Before being able to write Pytest tests for your Algorand Smart Contract, you will need to initialize some essential fixtures such as the smart contracts, signatures, and assets to be tested. Utility functions are provided byAlgoPytestwhich deploy these objects and return a reference to be used in a fixture. For a smart contract, this is most easily achieved by creating aconftest.pyfile and yielding the result ofalgopytest.create_appfrom within a fixture. It is critical toyieldrather thanreturnto not interfere with theAlgoPytestfixture clean up sequence.For example:# Sample project file structuresmart-contract-project/
├──assets
│├──approval_program.py
│├──clear_program.py
└──tests├──conftest.py└──test_behavior.py# File: conftest.pyimportpytestfromalgopytestimportcreate_app# Load the smart contracts from this project. The path to find these# imports can be set by the environment variable `$PYTHONPATH`.# e.g. `export PYTHONPATH=.../smart-contract-project/assets`fromapproval_programimportapproval_programfromclear_programimportclear_program# NOTE: It is critical to `yield` the `app_id` so that the clean up is properly performed.# The `owner` is an automatically available AlgoPytest defined fixture@pytest.fixturedefsmart_contract_id(owner):withcreate_app(owner,approval_program=diploma_program(),clear_program=clear_program(),local_bytes=1,local_ints=1,global_bytes=1,)asapp_id:yieldapp_idTheapproval_programandclear_programmust be Python functions which return apyteal.Expr.For example, the simplest clear program in this format is:# File: clear_program.pydefclear_program():"""A clear program that always approves."""returnReturn(Int(1))Writing Pytest TestsTheAlgoPytestpackage is written as a Pytest plugin. This allowsAlgoPytestto automatically register fixtures without you needing to import anything.  You may simply use the fixtures directly in the function signature.These fixtures make testing Algorand Smart Contracts significantly easier for you as the developer. Fixtures such as the user ones:owner,user1,user2, etc. automatically create users with funded balances and cleans them up at the end of the test. Any smart contracts, signatures and assets yielded as fixtures are automatically deployed over the life of the test and then cleaned up. WithoutAlgoPytest, writing a test even as simple as checking whether the owner of an application can update their application requires non-negligible boilerplate code. Now, in order to write this test, all of the necessary boilerplate code is taken care of; you only have to focus only on the testing code at hand and nothing else.# File: test_behavior.pydeftest_update_from_owner(owner,smart_contract_id):"""The `owner` and `smart_contract_id` are AlgoPytest fixtures.This call will raise if there is any error."""update_app(owner,smart_contract_id)Pytest Documentation ReferencesPytest directory structure:documentationPytest fixtures:documentationPytestconftest.py:documentationDev Installationgitclonehttps://github.com/DamianB-BitFlipper/algopytest.gitcdalgopytest
condaenvcreate-fenvironment.yml
pre-commitinstall
pipinstall-e.Please submit a Pull Request for any suggested changes you would like to make.DisclaimerThis package and smart contract(s) in this codebase have NOT been professionally audited. Therefore, they should not be used as a production application.