【发布时间】:2020-02-17 05:27:53
【问题描述】:
我的任务是在没有测试的情况下对代码库进行小幅更改,并且我第一次尝试使用 TDD 来实施更改,但我正在努力解决测试实施和行为之间的差异。我正在开发的系统呈现用户可配置的列表项。用户可以通过由 XML DAO 控制的全局偏好系统来更改列表项的行为:
class Preference {
boolean getX();
boolean getY();
}
我的任务是向这个 DAO 添加 Z,我已经实现了这个更改并添加了测试以确保值按照我的预期进行序列化和反序列化。
然后,以下列表项类应接收 Z 值:
class ListItemA extends ListItem {
private boolean Z;
ListItemA(boolean Z){
this.Z = Z;
}
OpenAction getOpenAction(){
OpenAction action = new OpenAction();
if(Z){
action.addValue('Filter', true);
}
return action;
}
}
我还编写了测试以确保返回的操作反映 Z 字段。这两者之间的联系是我苦苦挣扎的地方,渲染列表项时会调用一个控制器类:
class Controller {
private Preference preference;
Controller(Preference preference){
this.preference = preference;
}
List<ListItem> getListItems(State state){
// a bunch condition statements concerning the state
List<ListItem> items = new List();
if(state.items.includes('ListItemA')){
ListItemA item = new ListItemA();
}
return items;
}
}
当实例化 ListItemA 时,我现在需要从首选项字段传递 getZ(),但 TDD 说如果没有首先失败的测试,我无法进行此更改。
我可以模拟首选项、模拟状态、生成列表,然后编写相同的测试以确保 OpenAction 反映 Z 的值,但这看起来好像我正在测试实现并编写一个脆弱的测试。此外,ListItem 测试中会有很多重复的测试代码,因为它们正在做出相同的断言。另一种选择是废弃 ListItem 测试并在 Controller 测试中添加所有断言,但这似乎我正在测试另一个系统。
我的问题是:
如何在测试实现和编写过于宽泛的测试之间划清界限?
您将如何测试这种情况?
我是否过度测试?
我正在通过 TDD 对这个遗留系统进行更改,根据我刚刚完成的“在遗留代码中有效工作”一书,上述方法是否与我在处理类似系统时应该执行的过程相匹配这?
是否有什么好的文章、书籍或资源可供我阅读以进一步了解该领域?
如何在没有测试文化的工作场所测试遗留系统?我没有自己的旧系统可以开发,如何获得经验?
【问题讨论】:
标签: java unit-testing testing tdd legacy-code