关闭。这个问题是opinion-based .它目前不接受答案。
想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.
3年前关闭。
Improve this question
我总是了解到使用单元测试实现最大代码覆盖率是好的。我还听到微软等大公司的开发人员说,他们编写的测试代码行数比可执行代码本身多。
现在,真的很棒吗? 有时这看起来不是完全浪费时间,只会使维护变得更加困难吗?
例如,假设我有一个方法 DisplayBooks()
它从数据库中填充书籍列表。产品要求说,如果店里有一百多本书,就只能展示一百本。
因此,使用 TDD,
BooksLimit()
这将在数据库中保存两百本书,拨打 DisplayBooks()
,然后做一个 Assert.AreEqual(100, DisplayedBooks.Count)
. DisplayBooks()
通过将结果的限制设置为 100 和 好吧,直接进入第三步是不是更容易,永远不要做
BooksLimit()
单元测试?当需求从 100 本书的限制变为 200 本书的限制时,只更改一个字符,而不是更改测试,运行测试以检查是否失败,更改代码并再次运行测试以检查是否成功,这不是更敏捷吗?注意:让我们假设代码是完整记录的。否则,有些人可能会说,他们是对的,做完整的单元测试将有助于理解缺乏文档的代码。事实上,有一个
BooksLimit()
单元测试将非常清楚地显示要显示的最大数量的书籍,并且该最大数量为 100。单步进入非单元测试代码会困难得多,因为可以通过 for (int bookIndex = 0; bookIndex < 100; ...
实现这种限制。或 foreach ... if (count >= 100) break;
.
最佳答案
Well, isn't it much more easier to go directly to the third step, and do never make BooksLimit() unit test at all?
是的...如果您不花任何时间编写测试,那么编写测试的时间就会减少。您的项目总体上可能需要更长的时间,因为您将花费大量时间进行调试,但也许这更容易向您的经理解释?如果是这样的话……找一份新工作吧!测试对于提高您对软件的信心至关重要。
当您拥有大量代码时,单元测试可提供最大值(value)。使用几个类很容易调试一个简单的家庭作业,而无需进行单元测试。一旦你走出去,你正在处理数百万行的代码库 - 你会需要它。您根本无法单步调试您的调试器。你根本无法理解一切。您需要知道您所依赖的类(class)是有效的。您需要知道是否有人说“我只是要对行为进行这种更改……因为我需要它”,但他们忘记了还有 200 种其他用途取决于该行为。单元测试有助于防止这种情况。
关于使维护更加困难:不可能!我不能充分利用它。
如果您是唯一参与过您的项目的人,那么是的,您可能会这么想。但那是疯狂的谈话!尝试在没有单元测试的情况下加快 30k 行项目的速度。尝试在没有单元测试的情况下添加需要对代码进行重大更改的功能。没有信心你没有打破其他工程师所做的隐含假设。对于维护者(或现有项目的新开发人员)来说,单元测试是关键。我依靠单元测试来记录文档、行为、假设,以及在我破坏某些东西(我认为不相关)时告诉我。有时,编写得不好的 API 的测试编写得也很差,而且更改起来可能是一场噩梦,因为这些测试占用了您所有的时间。最终你会想要重构这段代码并修复它,但你的用户也会感谢你——因为它,你的 API 将更容易使用。
关于覆盖率的说明:
对我来说,这不是 100% 的测试覆盖率。 100% 覆盖率并没有找到所有的错误,考虑一个有两个
if
的函数声明:// Will return a number less than or equal to 3
int Bar(bool cond1, bool cond2) {
int b;
if (cond1) {
b++;
} else {
b+=2;
}
if (cond2) {
b+=2;
} else {
b++;
}
}
现在考虑我编写一个测试来测试:
EXPECT_EQ(3, Bar(true, true));
EXPECT_EQ(3, Bar(false, false));
那是 100% 的覆盖率。那也是不符合约定的函数-
Bar(false, true);
失败,因为它返回 4。所以“完全覆盖”不是最终目标。老实说,我会跳过
BooksLimit()
的测试.它返回一个常量,因此可能不值得花时间编写它们(并且应该在编写 DisplayBooks()
时对其进行测试)。当有人决定(错误地)根据货架尺寸计算该限制并且它不再满足我们的要求时,我可能会感到难过。我以前被“不值得测试”烧毁。去年我写了一些代码,我对我的同事说:“这个类主要是数据,不需要测试”。它有一个方法。它有一个错误。它进入生产阶段。它在半夜寻呼我们。我觉得很愚蠢。所以我写了测试。然后我仔细思考了哪些代码构成“不值得测试”。没有多少。所以,是的,你可以跳过一些测试。 100% 的测试覆盖率很棒,但这并不神奇地意味着您的软件是完美的。这一切都归结为面对变化时的信心。
如果我把
class A
, class B
和 class C
在一起,我发现一些不起作用的东西,我想花时间调试所有三个吗?不。我想知道A
和 B
已经满足了他们的契约(Contract)(通过单元测试)和我在 class C
中的新代码可能坏了。所以我对它进行了单元测试。如果我不进行单元测试,我怎么知道它坏了?通过单击一些按钮并尝试新代码?这很好,但还不够。一旦您的程序扩展,就不可能重新运行所有手动测试来检查一切是否正常。这就是为什么单元测试的人通常也会自动运行他们的测试。告诉我“通过”或“失败”,不要告诉我“输出是……”。好的,要去写一些更多的测试......
关于unit-testing - 在进行单元测试时,100% 的代码覆盖率真的是一件好事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3123777/