Привет Starknet Ninjas, сегодня мы рассмотрим процесс тестирования каирских контрактов. Тестирование является важным аспектом процесса разработки, поскольку оно позволяет нам оценить функциональность нашего кода и выявить возможные ошибки.

Цель этой статьи — выделить ключевые компоненты и атрибуты, используемые при тестировании нашего кода Cairo.

  1. Определение тестового модуля и функции
#[cfg(test)]
mod testing{
    #[test]
    #[available_gas(num)]
    fn it_works() {}
}

Важно указать атрибут #[cfg(test)], так компилятор узнает, что модуль является тестом. Для каждого теста укажите атрибуты #[тест] и #[доступный_газ(номер)], где переменная num может принимать произвольное значение.

2. Проверка результатов с помощью функции assert.

Функция assert, предоставленная Cairo, полезна, когда вы хотите убедиться, что какое-то условие в тесте оценивается как true.

#contract 

mod Sum{
#[external]

fn add(a:u8, b:u8) -> u8{
 a + b
}
}

#[cfg(test)]
mod sum_test{
//import the Sum contract into the test
 use super::Sum;

fn test_sum_of_two_num(){
let c = Sum::add(3,5);

assert(c = 4, 'result is not 4');
}

}

3. Проверьте наличие паники с атрибутом [should_panic]).

В дополнение к проверке возвращаемых значений важно убедиться, что код обрабатывает ошибки так, как мы ожидаем.

Мы делаем это, добавляя атрибут should_panic в нашу тестовую функцию. Тест проходит, если код внутри функции паникует; тест проваливается, если код внутри функции не паникует.

use array::ArrayTrait;

#[derive(Copy, Drop)]
struct Guess {
    value: u64,
}

trait GuessTrait {
    fn new(value: u64) -> Guess;
}

impl GuessImpl of GuessTrait {
    fn new(value: u64) -> Guess {
        if value < 1_u64 | value > 100 {
            let mut data = ArrayTrait::new();
            data.append('Guess must be >= 1 and <= 100');
            panic(data);
        }
        Guess { value }
    }
}

#[cfg(test)]
mod tests {
    use super::Guess;
    use super::GuessTrait;

    #[test]
    #[should_panic]
    fn greater_than_100() {
        GuessTrait::new(200_u64);
    }
}

Вышеупомянутый тест проходит, поскольку он паникует, потому что входные данные больше, чем граница, указанная в реализации.

4. Игнорирование некоторых тестовых случаев с атрибутом #[ignore]).

Иногда выполнение нескольких определенных тестов может занимать очень много времени, поэтому вы можете исключить их.

#[cfg(test)]
mod tests {
    #[test]
    fn test_sum() {
        let result = 2 + 2;
        assert(result == 4, 'result is not 4');
    }

    #[test]
    #[ignore]
    fn expensive_test() {
        // code that takes an hour to run
    }
}

После #[test] мы добавляем строку #[ignore] к тесту, который хотим исключить. Теперь, когда мы запускаем наши тесты, test_sum запускает функцию, но дорогая_тест игнорируется.

Для подробного изучения тестирования мы рекомендуем вам углубиться в кодовую базу, представленную ниже. Он включает в себя реализацию контракта ERC20 вместе с соответствующим тестом. Вы можете найти кодовую базу. Кроме того, мы рекомендуем изучить документацию Cairo-book для дальнейшего понимания методологий тестирования.

Функция assert, предоставленная Cairo, полезна, когда вы хотите убедиться, что какое-то условие в тесте оценивается как true.