我正致力于将单元测试集成到我所在团队的开发过程中,有一些人对此持怀疑态度。有什么好方法可以让团队中持怀疑态度的开发人员相信单元测试的价值?在我的具体情况下,我们将在添加功能或修复错误时添加单元测试。不幸的是,我们的代码库并不容易进行测试。
当前回答
我不知道。很多地方不做单元测试,但是代码质量很好。微软做单元测试,但是比尔·盖茨在他的演示中出现了蓝屏。
其他回答
我最近在我的工作场所经历了完全相同的经历,发现大多数人都知道理论上的好处,但必须具体地向他们推销这些好处,所以下面是我使用的(成功地)要点:
它们在执行负测试(处理意外输入(空指针、越界值等)时节省了时间,因为您可以在单个进程中完成所有这些。 它们在编译时提供关于更改标准的即时反馈。 它们对于测试在正常运行时可能不会公开的内部数据表示非常有用。
还有那个大的…
您可能不需要单元测试,但是当其他人进入并在没有完全理解的情况下修改代码时,它可以捕捉到他们可能犯的许多愚蠢的错误。
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).
我的观点是你必须传达你理解单元测试太少和太多之间的平衡——本质上你已经考虑了问题的两面。如果你能说服你的同事和/或你的管理层,你就获得了信誉,也许就有更好的机会赢得他们的信任。
我曾多次尝试单元测试,我仍然相信,考虑到我的情况,这是值得的。
我开发网站,其中很多逻辑涉及在数据库中创建、检索或更新数据。当我为了单元测试的目的而尝试“模拟”数据库时,它变得非常混乱,似乎有点毫无意义。
当我围绕业务逻辑编写单元测试时,从长远来看它从未真正帮助过我。因为我主要独自从事项目工作,我倾向于直观地知道哪些代码区域可能会受到我所从事的工作的影响,并且我手动测试这些区域。我希望尽可能快地向客户交付解决方案,而单元测试通常看起来是浪费时间。我列出了手动测试,并亲自完成它们,并在执行过程中标记它们。
我可以看到,当一个开发团队在一个项目中工作并互相更新代码时,这可能是有益的,但即使这样,我认为如果开发人员具有高质量,良好的沟通和编写良好的代码通常就足够了。
你想说服谁?工程师还是经理?如果你试图说服你的工程师同事,我认为你最好的办法是迎合他们的愿望,让他们做出高质量的软件。有许多研究表明,它能发现漏洞,如果他们关心做好工作,这对他们来说就足够了。
如果您试图说服管理层,您将很可能不得不做一些成本/收益推理,说明未检测到的缺陷的成本大于编写测试的成本。一定要把不可转化的成本也包括在内,比如失去客户的信心等等。
关于这个话题,我写了一篇很大的博客文章。我发现单靠单元测试是不值得的,而且通常在截止日期临近时就会被削减。
与其从“测试后验证”的角度来讨论单元测试,我们应该看看在实现之前编写规范/测试/想法时所发现的真正价值。
这个简单的想法改变了我写软件的方式,我不会回到“旧的”方式。
测试优先开发如何改变了我的生活
推荐文章
- python中的assertEquals和assertEqual
- 使用Mockito测试抽象类
- 使用Moq模拟单元测试的异步方法
- 你的项目没有引用“. net framework,Version=v4.6.2”框架。在“TargetFrameworks”中添加对“.NETFramework,Version=v4.6.2”的引用
- 使用Moq模拟扩展方法
- 基于输入参数模拟python函数
- 用于单元测试的NUnit vs. Visual Studio 2008测试项目
- 在使用信号时,你不能在'原子'块的末尾执行查询,但只能在单元测试期间执行
- .NET核心单元测试-模拟IOptions<T>
- 如何使用JUnit来测试异步进程
- 获取JUnit 4中当前正在执行的测试的名称
- 2个JUnit Assert类之间的区别
- 覆盖默认的Spring-Boot应用程序。属性设置在Junit测试
- 如何指定摩卡的测试目录?
- Karma vs测试框架Jasmine, Mocha, QUnit