#integration-tests #testing #chain #contracts #module #cosmwasm #sei

sei-integration-tests

为Sei链合约提供集成测试的自定义模块

4次发布

0.4.11 2024年4月25日
0.4.10 2023年2月23日
0.4.9 2022年12月8日
0.4.7 2022年10月18日

68#contracts

Download history 6/week @ 2024-04-28 1/week @ 2024-06-30

230 每月下载量

Apache-2.0

52KB
997

集成测试

通用设置

示例测试在 sei_cosmwasm_integration_tests.rs 中提供。测试使用 setup_test(),该函数利用 cw_multi_test 实例化 cosmwasm 合约的包装版本,例如,sei_tester,该版本位于此仓库下的 contracts/sei_tester

典型的集成测试将从以下内容开始

let mut app = mock_app(init_default_balances, vec![]);
let sei_tester_addr = setup_test(&mut app);

随后是相关的 Msg 以执行或 Query 以运行。

要执行 MsgToExecute,您可以使用 execute()execute_multi()

app
.execute_multi(
    addr_to_use,
    vec![CosmosMsg::Custom(SeiMsg::MsgToExecute {
        ...
    })],
)
.unwrap();

要查询 MsgToQuery,您可以使用 query_wasm_smart()

app
.wrap()
.query_wasm_smart(
    contract_addr,
    &QueryMsg::MsgToQuery {
        ...
    },
)

模块功能在链级别进行模拟,每个模块的更多详细信息如下。

交易模块

您可以通过以下方式与模拟的交易模块进行交互

消息

  • PlaceOrders(orders, funds, contract_address):为 contract_address 放置相应的 orders。每个订单遵循 Order 结构,并具有一个 order_id
  • CancelOrders(order_ids, contract_address):取消 contract_address 的特定 order_ids

查询

  • GetOrders(contract_address, account):返回特定账户的 orders
  • GetOrderById(contract_address, price_denom, asset_denom, id):根据 idprice_denom,以及 asset_denom 返回特定的 order
  • OrderSimulation(contract_address, order):返回针对给定 contract_address 的现有已放置订单的 order 模拟。

示例

  • 以下是一个示例,其中您创建一个订单并调用 PlaceOrders(),然后调用 GetOrders()

首先下单

let mut orders: Vec<Order> = Vec::new();
let mut funds = Vec::<Coin>::new();
let contract_addr = "example_contract".to_string();

// Make order1
let price = Decimal::raw(100);
let quantity = Decimal::raw(1000);
let price_denom = "USDC".to_string();
let asset_denom = "ATOM".to_string();
let order_type = OrderType::Market;
let position_direction = PositionDirection::Long;
let data = "".to_string();
let status_description = "order1".to_string();

let order1: Order = Order {
    price: price,
    quantity: quantity,
    price_denom: price_denom.clone(),
    asset_denom: asset_denom.clone(),
    order_type: order_type,
    position_direction: position_direction,
    data: data,
    status_description: status_description,
};
orders.push(order1);

let res = app
    .execute_multi(
        Addr::unchecked(ADMIN),
        vec![CosmosMsg::Custom(SeiMsg::PlaceOrders {
            orders: orders,
            funds: funds,
            contract_address: Addr::unchecked(&contract_addr),
        })],
    )
    .unwrap();

然后查询

let res: GetOrdersResponse = app
    .wrap()
    .query_wasm_smart(
        sei_tester_addr.clone(),
        &QueryMsg::GetOrders {
            contract_address: contract_addr.to_string(),
            account: sei_tester_addr.to_string(),
        },
    )
    .unwrap();

assert_eq!(res.orders.len(), 1);
assert_eq!(res.orders[0].id, 0);
assert_eq!(res.orders[0].status, OrderStatus::Placed);
...

模拟订单

let res: OrderSimulationResponse = app
    .wrap()
    .query(&QueryRequest::Custom(SeiQueryWrapper {
        route: SeiRoute::Dex,
        query_data: SeiQuery::OrderSimulation {
            contract_address: Addr::unchecked(contract_addr.to_string()),
            order: Order {
                price: Decimal::raw(100),
                quantity: Decimal::raw(10000),
                price_denom: "USDC".to_string(),
                asset_denom: "ATOM".to_string(),
                order_type: OrderType::Limit,
                position_direction: PositionDirection::Short,
                data: "".to_string(),
                status_description: "test_order".to_string(),
                nominal: Decimal::zero(),
            },
        },
    }))
    .unwrap();

Oracle 模块

在使用资产的价格历史初始化应用程序后,应与 Oracle 模块进行交互

let app = mock_app(
    init_default_balances,
    vec![
        DenomOracleExchangeRatePair {
            denom: "uusdc".to_string(),
            oracle_exchange_rate: OracleExchangeRate {
                exchange_rate: Decimal::percent(80),
                last_update: Uint64::zero(),
            },
        },
        DenomOracleExchangeRatePair {
            denom: "usei".to_string(),
            oracle_exchange_rate: OracleExchangeRate {
                exchange_rate: Decimal::percent(70),
                last_update: Uint64::zero(),
            },
        },
        DenomOracleExchangeRatePair {
            denom: "uusdc".to_string(),
            oracle_exchange_rate: OracleExchangeRate {
                exchange_rate: Decimal::percent(90),
                last_update: Uint64::new(1),
            },
        },
    ],
);

查询

  • ExchangeRates():返回所有对的最新的汇率
  • OracleTwaps(lookback_seconds):返回提供的 lookback_seconds 的所有对的价格加权平均值

示例

  • 以下是查询 Oracle 模块的示例

汇率

let res: ExchangeRatesResponse = app
    .wrap()
    .query(&QueryRequest::Custom(SeiQueryWrapper {
        route: SeiRoute::Oracle,
        query_data: SeiQuery::ExchangeRates {},
    }))
    .unwrap();

OracleTwaps

let res: OracleTwapsResponse = app
    .wrap()
    .query(&QueryRequest::Custom(SeiQueryWrapper {
        route: SeiRoute::Oracle,
        query_data: SeiQuery::OracleTwaps {
            lookback_seconds: 10,
        },
    }))
    .unwrap();

依赖项

~0.2–2.6MB
~51K SLoC