我正致力于将单元测试集成到我所在团队的开发过程中,有一些人对此持怀疑态度。有什么好方法可以让团队中持怀疑态度的开发人员相信单元测试的价值?在我的具体情况下,我们将在添加功能或修复错误时添加单元测试。不幸的是,我们的代码库并不容易进行测试。


当前回答

我曾多次尝试单元测试,我仍然相信,考虑到我的情况,这是值得的。

我开发网站,其中很多逻辑涉及在数据库中创建、检索或更新数据。当我为了单元测试的目的而尝试“模拟”数据库时,它变得非常混乱,似乎有点毫无意义。

当我围绕业务逻辑编写单元测试时,从长远来看它从未真正帮助过我。因为我主要独自从事项目工作,我倾向于直观地知道哪些代码区域可能会受到我所从事的工作的影响,并且我手动测试这些区域。我希望尽可能快地向客户交付解决方案,而单元测试通常看起来是浪费时间。我列出了手动测试,并亲自完成它们,并在执行过程中标记它们。

我可以看到,当一个开发团队在一个项目中工作并互相更新代码时,这可能是有益的,但即使这样,我认为如果开发人员具有高质量,良好的沟通和编写良好的代码通常就足够了。

其他回答

还没有人提到的一件事是,让所有开发人员承诺实际运行和更新任何现有的自动化测试。当您重新进行自动化测试并发现由于新的开发而出现故障时,会失去很多价值并使自动化测试非常痛苦。因为开发人员已经手动测试了代码,所以大多数测试不会指出错误,所以花在更新它们上的时间只是浪费。

说服怀疑者不要破坏其他人在单元测试上所做的工作,对于从测试中获得价值更为重要,而且可能更容易。

每次从存储库更新时,花费数小时更新由于新特性而损坏的测试既没有效率也没有乐趣。

thetalkingwalnut问道: 有什么好方法可以让团队中持怀疑态度的开发人员相信单元测试的价值?

Everyone here is going to pile on lots of reasons out of the blue why unit testing is good. However, I find that often the best way to convince someone of something is to listen to their argument and address it point by point. If you listen and help them verbalize their concerns, you can address each one and perhaps convert them to your point of view (or at the very least, leave them without a leg to stand on). Who knows? Perhaps they will convince you why unit tests aren't appropriate for your situation. Not likely, but possible. Perhaps if you post their arguments against unit tests, we can help identify the counterarguments.

It's important to listen to and understand both sides of the argument. If you try to adopt unit tests too zealously without regard to people's concerns, you'll end up with a religious war (and probably really worthless unit tests). If you adopt it slowly and start by applying it where you will see the most benefit for the least cost, you might be able to demonstrate the value of unit tests and have a better chance of convincing people. I realize this isn't as easy as it sounds - it usually requires some time and careful metrics to craft a convincing argument.

单元测试是一种工具,就像任何其他工具一样,应该以这样一种方式进行应用,即收益(捕捉错误)大于成本(编写它们的工作)。如果它们没有意义,就不要使用它们,记住它们只是你工具库的一部分(例如检查、断言、代码分析器、形式化方法等)。我告诉开发者的是:

They can skip writing a test for a method if they have a good argument why it isn't necessary (e.g. too simple to be worth it or too difficult to be worth it) and how the method will be otherwise verified (e.g. inspection, assertions, formal methods, interactive/integration tests). They need to consider that some verifications like inspections and formal proofs are done at a point in time and then need to be repeated every time the production code changes, whereas unit tests and assertions can be used as regression tests (written once and executed repeatedly thereafter). Sometimes I agree with them, but more often I will debate about whether a method is really too simple or too difficult to unit test. If a developer argues that a method seems too simple to fail, isn't it worth taking the 60 seconds necessary to write up a simple 5-line unit test for it? These 5 lines of code will run every night (you do nightly builds, right?) for the next year or more and will be worth the effort if even just once it happens to catch a problem that may have taken 15 minutes or longer to identify and debug. Besides, writing the easy unit tests drives up the count of unit tests, which makes the developer look good. On the other hand, if a developer argues that a method seems too difficult to unit test (not worth the significant effort required), perhaps that is a good indication that the method needs to be divided up or refactored to test the easy parts. Usually, these are methods that rely on unusual resources like singletons, the current time, or external resources like a database result set. These methods usually need to be refactored into a method that gets the resource (e.g. calls getTime()) and a method that takes the resource as a argument (e.g. takes the timestamp as a parameter). I let them skip testing the method that retrieves the resource and they instead write a unit test for the method that now takes the resource as a argument. Usually, this makes writing the unit test much simpler and therefore worthwhile to write. The developer needs to draw a "line in the sand" in how comprehensive their unit tests should be. Later in development, whenever we find a bug, they should determine if more comprehensive unit tests would have caught the problem. If so and if such bugs crop up repeatedly, they need to move the "line" toward writing more comprehensive unit tests in the future (starting with adding or expanding the unit test for the current bug). They need to find the right balance.

重要的是要认识到单元测试并不是万能的,而且存在太多单元测试这样的事情。在我的工作场所,每当我们做一个经验教训,我不可避免地听到“我们需要写更多的单元测试”。管理层点头表示同意,因为“单元测试”==“好”这句话已经被灌输到他们的头脑中了。

However, we need to understand the impact of "more unit tests". A developer can only write ~N lines of code a week and you need to figure out what percentage of that code should be unit test code vs production code. A lax workplace might have 10% of the code as unit tests and 90% of the code as production code, resulting in product with a lot of (albeit very buggy) features (think MS Word). On the other hand, a strict shop with 90% unit tests and 10% production code will have a rock solid product with very few features (think "vi"). You may never hear reports about the latter product crashing, but that likely has as much to do with the product not selling very well as much as it has to do with the quality of the code.

Worse yet, perhaps the only certainty in software development is that "change is inevitable". Assume the strict shop (90% unit tests/10% production code) creates a product that has exactly 2 features (assuming 5% of production code == 1 feature). If the customer comes along and changes 1 of the features, then that change trashes 50% of the code (45% of unit tests and 5% of the production code). The lax shop (10% unit tests/90% production code) has a product with 18 features, none of which work very well. Their customer completely revamps the requirements for 4 of their features. Even though the change is 4 times as large, only half as much of the code base gets trashed (~25% = ~4.4% unit tests + 20% of production code).

我的观点是你必须传达你理解单元测试太少和太多之间的平衡——本质上你已经考虑了问题的两面。如果你能说服你的同事和/或你的管理层,你就获得了信誉,也许就有更好的机会赢得他们的信任。

单元测试的好处之一是可预测性。

在单元测试之前,我可以非常准确地预测编写代码所需的时间,但无法预测调试所需的时间。

现在,因为我可以计划将要编写什么测试,所以我知道编码需要多长时间,并且在编码结束时,系统已经调试好了!这为开发过程带来了可预见性,消除了许多压力,但仍然保留了所有的乐趣!!

单元测试非常值得最初的投资。自从几年前开始使用单元测试以来,我发现了一些真正的好处:

回归测试消除了恐惧 对代码进行更改(什么都没有 就像看到代码的温暖光芒 每次有变化,要么工作,要么爆发 了) 以下的可执行代码示例 其他团队成员(包括你自己) 6个月的时间…) 无情的重构——这是令人难以置信的回报,试试吧!

代码片段可以极大地帮助减少创建测试的开销。创建能够在几秒钟内创建类大纲和相关单元测试fixture的代码片段并不困难。

如果您现有的代码库本身不适合单元测试,并且它已经处于生产环境中,那么通过试图重构所有代码以使其具有单元可测试性,您可能会产生比解决更多的问题。

您最好将精力放在改进集成测试上。有很多代码在没有单元测试的情况下编写起来更简单,如果QA可以根据需求文档验证功能,那么就完成了。船。

在我的脑海中,最经典的例子就是嵌入到GridView的ASPX页面中的SqlDataReader。代码都在ASPX文件中。SQL位于存储过程中。你做什么单元测试?如果页面做了它应该做的事情,那么是否真的应该将其重新设计成几个层,以便实现自动化?