РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
816 of 1245 menu

Параллельные тесты

Параллельные тесты - это режим выполнения тестов, который используется в Rust по умолчанию. Когда вы запускаете cargo test, фреймворк тестирования автоматически распределяет тесты по нескольким потокам и выполняет их одновременно. Это значительно ускоряет процесс проверки, особенно при большом количестве тестов. Параллельный запуск не требует специального синтаксиса - достаточно объявить тестовые функции с атрибутом #[test], и они будут выполняться параллельно без дополнительной настройки.

Стоит учитывать, что при параллельном выполнении тестов порядок их запуска не гарантирован. Если тесты используют общие ресурсы (файлы, переменные окружения, базы данных), это может привести к конфликтам. Для управления параллелизмом используется флаг --test-threads, который позволяет задать количество потоков или вовсе отключить параллельный режим.

Синтаксис

// Параллельный запуск по умолчанию cargo test // Указать количество потоков cargo test -- --test-threads=4 // Отключить параллелизм (один поток) cargo test -- --test-threads=1

Пример

Давайте создадим модуль с тестами, которые будут выполняться параллельно:

fn add(a: i32, b: i32) -> i32 { a + b } fn multiply(a: i32, b: i32) -> i32 { a * b } #[cfg(test)] mod tests { use super::*; #[test] fn test_add() { let res = add(2, 3); assert_eq!(res, 5); } #[test] fn test_multiply() { let res = multiply(4, 5); assert_eq!(res, 20); } #[test] fn test_add_negative() { let res = add(-2, -3); assert_eq!(res, -5); } } fn main() { println!("{}", add(2, 3)); println!("{}", multiply(4, 5)); }

При запуске cargo test все три теста (test_add, test_multiply, test_add_negative) будут выполнены параллельно в разных потоках. Результат выполнения:

running 3 tests test tests::test_add ... ok test tests::test_multiply ... ok test tests::test_add_negative ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Пример

Давайте запустим тесты в одном потоке, чтобы убедиться в последовательном выполнении:

fn compute(x: i32) -> i32 { x * x } #[cfg(test)] mod tests { use super::*; #[test] fn test_one() { let res = compute(1); assert_eq!(res, 1); } #[test] fn test_two() { let res = compute(2); assert_eq!(res, 4); } #[test] fn test_three() { let res = compute(3); assert_eq!(res, 9); } } fn main() { println!("{}", compute(5)); }

Команда для запуска в одном потоке:

cargo test -- --test-threads=1

Результат выполнения кода:

running 3 tests test tests::test_one ... ok test tests::test_two ... ok test tests::test_three ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Пример

Давайте рассмотрим пример, где параллельный запуск может вызвать проблему с общими данными. Такой тест следует запускать последовательно:

use std::sync::Mutex; static COUNTER: Mutex<i32> = Mutex::new(0); fn increment() -> i32 { let mut val = COUNTER.lock().unwrap(); *val += 1; *val } #[cfg(test)] mod tests { use super::*; #[test] fn test_increment_first() { let res = increment(); assert!(res >= 1); } #[test] fn test_increment_second() { let res = increment(); assert!(res >= 1); } } fn main() { println!("{}", increment()); }

Если такие тесты зависят от порядка выполнения, их нужно запускать с флагом --test-threads=1, чтобы избежать состояния гонки. Результат последовательного выполнения:

running 2 tests test tests::test_increment_first ... ok test tests::test_increment_second ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Смотрите также

  • атрибут test,
    который помечает функцию как тестовую
  • команда cargo test,
    которая запускает все тесты в проекте
  • флаг filter,
    который позволяет запускать только выбранные тесты
  • опция show-output,
    которая показывает вывод println в тестах
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить