Тестирование
Сообщество Rust обычно пишет модульные тесты в модуле, размещённом в том же исходном файле, что и тестируемый код. Это рассматривалось ранее в курсе и выглядит так:
#![allow(unused)]
fn main() {
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#[cfg(test)]
mod tests {
#[test]
fn my_test() {
todo!()
}
}
}
В Chromium мы помещаем модульные тесты в отдельный исходный файл, и для Rust продолжаем следовать этой практике — так тесты всегда легко найти, и не приходится дважды пересобирать файлы .rs (в конфигурации test).
Для тестирования кода Rust в Chromium есть следующие варианты:
- Нативные тесты Rust (то есть
#[test]). Вне//third_party/rustих не рекомендуется использовать. - Тесты
gtest, написанные на C++, которые проверяют Rust через вызовы FFI. Этого достаточно, когда код Rust — это тонкий слой FFI, а существующие модульные тесты уже покрывают функциональность. - Тесты
gtest, написанные на Rust, которые используют тестируемый крейт через его публичный API (при необходимости черезpub mod for_testing { ... }). Этому посвящено несколько следующих слайдов.
Упомяните, что нативные тесты Rust для сторонних крейтов в итоге должны запускаться ботами Chromium. (Такое тестирование нужно редко — только после добавления или обновления сторонних крейтов.)
Несколько примеров помогут проиллюстрировать, когда следует использовать gtest на C++, а когда gtest на Rust:
-
В QR очень мало функциональности в собственном слое Rust (это просто тонкий клей FFI), поэтому для тестирования и реализации на C++, и реализации на Rust используются существующие модульные тесты C++ (тесты параметризуются так, чтобы включать или отключать Rust через
ScopedFeatureList). -
Гипотетическая или разрабатываемая интеграция PNG может требовать безопасных по памяти реализаций преобразований пикселей, которые предоставляет
libpng, но которых нет в крейтеpng, например RGBA => BGRA или гамма-коррекция. Такая функциональность может выиграть от отдельных тестов, написанных на Rust.