测试
测试在任何软件开发过程中都是重要组成部分。Dojo 提供了一个测试框架,允许您为智能合约编写测试。由于 Dojo 使用自定义编译器,因此您需要使用 sozo
来测试您的合约。
在项目目录中,只需:
sozo test
这将搜索项目中的所有测试并运行它们。
编写单元测试
最佳做法是将单元测试包含在与正在编写的组件/系统相同的文件中。
让我们展示一个来自 dojo-starter 的 Component
测试示例:
components.cairo
...rest of code
#[cfg(test)]
mod tests {
use debug::PrintTrait;
use super::{Position, PositionTrait};
#[test]
#[available_gas(100000)]
fn test_position_is_zero() {
let player = starknet::contract_address_const::<0x0>();
assert(PositionTrait::is_zero(Position { player, x: 0, y: 0 }), 'not zero');
}
#[test]
#[available_gas(100000)]
fn test_position_is_equal() {
let player = starknet::contract_address_const::<0x0>();
let position = Position { player, x: 420, y: 0 };
position.print();
assert(PositionTrait::is_equal(position, Position { player, x: 420, y: 0 }), 'not equal');
}
}
在本测试中,我们将测试 Position
组件的 is_zero
和 is_equal
函数。测试组件的所有函数是一种很好的实践。
编写集成测试
集成测试是测试整个系统的 e2e 测试。您可以在项目根目录下创建一个 tests
目录,为您的世界编写集成测试。然后为要编写的每个集成测试创建一个文件。
这是来自 dojo-starter: 的示例:
systems.cairo
#[cfg(test)]
mod tests {
use core::traits::Into;
use array::ArrayTrait;
use dojo::world::IWorldDispatcherTrait;
use dojo::test_utils::spawn_test_world;
use dojo_examples::components::position;
use dojo_examples::components::Position;
use dojo_examples::components::moves;
use dojo_examples::components::Moves;
use dojo_examples::systems::spawn;
use dojo_examples::systems::move;
#[test]
#[available_gas(30000000)]
fn test_move() {
let caller = starknet::contract_address_const::<0x0>();
// components
let mut components = array::ArrayTrait::new();
components.append(position::TEST_CLASS_HASH);
components.append(moves::TEST_CLASS_HASH);
// systems
let mut systems = array::ArrayTrait::new();
systems.append(spawn::TEST_CLASS_HASH);
systems.append(move::TEST_CLASS_HASH);
// deploy executor, world and register components/systems
let world = spawn_test_world(components, systems);
let spawn_call_data = array::ArrayTrait::new();
world.execute('spawn', spawn_call_data);
let mut move_calldata = array::ArrayTrait::new();
move_calldata.append(move::Direction::Right(()).into());
world.execute('move', move_calldata);
let mut keys = array::ArrayTrait::new();
keys.append(caller.into());
let moves = world.entity('Moves', keys.span(), 0, dojo::SerdeLen::<Moves>::len());
assert(*moves[0] == 9, 'moves is wrong');
let new_position = world
.entity('Position', keys.span(), 0, dojo::SerdeLen::<Position>::len());
assert(*new_position[0] == 11, 'position x is wrong');
assert(*new_position[1] == 10, 'position y is wrong');
}
}
有用的 Dojo 测试函数
spawn_test_world(components, systems)
- 这个函数将用你传入的组件和系统创建一个测试世界。它还将部署该世界并注册组件和系统。