测试

测试在任何软件开发过程中都是重要组成部分。Dojo 提供了一个测试框架,允许您为智能合约编写测试。由于 Dojo 使用自定义编译器,因此您需要使用 sozo 来测试您的合约。

在项目目录中,只需:

sozo test

这将搜索项目中的所有测试并运行它们。

编写单元测试

最佳做法是将单元测试包含在与正在编写的组件/系统相同的文件中。

让我们展示一个来自 dojo-starterComponent 测试示例:

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_zerois_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) - 这个函数将用你传入的组件和系统创建一个测试世界。它还将部署该世界并注册组件和系统。