Unit testing 我如何确保我不';当我重构测试代码时,它不会被破坏吗?
代码在不断进化,并且随着它的发展,如果不修剪,它也会衰退,在这方面有点像花园。修剪意味着重构,以使其满足其不断发展的目的 如果我们有一个良好的单元测试覆盖率,重构会更安全。 测试驱动开发迫使我们首先编写测试代码,然后再编写生产代码。因此,我们无法测试实现,因为没有任何实现。这使得重构生产代码变得更加容易 TDD周期是这样的:编写测试,测试失败,编写生产代码直到测试成功,重构代码 但就我所见,人们重构生产代码,而不是测试代码。随着测试代码的衰退,生产代码将变得陈旧,然后一切都会走下坡路。因此,我认为有必要重构测试代码 问题是:如何确保在重构测试代码时不会破坏它 (我做过一种方法,但我认为可能有更好的方法。) 显然有一本书,我还没读过 还有一个关于这个问题的维基页面,它没有解决方案。嗯 用于JAVA解决方案!我不知道你在用什么语言编程 好的,我刚刚读了Martins的一本书《干净的代码》,这本书认为重构测试代码以保持干净和可读性是一个好主意,而且确实是一个目标。因此,重构和保持代码整洁的雄心壮志是好的,而不是我最初认为的愚蠢想法 但是这不是你要的,所以我们来回答一下吧!p> 我会把你的测试或者最后的测试结果记录下来。 通过一些java注释,您可以执行以下操作:Unit testing 我如何确保我不';当我重构测试代码时,它不会被破坏吗?,unit-testing,refactoring,tdd,Unit Testing,Refactoring,Tdd,代码在不断进化,并且随着它的发展,如果不修剪,它也会衰退,在这方面有点像花园。修剪意味着重构,以使其满足其不断发展的目的 如果我们有一个良好的单元测试覆盖率,重构会更安全。 测试驱动开发迫使我们首先编写测试代码,然后再编写生产代码。因此,我们无法测试实现,因为没有任何实现。这使得重构生产代码变得更加容易 TDD周期是这样的:编写测试,测试失败,编写生产代码直到测试成功,重构代码 但就我所见,人们重构生产代码,而不是测试代码。随着测试代码的衰退,生产代码将变得陈旧,然后一切都会走下坡路。因此,我认
@SuperTestingFramerworkCapable
public class MyFancyTest {
@TestEntry
@Test
public testXEqualsYAfterConstructors(){
@TestElement
//create my object X
@TestElement
//create my object Y
@TheTest
AssertTrue(X.equals(Y));
}
}
无论如何,您还需要一个反射和注释处理超类,用于检查此代码。这可能只是处理过程中的一个额外步骤——编写测试,通过这个超级处理器,然后,如果通过,运行测试。
您的超级处理器将使用模式
MyFancyTest
对于类中的每个成员,它都将使用一个新表-这里(唯一)的表是testXEqualsYAfterConstructors
该表中的每一项都有列,并标有@TestElement注释。它还将有一个列用于@TheTest
我想您可以调用TestElement1、TestElement2等列
然后,一旦设置好了所有这些,它将只保存变量名和注释为@TheTest的行。
所以这张桌子是
testXEqualsYAfterConstructors
TestElement1 | TestElement2 | TheTest
SomeObjectType X | SomeObjectType X | AssertTrue(X.equals(Y));
因此,如果超级处理器发现表存在,那么它可以将代码中已有的表与现在的表进行比较,并针对每个不同的条目发出警报。你可以创建一个新的用户,一个管理员,他可以得到这些改变,可以检查它们,坩埚式的,以及确定与否
然后你可以针对这个问题推销这个解决方案,以1亿美元的价格卖给你的公司,给我20%
干杯
缓慢的一天,这是理性的:
YOUR解决方案在实际的生产代码中使用了大量额外的开销,这是最有害的。您的prod代码不应该绑定到您的测试代码,而且它当然不应该包含特定于测试的随机变量。
我对您提供的代码的下一个建议是,您的框架不会阻止人们破坏测试。毕竟,你可以做到这一点:
@Test
public void equalsIfSameObject()
{
Person expected = createPerson();
Person actual = expected;
check(Person.FEATURE_EQUAL_IF_SAME_OBJECT);
boolean isEqual = actual.equals(expected);
assertThat(isEqual).isTrue();
}
但是如果我在一些测试类的“重构”中更改最后两行代码,那么您的框架将报告成功,但测试不会做任何事情。您确实需要确保发出警报,人们可以看到“差异”
再说一遍,您可能只想使用svn或perforce和crucible来比较和检查这些东西
此外,鉴于您对一个新想法很感兴趣,您还需要阅读有关本地注释的内容:http://stackoverflow.com/questions/3285652/how-can-i-create-an-annotation-processor-that-processes-a-local-variable
嗯,所以你可能需要得到那个家伙的-见上面链接中的最后一条评论-你可能也需要他的自定义java编译器
@免责声明
如果您创建了一家新公司,其代码基本上符合上述要求,我保留在您身价超过3000万美元时获得公司20%股份的权利,在我选择的时候,我认为您不应该更改您的测试代码 为什么?? 在TDD中,为类定义接口。 此接口包含使用特定功能集定义的方法。需求/设计 首先:重构生产代码时,这些要求不会改变。重构意味着:在不改变功能的情况下更改/清理代码。
第二:测试检查某一组功能,该组功能保持不变 结论:重构测试和重构生产代码是两件不同的事情 提示:编写测试时,请编写干净的代码。做一些小测试。它真正测试了一项功能 但是“您的设计因需求的不可预见的变化而改变”。这可能会导致或不会导致界面的更改。
当您的需求改变时,您的测试必须改变。这是无法避免的。
您必须记住,这是一个新的TDD周期。首先测试新功能,然后删除旧功能测试。然后实现新的设计 要使其正常工作,需要进行干净的小测试。 例如:
MethodOne does: changeA and changeB
Don't put this in 1 unit test, but make a test class with 2 unit tests.
Both execute MethodOne, but they check for other results (changeA, changeB).
When the specification of changeA changes, you only need to rewrite 1 unit method.
When MethodOne gets a new specification changeC: Add a unit test.
通过以上示例,您的测试将更加灵活,更容易更改
总结:
- 在重构生产代码时,不要重构测试
- 编写干净敏捷的测试