对旧版 ASP.NET Webforms 应用程序进行单元测试
我继承了一个遗留的 Web 应用程序,其中没有单元测试。 我想补充一些,但不知道从哪里开始。 我应该将它们添加到旧代码中吗? 或者只是未来的新代码? 如果该代码与遗留代码交互怎么办? 你有什么建议?
I've inherited a legacy web application that has no unit tests in it. I'd like to add some, but am at a loss of where to start. Should I add them to old code? Or just new code going forward? What if that code interacts with legacy code? What would you suggest?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
首先,我建议对未来的所有更改进行单元测试,我认为大多数人都会同意这是回归的好主意。
但是,对于现有代码,这是您需要查看您愿意或允许在产品中引入多少风险的情况之一。 问题是,当您开始对现有代码库进行单元测试时,您很快就会意识到许多重构和设计细化的机会。
相信我,如果你是优秀设计的坚持者,但你没有被授权做出彻底的重构决定,那么当你尝试为遗留部分编写测试时,你最终只会心碎——是的,如果没有现有的测试套件,则需要重构。 如果您不允许对生产应用程序进行高影响的更改,那么您最终将实现我们称之为“垃圾适配器模式”的东西。 祝你好运!
First, I would recommend unit testing all changes going forward, I think most everyone would agree this is a good idea for regression.
However, for existing code, this is one of those situations where you need to look at how much risk you're willing or allowed to introduce into the product. The problem is that when you start to unit test an existing code base, you're going to soon realize many opportunities for refactoring and design refinement.
Take it from me, if you're a stickler for good design, but you haven't been empowered to make drastic refactoring descisions, you're only going to end up with a broken heart when you try to write tests for the legacy parts -- and yes, if it doesn't have existing test suite its going to NEED refactoring. If you're not allowed to make high impact changes to the production application, you're going to end up implementing something we like to call the "garbage adapter pattern". Good luck!
我建议获取一份有效使用旧代码。
我们在一个学习小组中读完了这本书。 这很痛苦,但很有用。
主题包括:
您可以在 < a href="http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf" rel="nofollow noreferrer">http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf
I would suggest getting a copy of Working Effectively with Legacy Code.
We went through this book in a study group. it was painful, but useful.
Topics include:
You can see a short into to this at http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf
遗留应用程序是分层的吗?
如果是这样,首先将单元测试添加到后端/业务层
如果没有,则将单元测试添加到未来的新代码中,并且当发现错误时(用于回归测试)
如果您有时间/雄心对整个事情进行单元测试(最终),启动一个功能列表(首先是关键功能)并为这些功能添加单元测试,一次几个
is the legacy app layered?
if so, add units tests to the back-end/business layer first
if not, add unit tests to new code going forward, and when bugs are discovered (for regression testing)
if you have the time/ambition to unit test the whole thing (eventually), start a list of features (critical ones first) and add unit tests for those, a few at a time
如果它是您继承的代码,那么您可能必须开始阅读它并了解它的作用和不作用。 我建议您编写单元测试来反映您对代码库不断增长的理解。 最终,您将建立有关遗留应用程序的知识体系,其中指出“这些函数是通过这些测试的函数”,而不是“这些函数是具有这些实现的函数”。 然后你将有更多的自由和信心来做出改变而不破坏事物。
If it's code you inherited, presumably you have to start reading it and understanding what it does and does not do. I suggest you write unit tests that reflect your growing understanding of the code base. Eventually you will build up a body of knowledge about your legacy application that says 'these functions are the functions that pass those tests' as opposed to 'these functions are the functions that have those implementations'. Then you will have more freedom and confidence to make changes without breaking things.
我不会仅仅为了进行测试而编写任何测试。 我只会在发现错误或添加新功能时编写测试。 然后编写测试来封装您需要更改/实现的代码,以定义它当前的功能。 如果出现错误,请编写测试以证明错误已得到修复。 对于新代码,它应该做什么。 现在去实施修复/新功能。 如果您发现自己很想触碰测试“框”之外的代码,请编写更多测试来框住该区域(或重新考虑您想要进行的更改)。 根据需要逐步引入新的测试,以最大限度地提高您在测试中的投资。 编写测试来证明工作代码可以工作似乎毫无意义,除非它被证明被破坏了。
I wouldn't write any tests just for the sake of having tests. I would only write tests when a bug is discovered or you are adding new functionality. Then write tests to box the code that you need to change/implement to define what it currently does. In the case of a bug, write the test to prove the bug has been fixed. In the case of new code, what it is supposed to do. Now go and implement the fix/new feature. If you find that you're tempted to touch code outside your test "box" -- write some more tests to box that area (or reconsider the changes you want to make). Introduce new tests gradually as needed to maximize the investment you are making in the tests. Writing tests to prove that working code works seems pointless until it's shown to be broken.
如果网络应用程序没有经过单元测试,那么它也可能不容易进行单元测试。 将其置于单元测试下可能存在风险,因为您没有[单元]测试,是的,先有鸡还是先有蛋。 而且这需要时间并且不会给应用程序带来太多价值。
我的目标是使用 Selenium 编写端到端自动测试,Watir、HtmlUnit 或 HttpUnit、YMMV 用于应用程序的遗留部分。 这些测试(特征测试)将确定您当前的应用程序行为,就像单元测试一样,但是从外部,让您能够进行更改并能够检测到不需要的副作用。
为新代码以及更改遗留代码时编写单元测试,无论是为了修复问题还是添加新功能。
If the web app is not unit-tested, it's probably also not easily unit-testable. Putting it under unit-tests can be risky as you do not have [Unit] tests, yes, chicken and eggs. Moreover this takes time and doesn't bring much value to the application.
I'd aim to write end-to-end automatic test with Selenium, Watir, HtmlUnit, or HttpUnit, YMMV for the legacy part of your application. These tests (characterization tests) will pin down your current application behavior, like unit tests do, but from the outside, allowing you to make changes with the ability to detect undesired side effects.
Write unit tests for the new code, and when changing the legacy code, whether it is for fixing a problem, or adding new capabilities.
针对应用程序的已知“痛点”编写测试。 经常损坏或通常风险较高的代码是一个很好的起点,因为它有助于在该领域建立前线防御,并使团队了解该应用程序中单元测试的范围。
每次针对应用程序打开缺陷时,请尝试编写单元测试来暴露此行为。 它会在修复后通知您,并希望防止将来再次引入该问题。
此外,查找需要重构的代码。 任何重构工作都应该以创建单元测试为前提。 这有助于确保它在您进行更改之前和之后都可以正常工作。 重构一开始可能会很困难,因为存在“连锁反应”的风险,其中一次破坏可能会以意想不到的方式对整个应用程序造成严重破坏。
Write tests at the known "pain points" of the application. Code that breaks often or is generally of higher risk is a good place to start, as it helps to build a front-line of defense in this area and exposes the team to the scope of the unit tests in that application.
Every time a defect is opened against the application, going forward, try to write a unit test to expose this behavior. It will let you know when it is fixed and hopefully prevent it from being introduced again in the future.
Additionally, look for code that needs to be refactored. Any refactoring effort should be prefaced by the creation of unit tests. This helps to ensure that it was working both before and after you have made your changes. Refactoring can be tough in the beginning, because of the risk of the "ripple effect", where one breakage can wreak havoc through the entire application in unexpected fashions.