1 stable release
new 1.0.0 | Mar 24, 2025 |
---|
#975 in #plugin
31KB
270 lines
Test framework for Picodata plugin
Описание
Picotest - это фреймворк для тестирования плагинов, созданных в окружении pike
.
Для использования Picotest требуется выполнить следующие действия:
- Установить pike:
cargo install picodata-pike
- Добавить зависимости
picotest
иrstest
вCargo.toml
плагина:
cargo add picotest --git https://github.com/picodata/picotest.git
cargo add rstest
Совместимость с Picodata
Picotest поддерживает версии Picodata, начиная с 25.1.1 и выше.
Интеграционное тестирование
Макрос #[picotest]
используется для написания интеграционных тестов и может применяться как к функциям, так и к модулям.
Атрибуты макроса #[picotest]
Макрос #[picotest]
поддерживает следующие аргументы:
- path - путь до директории плагина. Значение по умолчанию:
$(pwd)
. - timeout - длительность ожидания после развертывания кластера и перед запуском тестов. Указывается в секундах. Значение по умолчанию: 0 секунд.
Использование #[picotest]
на функциях
При использовании макроса на функциях, picotest
будет создавать кластер при каждом запуске очередного теста и удалять кластер по завершению теста.
use picotest::picotest;
use rstest::rstest;
#[picotest]
fn test_foo_bar() {
assert_eq!("foo bar", "foo bar");
}
Использование #[picotest]
на модулях
При использовании макроса на модуле picotest
автоматически пометит все функции, названия которых начинаются с test_
, как rstest
-функции. Кластер будет создан один раз и удален после выполнения всех тестов в модуле.
use picotest::picotest;
#[picotest]
mod test_mod {
fn test_foo() {
assert_eq!("foo", "foo");
}
fn test_bar() {
assert_eq!("bar", "bar");
}
}
Совместимость с rstest
Макрос #[picotest]
является оберткой над rstest
, поэтому поддерживает использование fixture
.
use picotest::picotest;
#[picotest]
mod test_mod {
#[fixture]
fn foo() -> String {
"foo".to_string()
}
#[fixture]
fn bar() -> String {
"bar".to_string()
}
fn test_foo(foo: String) {
assert_eq!(foo, "foo".to_string());
}
fn test_bar(bar: String) {
assert_eq!(bar, "bar".to_string());
}
fn test_foo_bar(foo: String, bar: String) {
assert_ne!(foo, bar);
}
}
Запуск тестов
Запустите тесты с использованием переменной RUST_TEST_THREADS=1
:
RUST_TEST_THREADS=1 cargo test
наличие переменной RUST_TEST_THREADS=1
необходимо только в том случае, если вы используете несколько модулей или функций с макросом #[picotest]
.
Пользовательские хуки
Picotest поддерживает работу с хуками before_all
и after_all
Для использования добавьте в свой Cargo.toml
файл:
[dev-dependencies]
test-env-helpers = "0.2.2"
Пример:
use picotest::picotest;
use test_env_helpers::{after_all, before_all};
#[picotest]
#[before_all]
#[after_all]
mod test_mod {
fn before_all() {
todo!()
}
fn after_all() {
todo!()
}
#[fixture]
fn foo() -> String {
"foo".to_string()
}
#[fixture]
fn bar() -> String {
"bar".to_string()
}
fn test_foo(foo: String) {
assert_eq!(foo, "foo".to_string());
}
fn test_bar(bar: String) {
assert_eq!(bar, "bar".to_string());
}
fn test_foo_bar(foo: String, bar: String) {
assert_ne!(foo, bar);
}
}
Создание кластера вручную
Picotest позволяет создавать и удалять кластер без использования макроса #[picotest]
.
use rstest::rstest;
#[rstest]
fn test_without_picotest_macro() {
let cluster = picotest::run_cluster(".", 0);
assert!(cluster.is_ok());
assert!(cluster.is_ok_and(|cluster| cluster.path == "."));
}
Ограничения
- Параллельное исполнение тестов не поддерживается. Тесты должны запускаться последовательно, т.е. с переменной окружения
RUST_TEST_THREADS=1
(issue #2)
Модульное тестирование
Макрос #[picotest_unit]
используется для написания юнит-тестов для плагинов, созданных с помощью утилиты pike
.
#[picotest_unit]
fn test_my_http_query() {
let http_client = fibreq::ClientBuilder::new().build();
let http_request = http_client.get("http://example.com").unwrap();
let http_response = http_request.send().unwrap();
assert!(http_response.status() == http_types::StatusCode::Ok);
}
Запуск тестов
Тесты запускаются через интерфейс cargo test с использованием переменной RUST_TEST_THREADS=1
:
RUST_TEST_THREADS=1 cargo test
или опцией --test-threads=1
:
cargo test -- --test-threads=1
Ограничения
#[picotest_unit]
не может использоваться в модуле под#[cfg(test)]
.
Пример неверного использования макроса:
#[cfg(test)]
mod tests {
#[picotest_unit]
fn test_declared_under_test_cfg() {}
}
Пример верного использования макроса:
mod tests {
#[picotest_unit]
fn test_is_NOT_declared_under_test_cfg() {}
}
По скольку каждый юнит-тест компилируется и линкуется в динамическую библиотеку плагина (см. Структура плагина), он не должен быть задан в конфигурации, отличной от debug. В противном случае при сборке тестов они будут проигнорированы компилятором.
#[picotest_unit]
не может использоваться совместно с другими атрибутами.
Все атрибуты используемые совместно с макросом будут отброшены.
В примере ниже #[should_panic]
будет отброшен в процессе компиляции.
#[should_panic]
#[picotest_unit]
fn test_will_ignore_should_panic_attribute() {}
- Параллельное исполнение тестов не поддерживается. Тесты должны запускаться последовательно, т.е. с переменной окружения
RUST_TEST_THREADS=1
(issue #2)
Dependencies
~14–25MB
~398K SLoC