6

我目前正在与另一名合作学生一起完成一个即将完成的项目的合作项目。由于该项目已从合作社传递到合作社,因此沿途采取了不良做法,并将测试留到最后。我决定写单元测试来在测试时学习新东西。

但是,我正在开发一个 3 层、紧密耦合的应用程序,它似乎无法以当前形式进行单元测试。我不想通过一夜之间重构无法识别的代码来甩掉其他对这些概念一无所知的合作学生。那么我应该采取哪些步骤来慢慢地将代码拉向单元可测试性呢?我应该先实现一个工厂模式,然后让其他学生熟悉它,然后再继续前进吗?

如果我的知识有缺陷并且不应该有任何问题,我深表歉意。我是新手:)

4

4 回答 4

7

Michael Feathers有效地使用遗留代码

很难知道实现工厂模式是否有任何好处,这取决于代码在做什么:)

于 2009-06-19T13:26:53.263 回答
2

Michael Feathers 的《有效使用遗留代码》(如果您订阅了 Safari,也可以使用)是完成任务的绝佳资源。作者将遗留代码定义为没有单元测试的代码,并且他给出了许多保守技术的实际演练——这是必要的,因为你在没有安全网的情况下工作——以便对代码进行测试。目录:

  • 第一部分:I 变化的机制
    • 第 1 章更改软件
      • 改变软件的四个理由
      • 风险变化
    • 第 2 章处理反馈
      • 什么是单元测试?
      • 更高级别的测试
      • 测试覆盖物
      • 遗留代码更改算法
    • 第 3 章传感与分离
      • 伪造合作者
    • 第 4 章接缝模型
      • 一大段文字
      • 接缝
      • 接缝类型
    • 第 5 章工具
      • 自动重构工具
      • 模拟对象
      • 单元测试工具
      • 通用测试工具
  • Part: II 更改软件
    • 第 6 章 我没有多少时间,我必须改变它
      • 发芽法
      • 新芽类
      • 包裹方法
      • 包装类
      • 概括
    • 第 7 章 做出改变需要永远
      • 理解
      • 时差
      • 打破依赖关系
      • 概括
    • 第 8 章如何添加功能?
      • 测试驱动开发 (TDD)
      • 差异编程
      • 概括
    • 第 9 章我不能把这个类放到测试工具中
      • 刺激性参数案例
      • 隐藏依赖的案例
      • 构建 Blob 的案例
      • 恼人的全球依赖案例
      • 可怕的包含依赖关系的案例
      • 洋葱参数的案例
      • 别名参数的情况
    • 第 10 章我无法在测试工具中运行此方法
      • 隐藏方法的案例
      • “有用”语言特征的案例
      • 无法检测到的副作用案例
    • 第 11 章。我需要做出改变。我应该测试什么方法?
      • 关于效果的推理
      • 向前推理
      • 效果传播
      • 效果推理工具
      • 从效果分析中学习
      • 简化效果草图
    • 第 12 章我需要在一个领域进行许多更改。我必须打破所有涉及的类的依赖关系吗?
      • 拦截点
      • 用夹点判断设计
      • 夹点陷阱
    • 第 13 章 我需要做出改变,但我不知道要编写什么测试来编写表征测试
      • 表征类
      • 有针对性的测试
      • 编写表征测试的启发式
    • 第 14 章对库的依赖正在扼杀我
    • 第 15 章 我的应用程序都是 API 调用
    • 第 16 章 我对代码的理解还不够好,无法更改它
      • 笔记/素描
      • 列表标记
      • 从头重构
      • 删除未使用的代码
    • 第 17 章 我的应用程序没有结构
      • 讲述系统的故事
      • 裸CRC
      • 对话审查
    • 第 18 章 我的测试代码有问题
      • 类命名约定
      • 测试地点
    • 第 19 章我的项目不是面向对象的。如何进行安全更改?
      • 一个简单的案例
      • 硬壳
      • 添加新行为
      • 利用面向对象
      • 都是面向对象的
    • 第 20 章 这堂课太大了,我不想让它变得更大
      • 看到责任
      • 其他技术
      • 向前进
      • 提取类后
    • 第 21 章我在各处更改相同的代码
      • 第一步
    • 第 22 章 我需要更改一个怪物方法,但我不能为它编写测试
      • 各种怪物
      • 使用自动重构支持来对付怪物
      • 手动重构挑战
      • 战略
    • 第 23 章 我怎么知道我没有破坏任何东西?
      • 超感知编辑
      • 单目标编辑
      • 保留签名
      • 依赖编译器
    • 第 24 章我们感到不知所措。它不会变得更好
  • Part: III 依赖打破技术
    • 第 25 章 依赖破坏技术
      • 适应参数
      • 突破方法对象
      • 定义完成
      • 封装全局引用
      • 暴露静态方法
      • 提取和覆盖调用
      • 提取和覆盖工厂方法
      • 提取和覆盖 Getter
      • 提取实施者
      • 提取接口
      • 引入实例委托者
      • 介绍静态二传手
      • 链接替换
      • 参数化构造函数
      • 参数化方法
      • 原始化参数
      • 上拉功能
      • 下推依赖
      • 用函数指针替换函数
      • 用 Getter 替换全局引用
      • 子类和覆盖方法
      • 取代实例变量
      • 模板重定义
      • 文本重新定义
  • 附录:重构
    • 提取方法
于 2009-06-19T13:44:06.300 回答
1

在项目的中途开始新的开发实践是非常困难的。过去,当我从事从一开始就没有进行单元测试的项目时,一个好的方法是制定“新代码必须有单元测试”的规则,但不要对单元测试施加压力为旧代码编写。

当然,当项目的结构不适合可测试性时,即使这样也很困难。

我最好的建议是采取小步骤。

首先创建没有测试的单元测试程序集(或项目或其他)。然后找到一个定义和分离得相当好的代码的小区域,并为该区域编写一些单元测试。让你的 co-coder 也来看看,并开始获得一些“最佳实践”,比如每次签入任何代码时运行单元测试(如果可能,自动运行)。

一旦你有这个工作,你可以慢慢开始添加更多。

关键是慢慢来。就像我说的,从一开始就让旧代码免于测试更容易。一旦您的团队掌握了单元测试的想法并且在编写它们方面变得更好,您总是可以稍后再返回它。

于 2009-06-19T13:23:42.880 回答
1

围绕代码中的主要功能编写一系列黑盒测试怎么样?由于您提到它是一个 ASP.NET 项目,因此您可以使用WaitNSelenium等框架来自动化 Web 浏览器。这为您提供了一组基线功能,无论代码更改多少,该功能都应保持不变。

一旦你有足够数量的测试来测试你项目的高级功能,我就会开始深入研究代码,正如 Simon P. Stevens 提到的,慢慢地工作。获取Refactor的(免费!)副本!对于 Visual Basic,因此您将能够自动执行一些基本的重构,例如提取方法。只需将较大的代码块拆分为更小、更可测试的块,您就可以在不更改任何功能的情况下大幅提高可测试性。

于 2009-06-19T13:39:01.257 回答