Я только что провел набор тестов, которые разрабатывал.
Внезапно я начал получать такое резюме:
Summary [ 0.598s] 26/28 tests run: 24 passed, 2 failed, 0 skipped
Точнее, я комментирую достаточное количество тестов, чтобы выполнить «прямое количество» тестов. Это отчет:
Summary [ 0.588s] 27 tests run: 26 passed, 1 failed, 0 skipped
Затем я добавляю этот тест в mod tests:
#[test]
fn do_test() -> Result<()> {
assert!(false);
Ok(())
}
Отчет, который я сейчас получаю:
Summary [ 0.607s] 26/28 tests run: 24 passed, 2 failed, 0 skipped
«2 неудачи»: кажется разумным. Но сложнее: он говорит мне, что на самом деле было пройдено на два теста меньше. Не менее загадочно и то, что внезапно становится «неуверенным», сколько тестов было проведено.
Обновление благодаря комментариям cafce25
Фактически «26/28 тестов» означает «было 28 тестов, но выполнено только 26». Тогда возникает вопрос: почему не запускаются эти два невыполненных теста?
Важным фактом может быть то, что я использую здесь макет ящика , включая директиву #[double].
Может ли кто-нибудь объяснить, что происходит и где в следующей документации это можно объяснить?
Подробнее
Итак, это прогон, показывающий, что в начале прогона объявлено 29 тестов... но сводный отчет в конце показывает, что 4 теста не запускались:
(doc_indexer) D:\...\populate_index_module>cargo nextest run -v
Compiling populate_index_module v0.1.0 (D:\...\populate_index_module)
Finished test [unoptimized + debuginfo] target(s) in 4.33s
Starting 29 tests across 4 binaries
PASS [ 0.031s] populate_index_module auxiliaries::tests::working_up_from_app_execution_cwd_finds_doc_indexer_project_root_dir
PASS [ 0.025s] populate_index_module handling_framework::tests::unreadable_zip_complaint_causes_continue_not_error_propagation::case_1
...
PASS [ 0.088s] populate_index_module::test_1 ldocs_contain_more_than_one_para
FAIL [ 0.232s] populate_index_module text_document::tests::deliberately_failing_test
... отчет об окончании тестового запуска:
PASS [ 0.557s] populate_index_module::test_1 all_text_in_files_is_correctly_caught::case_2
------------
Summary [ 0.599s] 25/29 tests run: 22 passed, 3 failed, 0 skipped
FAIL [ 0.232s] populate_index_module text_document::tests::deliberately_failing_test
FAIL [ 0.266s] populate_index_module::test_1 framework_init_populates_the_index_by_submitting_bulk_inserts
FAIL [ 0.208s] populate_index_module::test_1 test_thing
error: test run failed
Обратите внимание, что в стартовом списке «Старт» на самом деле указано только 17 результатов выше. Есть больше «тотальных» тестов, потому что я использую crate rstest для параметризации тестов.
Странные вещи
У cargo nextest довольно много опций и флагов (попробуйте cargo nextest run --help)... Я нашел один под названием --run-ignored. Итак, запустил это:
(doc_indexer) D:\...\populate_index_module>cargo nextest run --run-ignored all
Результаты довольно странные: иногда он запускает все 29 тестов. Иногда 26/29. Иногда 23/29. Иногда 27/29. ... На этом этапе я перехожу на сайт Github, чтобы в ближайшее время поднять проблему. Но если кто-нибудь может дать какое-либо объяснение, я бы хотел его услышать. Имейте в виду, что ни один из этих тестов не является пропущенным, как я решил: решение не запускать эти тесты полностью принимается следующим.
Хорошо, но тогда возникает вопрос: почему добавление этого фиктивного теста привело к выводу, что существуют тесты «26/28», а не «28»? Я думаю, что есть 28 тестов, просто. nextest пришел к другому выводу. Я пытаюсь понять.
Всего тестов 28, из них было выполнено 26, что означает «выполнено 26/28 тестов», буквально «выполнено 26 из 28 тестов».
Ах... отлично, спасибо. Но тогда... (неизбежно) почему он не запускает эти два невыполненных теста?





На самом деле это было запланированное поведение, поскольку по умолчанию следующий запуск выполняется в отказоустойчивом режиме.
Мне нужно было разобраться с двумя вещами.
Я узнал, что nextest выполняет тесты параллельно. Два моих теста включали создание некоторых файлов и каталогов во временном дереве каталогов перед их очисткой при удалении. В Rust есть функция std::env::temp_dir(), которая возвращает PathBuf, видимо, для такой цели. На самом деле он не создает возвращаемый каталог.
В любом случае я понял, что создание этих файлов и каталогов противоречит друг другу. Я приложил все усилия, чтобы эти два теста не могли перепутать пути к своим временным файлам.
Оказывается, по мнению следующего создателя, это не «лучшая практика». Она рекомендует ящик tempfile , tempfile::tempfile или, еще лучше, свой собственный ящик camino-tempfile. Временные каталоги в последнем являются потокобезопасными.
... но на самом деле причина проблемы была не в этом. Даже при полностью разделенных тестовых ресурсах у меня все равно возникала проблема, особенно когда было много сбоев.
Поэтому она также рекомендует использовать переключатель --no-fail-fast. Похоже, это сработало.
Я не на 100% понимаю, что означает работа без этого переключателя: потому что я думал, что запуск набора тестов в «быстром режиме» будет означать, что первый сбой остановит выполнение. Но в этих незавершенных заездах я обычно получал несколько неудач. Скорее всего, объяснение этому состоит именно в том, что все эти тесты выполняются параллельно, поэтому прекращение выполнения не означает, что вы всегда получаете только один сбой.
... другая загадка заключается в том, что, несмотря на то, что я не работал с этим переключателем «без сбоев быстро», я раньше не сталкивался с этим: может быть, он имеет тенденцию начинать срабатывать после определенного объема тестов? Моя машина имеет количество ядер 8, но я почти уверен, что только после примерно 20 тестов начало происходить невыполнение некоторых тестов.
Все это складывается, хотя из 28 тестов было проведено 26, из них 24 прошли успешно, 2 провалились, всего 26.