Files
move_base2/test/move_base2_scenario_test.cpp
2026-07-30 09:24:47 +07:00

116 lines
3.4 KiB
C++

/*********************************************************************
*
* Software License Agreement (BSD License)
*
* move_base2 — chạy toàn bộ kịch bản khai báo trong nav_test_harness/scenarios.
*
* Test này **tự tìm** file trong thư mục kịch bản và sinh một ca gtest cho mỗi file. Đó là điều kiện
* để giữ đúng mục tiêu của Phase 5: thêm một ca test = thêm một file YAML, không sửa C++.
*
* Author: DuongTD
*********************************************************************/
#include <gtest/gtest.h>
#include <algorithm>
#include <string>
#include <vector>
#include <nav_test_harness/scenario.h>
#include <nav_test_harness/scenario_runner.h>
#include "move_base2_scenario_driver.h"
namespace
{
using move_base2::testing::MoveBase2ScenarioDriver;
using nav_test_harness::Scenario;
using nav_test_harness::ScenarioReport;
using nav_test_harness::ScenarioRunner;
/// @brief Thư mục kịch bản, do CMake truyền vào — test không được đoán đường dẫn.
std::string scenarioDir()
{
return MOVE_BASE2_SCENARIO_DIR;
}
std::vector<std::string> scenarioFiles()
{
std::vector<std::string> files = nav_test_harness::listScenarioFiles(scenarioDir());
// Sắp xếp để thứ tự chạy ổn định giữa các máy — thứ tự đọc thư mục không được đảm bảo.
std::sort(files.begin(), files.end());
return files;
}
/// @brief Nạp, chạy, và khẳng định một kịch bản.
void runScenarioFile(const std::string& path)
{
Scenario scenario;
std::string error;
ASSERT_TRUE(nav_test_harness::loadScenarioFile(path, scenario, error))
<< "không nạp được " << path << ": " << error;
MoveBase2ScenarioDriver driver;
ASSERT_TRUE(driver.setup(scenario, error)) << scenario.name << ": setup thất bại: " << error;
ScenarioRunner runner;
const ScenarioReport report = runner.run(scenario, driver);
EXPECT_TRUE(report.passed) << nav_test_harness::formatReport(report);
}
/**
* @class ScenarioFixture
* @brief Một ca gtest cho mỗi file kịch bản, tên ca lấy từ tên file.
*/
class ScenarioFixture : public ::testing::TestWithParam<std::string>
{
};
TEST_P(ScenarioFixture, Passes)
{
runScenarioFile(GetParam());
}
/// @brief Tên ca test lấy từ tên file, bỏ đuôi và ký tự không hợp lệ.
std::string caseName(const ::testing::TestParamInfo<std::string>& info)
{
std::string name = info.param;
const std::size_t slash = name.find_last_of('/');
if (slash != std::string::npos)
{
name = name.substr(slash + 1);
}
const std::size_t dot = name.find_last_of('.');
if (dot != std::string::npos)
{
name = name.substr(0, dot);
}
for (char& c : name)
{
if (!std::isalnum(static_cast<unsigned char>(c)))
{
c = '_';
}
}
return name;
}
INSTANTIATE_TEST_SUITE_P(Scenarios, ScenarioFixture, ::testing::ValuesIn(scenarioFiles()),
caseName);
/// @brief Thư mục kịch bản không được rỗng — rỗng thì mọi ca ở trên biến mất mà suite vẫn xanh.
TEST(ScenarioSuite, ScenarioDirectoryIsNotEmpty)
{
const std::vector<std::string> files = scenarioFiles();
EXPECT_FALSE(files.empty()) << "không tìm thấy kịch bản nào trong " << scenarioDir()
<< " — suite sẽ xanh mà không kiểm gì cả";
}
} // namespace
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}