Skip to content

Testing Strategy

shijiashuai edited this page Mar 9, 2026 · 1 revision

测试策略

FastQTools 采用分层测试策略,结合单元测试、集成测试和端到端测试确保代码正确性。


测试金字塔

        /\
       /  \  E2E 测试(少量,验证 CLI 集成)
      /----\
     /      \  集成测试(适量,验证模块协作)
    /--------\
   /          \  单元测试(大量,验证独立逻辑)
  /------------\

目录结构

tests/
├── unit/                     # 单元测试(GTest)
│   ├── common/               #   通用工具测试
│   ├── config/               #   配置模块测试
│   ├── error/                #   错误处理测试
│   ├── io/                   #   I/O 模块测试
│   └── statistics/           #   统计模块测试
├── integration/              # 集成测试
│   └── test_pipeline_integration.cpp
├── e2e/                      # 端到端测试
│   ├── test_cli.sh           #   Shell E2E
│   └── test_advanced_cli.py  #   Python E2E
├── utils/                    # 测试工具库
│   ├── test_helpers.h        #   临时文件/合成数据/文件比较
│   └── fixture_loader.h      #   测试数据加载
└── cmake_package_consumer/   # CMake 包集成测试

运行测试

# 所有测试
./scripts/core/test

# 仅单元测试
./scripts/core/test --type unit

# 仅集成测试
./scripts/core/test --type integration

# 过滤特定测试
./scripts/core/test --filter "*timer*"

# 重复执行(检测 flaky tests)
./scripts/core/test --repeat 5

# 详细输出
./scripts/core/test --verbose

# 覆盖率报告
./scripts/core/build --coverage --dev
./scripts/core/test --coverage

单元测试

使用 Google Test 框架,通过 TESTTEST_F 宏定义测试用例。

示例

class FastqReaderTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建临时 FASTQ 文件
    }
    void TearDown() override {
        // 清理资源
    }
};

TEST_F(FastqReaderTest, ReadBasic) {
    EXPECT_EQ(records[0].id, "read1");
}

CMake 集成

tests/CMakeLists.txt 提供 add_unit_test 宏,自动链接 GTest 和测试工具库。


集成测试

验证模块间协作,如完整的 filter 流水线:

  • 创建临时 FASTQ 输入文件
  • 配置 pipeline(predicates + mutators)
  • 执行 pipeline->run()
  • 验证输出文件内容和统计结果

端到端测试

Shell E2E (test_cli.sh)

直接调用 FastQTools 可执行文件,验证:

  • --help 输出可用命令
  • filter --help / stat --help 显示选项
  • --quiet 抑制 banner
  • filter / stat 命令功能正确
  • 退出码正确

使用 mktemp -d + trap 确保临时资源自动清理。

Python E2E (test_advanced_cli.py)

更复杂的场景测试,使用 Python subprocess 调用可执行文件。


测试工具库

tests/utils/ 提供两个核心工具类,编译为 test_utils 静态库。

FixtureLoader

// 加载预定义测试数据
auto content = FixtureLoader::loadTextFile("sample.fastq");
auto lines = FixtureLoader::loadLines("expected_output.txt");

TestHelpers

// 创建临时文件/目录
auto tmpFile = TestHelpers::createTempFile(content, ".fastq");
auto tmpDir = TestHelpers::createTempDir();

// 生成合成数据
auto records = TestHelpers::generateFastQRecords(1000, 150);
auto dna = TestHelpers::generateRandomDNA(150);

// 文件比较
bool same = TestHelpers::compareFiles(file1, file2);

// 清理
TestHelpers::cleanup();

覆盖率

# 构建 + 测试 + 报告
./scripts/core/build --coverage --dev
./scripts/core/test -b build/clang-debug
./scripts/tools/coverage-report

产出:

  • HTML 报告: coverage_report/html/index.html
  • XML 报告: coverage_report/coverage.xml

阈值配置

编辑 config/coverage/thresholds.json

{
  "line_coverage": { "minimum": 70, "target": 80 },
  "function_coverage": { "minimum": 80, "target": 90 }
}

编写新测试指南

  1. 使用工具库: 通过 TestHelpers 创建临时文件,避免手动管理
  2. 资源清理: 在 TearDown()cleanup() 中释放资源
  3. 独立性: 每个测试使用独立临时目录,避免跨测试副作用
  4. 边界用例: 重点测试空输入、大文件、非法格式等边界情况
  5. 性能测试: 在 Release 模式下运行,使用 Timer 类计时

常见测试问题排查

现象 原因 解决
Fixture 文件找不到 工作目录不正确 使用 FixtureLoader::getFixturePath 智能查找
CI 上随机失败 并发竞争 确保每个测试使用独立临时目录
find_package(GTest) 失败 依赖未安装 运行 conan install
覆盖率工具缺失 lcov 未安装 sudo apt install lcov

相关页面

FastQTools v3.1.0

🚀 快速上手

🏗️ 架构与设计

🔧 构建与部署

🧪 质量工程

📖 规范与参考

🔗 外部链接

Clone this wiki locally