6Working Effectively with Legacy Code

自动化

自动化测试

自动化框架Mock对象测试基础设施持续集成

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第6章:自动化(Automation)

一、导读

1.1 本章学习目标

第6章讲解如何通过自动化来管理遗留代码——自动化测试、自动化构建、持续集成。

本章的核心学习目标包括:

  • 理解自动化测试框架的选择
  • 掌握 Mock 对象的使用
  • 学会搭建测试基础设施
  • 理解持续集成在遗留代码项目中的作用

1.2 为什么本章如此重要

遗留代码项目的自动化往往面临特殊挑战——依赖复杂、环境不稳定、测试运行缓慢。本章教你如何在这些约束下建立有效的自动化体系。

1.3 核心问题引导

遗留代码项目应该选择什么测试框架?

Mock 对象在遗留代码测试中扮演什么角色?

如何处理缓慢的测试套件?

持续集成如何帮助遗留代码项目?


二、核心概念详解

2.1 测试框架选择

遗留代码测试框架考虑因素:
1. 与现有构建系统的兼容性
2. 对旧版 Java/框架的支持
3. 运行速度和资源消耗
4. 团队熟悉程度

推荐策略:
- 优先使用项目已有的测试框架
- 新代码使用现代框架
- 逐步迁移,不强制统一

2.2 Mock 对象

java
// 使用 Mockito 创建 mock
@Test
void testOrderProcessing() {
    // 创建 mock
    Repository mockRepo = mock(Repository.class);
    Notifier mockNotifier = mock(Notifier.class);
    
    // 设置预期行为
    when(mockRepo.findById("123")).thenReturn(new Order("123"));
    
    // 使用 mock
    OrderService service = new OrderService(mockRepo, mockNotifier);
    service.process("123");
    
    // 验证交互
    verify(mockRepo).save(any(Order.class));
    verify(mockNotifier).notify(any(), eq("Order processed"));
}

2.3 测试基础设施

遗留代码测试基础设施:
1. 测试数据库:独立的测试数据库实例
2. 测试配置:与生产环境隔离的配置
3. 测试数据:可重复的测试数据集
4. 测试工具:辅助测试的工具类
5. CI 环境:自动化的构建和测试环境

2.4 持续集成

yaml
# CI 配置示例
stages:
  - compile
  - unit-test
  - integration-test
  - quality-check

unit-test:
  script:
    - mvn test -pl legacy-module    # 遗留模块测试
    - mvn test -pl new-module       # 新模块测试

quality-check:
  script:
    - mvn sonar:sonar               # 代码质量分析
    - mvn dependency:check          # 依赖检查

三、实战案例

3.1 案例一:搭建遗留代码的测试环境

java
// 测试基类:提供公共的测试基础设施
public abstract class LegacyTestBase {
    protected TestDatabase db;
    protected TestClock clock;
    
    @Before
    public void setUp() {
        db = new TestDatabase();
        db.reset();    // 每个测试前重置数据库
        clock = new TestClock();
        clock.setFixedTime(LocalDateTime.of(2024, 1, 1, 12, 0));
    }
    
    @After
    public void tearDown() {
        db.cleanup();
    }
    
    // 辅助方法
    protected User createTestUser(String name) {
        return db.createUser(name, "test@example.com");
    }
}

// 具体测试类
public class OrderServiceTest extends LegacyTestBase {
    @Test
    void testPlaceOrder() {
        User user = createTestUser("Alice");
        OrderService service = new OrderService(db, clock);
        
        Order order = service.placeOrder(user, "Product A");
        
        assertNotNull(order.getId());
        assertEquals("Product A", order.getProduct());
    }
}

四、本章小结

测试框架:优先兼容现有系统,逐步引入现代框架。

Mock 对象:隔离依赖,控制测试环境。

测试基础设施:测试数据库、配置、数据、工具。

持续集成:自动化构建、测试、质量检查。


五、思考与练习

为一个遗留项目设计测试基础设施方案。

Mock 对象过度使用有什么风险?

如何处理运行时间超过1小时的测试套件?


6/7自动化
0%