Skip to main content

Pytest support for cairo-lang and starknet

Project description

pytest-cairo: pytest support for cairo-lang and starknet

Usage

To install:

$ pip install pytest-cairo

The plugin will automatically run any function with a test prefix, from files with a test_ prefix and a .cairo extension.

Examples

Basic tests

Consider the following Starknet contract:

# Contents of contract.cairo
%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin

func calculate_inverse{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
    range_check_ptr,
}(val : felt) -> (res : felt):
    return (1 / val)
end

We could write a basic test for the function calculate_inverse:

# Contents of test_contract.cairo
%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin

from contracts.contract import calculate_inverse

@external
func test_calculate_inverse{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
    range_check_ptr,
}() -> ():
    let (actual) = calculate_inverse(2)
    let expected = 1 / 2
    assert actual = expected
    return ()
end

Additionally we could use a raises attribute to assert that the function fails if we pass val=0:

@external
func test_calculate_inverse_expected_exception{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
    range_check_ptr,
}() -> ():
    with_attr raises("assert_not_zero failed"):
        calculate_inverse(0)
    end
    return ()
end

Deploying contracts

Contracts can be deployed from tests using the deploy_contract helper function. Consider the same contract from the previous example, but extended with a constructor:

# Contents of contracts/contract.cairo
%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin

@constructor
func constructor{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
}(arg : felt):
    return ()
end

func calculate_inverse{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
    range_check_ptr,
}(val : felt) -> (res : felt):
    return (1 / val)
end

We can deploy this contract in our test_contract function and call its methods:

%lang starknet

from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import HashBuiltin

from contracts.interfaces.IContract import IContract

from pytest_cairo.contract_index import contracts
from pytest_cairo.helpers import deploy_contract

@view
func test_contract{
    syscall_ptr : felt*,
    pedersen_ptr : HashBuiltin*,
    range_check_ptr,
}() -> ():

    let (calldata : felt*) = alloc()
    assert calldata[0] = 1  # Value is not relevant
    let (contract_address) = deploy_contract(contracts.contract, 1, calldata)

    let (result) = IContract.calculate_inverse(
        contract_address=contract_address, val=4)

    assert result = 1/4

    return ()
end

The contract_index provides a reference to contracts and is generated automatically by indexing folders that contain .cairo files in the current working directory. In the above example the contract contract.cairo is located in a folder called contracts, so we can reference it as contracts.contract.

Other helper functions

Other available helper functions:

  • set_block_number: sets the current block number
  • set_block_timestamp: sets the current block timestamp
  • set_caller_address: sets the caller address returned by get_caller_address
  • set_contract_address: sets the contract address of the current test contract. This is useful when calling other contracts, since this address will be returned when the other contract calls get_caller_address
  • impersonate: sets both the caller address and the contract address. The former is useful when testing functions directly, the latter when calling functions in other contracts

Helper functions can be imported from pytest_cairo.helpers.

Fixtures

Fixtures work similarly to regular pytest fixtures: functions can be marked as fixtures using the @fixture decorator. Tests can then request a fixture's result by referencing the fixture name as an argument. A basic example:

%lang starknet


@view
@fixture
func my_fixture() -> (fixture_return_value : felt):
    return (fixture_return_value=999)
end


@view
func test_fixture_usage(my_fixture : felt) -> ():

    assert my_fixture = 999

    return ()
end

Note:

  • Fixtures can only return a single value. Use a struct if multiple values have to be returned.
  • Fixtures are module scope, i.e. they are executed once for each test module and the result is cached. If function scope is required, consider calling the function directly.
  • If a fixture is not meant to return any value, the argument in the test function should be annotated as a felt (a default value of 0 will be passed).

Development

To install development dependencies, run:

$ pip install -r requirements-dev.txt

Run tests with:

$ pytest

or:

$ docker-compose run test

To run tests against all supported interpreters (using docker-compose):

$ tox

This assumes tox, docker and docker-compose are installed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest-cairo-0.1.0.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

pytest_cairo-0.1.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file pytest-cairo-0.1.0.tar.gz.

File metadata

  • Download URL: pytest-cairo-0.1.0.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for pytest-cairo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f9a75fe9310791133efc505f2b0598013c2bac610cde1f969b3dac3b7639298f
MD5 2e0d1eab2a3ae67abed540c9ff741655
BLAKE2b-256 40d94c24bc0c21f753b4eedfcbe6744886b91560ab50ebf9d551a17ce5b1f4ca

See more details on using hashes here.

File details

Details for the file pytest_cairo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_cairo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for pytest_cairo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a8ec98d7406c74096f6fbab0f95b7b5e323cac4a596da0781012eda766a9548
MD5 6cf5a0cde67b782305f1a63301872682
BLAKE2b-256 285aeba9a695391b7248fc3bd51b6f52e8fd23360491e3cfdda3ed2d30e3e0aa

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page