测试驱动开发 测试前移

by Ronauli Silva

通过罗纳利·席尔瓦(Ronauli Silva)

I first read about test driven development (TDD) in some technical reviews blog, but I barely read it (or thought about it). Why would people write tests first when they already knew the logic?

我首先在一些技术评论博客中阅读了有关测试驱动开发(TDD)的信息,但几乎没有阅读(或考虑过)。 人们为什么已经知道逻辑就为什么要先写测试

So what was this all about? Writing tests first, incrementally building the logic, and doing it in iterations. The funny thing is, when you give two programmers five minutes to code a simple fibonacci sequence and ask one to do TDD, by the end of the 5 minutes, the programmer doing TDD may say “I have test for it!” But they won’t have finished the code. On the other hand, the other one will have finished the entire fibonacci sequence and will have optimized it.

那到底是什么呢? 首先编写测试,逐步构建逻辑,然后进行迭代。 有趣的是,当您给两个程序员五分钟的时间来编写一个简单的斐波那契序列并要求一个人进行TDD时,在5分钟结束时,执行TDD的程序员可能会说:“我已经对此进行了测试!” 但是他们不会完成代码。 另一方面,另一个将完成整个斐波那契数列并对其进行优化。

为什么要使用TDD? 单元测试不够好吗? (Why use TDD? Aren’t unit tests good enough?)

At the end of last year, I finally met TDD face to face. In a three-month bootcamp session, we were forced to always do things with TDD. I was already struggling enough, and so my brain always rebelled when it came time to write the tests.

去年年底,我终于与TDD面对面了。 在为期三个月的训练营会议中,我们被迫始终使用TDD进行操作。 我已经很挣扎了,所以到了编写测试的时候,我的大脑总是反叛。

Why should we write tests first when I can directly code the logic, my brain asked? Can’t we just write them later? After all functionality is finished?

我的大脑问,当我可以直接编写逻辑代码时,为什么要先编写测试? 我们不能稍后再写吗? 所有功能完成之后?

Let me give you a quick overview of TDD in a nutshell.

让我简要概述一下TDD。

Let’s say I’m creating a fibonacci function. I might ask, what is the simplest assertion on a fibonacci? => Returns 1 if input is 1.

假设我要创建一个斐波那契函数。 我可能会问,关于斐波那契的最简单的断言是什么? =>如果输入为1,则返回1。

What is the simplest solution for that assertion? The simplest solution, I mean it.

该断言最简单的解决方案是什么? 最简单的解决方案 我是认真的。

Now, next move. What is next simplest assertion for fibonacci?=> Returns 2 for inputs = 3

现在,下一步。 斐波那契的下一个最简单的断言是什么?=>输入2返回2 = 3

Again, let’s fix this very quickly. Just return it and add some branching.

同样,让我们​​快速修复此问题。 只需返回它并添加一些分支即可。

Move to another expectation. Aim for a bigger number. Do it iteratively, incrementally.

移到另一个期望。 争取更大的数量。 逐步进行迭代。

On and on it goes, until you get the nice solution for your fibonacci function. If you want to practice more, try adding memoization during the process (and don’t forget—with TDD).

不断进行下去,直到您获得斐波那契函数的理想解决方案为止。 如果您想练习更多,请尝试在此过程中添加备忘(不要忘了-使用TDD)。

Did you notice what we did there? The baby steps, your assertion, and how we define the solution? Your thought process got separated into these five critical points:

您注意到我们在那里做了什么吗? 婴儿的脚步,您的主张以及我们如何定义解决方案? 您的思考过程分为以下五个关键点:

Simple & Incremental Design — You have to think about what is the simplest thing a particular function could do, and what’s coming next. The fibonacci example describes this point perfectly.

简单和增量设计-您必须考虑某个特定功能可以做的最简单的事情,以及下一步的工作。 斐波那契示例很好地描述了这一点。

Assertion — What is your expectation of that function? And how do you describe that expectation? Will other people understand it quickly?Some test libraries provide you with a test description feature. That string is the only verbose thing that explains what your code is doing.

断言-您对该功能有什么期望? 您如何描述这种期望? 其他人会很快理解吗?某些测试库为您提供测试描述功能。 该字符串是解释您的代码正在执行的唯一冗长的操作。

Make sure it’s a good explanation, or you’ll get a call on your holiday because your unreadable test case is failing, and no one knows why.

确保这是一个很好的解释,否则您的假期会打来电话,因为您无法读取的测试用例失败了,没人知道原因。

Testable Design — How should you design it so it can be testable? Take a look at these two snippets below.

可测试的设计 -应该如何设计它以便可测试? 看看下面的这两个片段。

The first one:

第一个:

By doing TDD, since you write the test first, you have to make sure that your code is testable. You can see from the example that you don’t even test your fibonacci function. Instead, you test the side-effect of that fibonacci logic in your code, which invokes the console.log function.

通过执行TDD,由于您首先编写了测试,因此必须确保您的代码是可测试的 从示例中可以看到,您甚至没有测试斐波那契函数。 而是在代码中测试该斐波那契逻辑的副作用 ,该逻辑调用console.log函数。

The other thing is, you never know which one is failing, the console.log() or your fibonacci block when you refactor it. In this way, TDD leads us to increase modularity in our code.

另一件事是,当您重构它时,您永远都不知道哪个是失败的console.log()或您的fibonacci块。 通过这种方式,TDD使我们提高了代码的模块化程度。

Now, let’s look at second snippet.

现在,让我们看看第二个片段。

In the second example, we can see that we test the particular fibonacci function, not the other function that spikes on it. We are confident that the function works perfectly under the conditions that we state. We are sure that if the other function invokes our fibonacci and fails, it is not from our code.

在第二个示例中,我们可以看到我们测试了特定的斐波那契函数,而不是其他尖峰函数。 我们相信该功能在我们声明的条件下可以完美运行。 我们确定如果另一个函数调用我们的斐波那契并失败,则不是来自我们的代码。

Negatives and Corner Cases — what do you expect when something’s not right: is it invoked with null? Does it throw an exception? How should it be handled? What could possibly happen in the code? What could be the strangest and weirdest thing that could happen in this loop? What test can catch that?

否定情况和极端情况 –如果出现不正确的情况,您会期望什么:使用null调用吗? 它会引发异常吗? 应该如何处理? 代码中可能会发生什么? 在此循环中可能发生的最奇怪和最奇怪的事情是什么? 有什么考验可以抓住?

Boundaries — Should you expect that from your function? Are you sure it’s not another class’s responsibility?

边界 -您是否应该从职能中获得期望? 您确定这不是另一堂课的责任吗?

我对TDD的问题 (My issues with TDD)

Yes, it is slow indeed. Sometimes, your time is doubled since you’re writing both tests and logic at the same time. This makes how you use your keyboard important (typing speed, better shortcut usage, and so on).

是的,确实很慢。 有时,由于您同时编写测试和逻辑,因此您的时间增加了一倍。 这使您使用键盘的方式变得很重要(键入速度,更好的快捷方式用法等)。

And even worse —when the requirements change—you have to refactor or delete and rewrite test code you worked hard on. Which means that tests code is code you write that is more likely to be deleted in the future. And you are doing it, iteratively. DELETES. CODES. REWRITES. AGAIN. IN A LOOP!

更糟糕的是,当需求发生变化时,您必须重构或删除并重写您一直在努力的测试代码。 这意味着测试代码是您编写的代码,将来很有可能被删除。 而您正在迭代地这样做。 删除。 编码。 重写。 再次。 一圈!

Think about it. Why would you write code that is more likely to be deleted?

想一想。 您为什么要编写更有可能被删除的代码?

“Nope, that’s enough of this TDD thing. I’ll do it when I find a strong reason why I should spend time writing code I’m likely to delete”, I said to myself.

“不,这个TDD够了。 我对自己说:“当我发现有充分的理由为什么我应该花时间编写可能会删除的代码时,我会做的。”

And that was right before I unconsciously started digging my own grave.

那是在我不知不觉开始挖掘自己的坟墓之前。

为什么我改变主意 (Why I changed my mind)

The enlightenment came about two months later, when I was assigned to a group that did not implement TDD well at all.

大约两个月后,当我被分配到一个完全没有很好地执行TDD的小组时,就得到了启迪。

I mean, they implemented TDD, but they left the tests broken. They didn’t bother to fix those failing test cases (which often broke because the requirements had changed). And this happened because of the most cliche reason in the world: they didn’t have time. They had to make deadlines.

我的意思是,他们实施了TDD, 但是却使测试失败了。 他们没有费心去修复那些失败的测试用例(由于需求发生了变化,测试用例经常失败)。 发生这种情况是由于世界上最陈词滥调的原因:他们没有时间。 他们必须规定最后期限。

After looking at the situation, I mumbled “Look, see! This TDD doesn’t work in the production world!” It made me question many things: is this TDD worth fighting for? Is TDD worth the time? Does it even deliver any business value?

看完情况后,我喃喃地说:“看,看! 该TDD在生产环境中不起作用!” 这让我提出了很多问题:这个TDD是否值得争取? TDD值得吗? 它甚至提供任何商业价值吗?

After a while, I realized that the problems were growing exponentially, tasks were getting delayed, chaos was reigning, and the developer experience was getting really bad — all because they implemented TDD poorly and halfheartedly. It was even worse than not writing tests at all.

过了一会儿,我意识到问题正在成倍增长,任务被延迟,混乱不断,开发人员的经验真的变得很糟糕-所有这些都是因为他们对TDD的执行不力而全力以赴。 比根本不编写测试还要糟糕。

Here are some of the issues it caused:

这是它引起的一些问题:

  • When I added a new feature or refactored things, I didn’t know whether that code was failing or not because the test was already failing.当我添加新功能或重构事物时,我不知道该代码是否失败,因为测试已经失败。
  • We were forced to have high threshold on code coverage. And make no mistake, programmers are smart and sneaky. They write tests with no expectations, like smoke tests. And that was the only test they had on that particular logic. It was like, we only knew it was failing after everything was on fire. How dangerous.

    我们被迫对代码覆盖率设置高阈值。 毫无疑问,程序员是聪明而狡猾的 。 他们编写没有期望的测试,例如冒烟测试。 那是他们对该特定逻辑进行的唯一测试。 就像,我们只知道一切都着火之后才失败。 多么危险

  • We used CI/CD for deployment. And we always deployed even though it was failing, which was scary: You never knew whether your production itself was failing, or if it was because you didn’t fix the tests.我们使用CI / CD进行部署。 而且,即使失败了,我们也总是进行部署,这很可怕:您永远不知道自己的生产是否失败,或者是因为您没有修复测试。
  • After production, we ended up fixing strange and completely out-of-mind bugs. We had never even thought of those strange conditions before. (Ever find a situation when something in a try-catch block is failing but not throwing an exception?)生产后,我们最终修复了奇怪且完全过时的错误。 我们以前从未想过那些奇怪的情况。 (是否找到了try-catch块中的某项失败但没有引发异常的情况?)

Oh, the horror!

哦,恐怖!

After analyzing the situation, doing it in iterations, and reflecting on it, I realized that TDD is actually a golden nugget. If done right, it can make us better developers.

在分析了情况,反复进行并反思之后,我意识到TDD实际上是一个金块。 如果做得对,它可以使我们成为更好的开发人员。

为什么我现在爱TDD (Why I now love TDD)

使用TDD,您的bug更少 (With TDD, you have fewer bugs)

You’ll hardly miss things that you can catch with your tests.

您几乎不会错过可以通过测试掌握的东西

When you get a requirement, you write a test for it first. Then you run the test, and see if it fails first. When you add the logic, you see if it passes.

收到需求后,您首先要为其编写测试。 然后运行测试,然后查看它是否首先失败。 添加逻辑时,您可以查看它是否通过。

Seeing it fail is important, because you know what broke your code. In the long run, this practice ensures that all lines in your code are well-tested.

看到它失败很重要,因为您知道什么破坏了您的代码 。 从长远来看,这种做法可以确保代码中的所有行都经过良好测试。

TDD节省了很多时间(将来) (TDD saves you lot of time (in the future))

CI/CD relies heavily on tests. If you write the wrong tests (or too few tests) you already wasted five hours to find what errors it couldn’t catch. If you write good tests, and spend just five more minutes writing deeper and more complete conditions of your code, you’ll save time debugging it in the future.

CI / CD严重依赖测试。 如果您编写了错误的测试(或测试太少),您已经浪费了五个小时来查找无法捕获的错误。 如果您编写了良好的测试,并且只花了五分钟以上的时间来编写更深入,更完整的代码条件,则可以节省将来调试它的时间。

TDD处理编码的人为方面 (TDD deals with the human aspects of coding)

The main ones being negligence and forgetfulness. If you write all the logic directly, by the end of, say, line 190, you may forget why you multiplied a variable by 100 at line 19.

主要是疏忽和健忘。 如果直接编写所有逻辑,例如在第190行的末尾,您可能会忘记为什么在第19行将变量乘以100。

But, by doing it incrementally and stating the assertion of our code, we gradually build our understanding. This makes us understand the code and its behaviors better.

但是,通过逐步执行并声明代码声明,我们逐渐建立了理解。 这使我们更好地理解了代码及其行为。

As a bonus, we have sort of living and functional documentation of our code. You can see which test is failing if you delete the previous line, and you instantly know why.

值得一提的是,我们还提供了一些有效的代码文档。 如果删除上一行,您可以看到哪个测试失败,并且您立即知道原因。

TDD可帮助您集中精力 (TDD helps you focus)

Programmers tend to write too much code, or write code that does too much. Or they try to plan for conditions that never exist. Often, when my team practiced pair pairing, I discovered that TDD allowed us to write less code compared to other teams that didn’t do TDD. While coding, we were focused on getting the test case passed — nothing less, nothing more.

程序员倾向于写太多的代码,或者写太多的代码。 或者他们试图为不存在的情况做计划。 通常,当我的团队练习配对时,我发现与没有TDD的其他团队相比,TDD允许我们编写更少的代码。 在编码时,我们专注于通过测试用例-没什么,仅此而已。

TDD也有益于您的大脑 (TDD also benefits your brain)

You have proof of your code’s readiness for production, even before deploying it. You don’t have to worry about things you already tested for before. You don’t have to brag to your project manager about how project is going, because you can show them that the tests are passing!

您甚至可以在部署代码之前就证明您的代码已经可以投入生产。 您不必担心之前已经测试过的东西。 您不必向项目经理吹嘘项目的进展情况,因为您可以向他们证明测试已通过!

However, TDD is not always your silver bullet. It takes time. You have to set up the project — such as the environment, mocks, and stubs — even before you start doing anything.

但是,TDD并不总是 你的银弹。 这需要时间。 您必须在开始做任何事情之前就设置项目(例如环境,模拟和存根)。

But remember, time spent on writing tests is not wasted time. It’s the time you invest now to save your time later. It’s the investment you make on the system you build, as you build code on top of more code. And you want to make its foundation as solid as possible. TDD gives you that.

但是请记住,花在编写测试上的时间不会浪费时间。 现在是时候进行投资,以节省以后的时间了。 当您在更多代码之上构建代码时,这就是您对所构建系统的投资。 您想使其基础尽可能牢固。 TDD为您提供。

In the end, it could cost you a fortune if you don’t do TDD. It may take time, but it is good for you and your team in the long run.

最后,如果您进行TDD,可能会花费您一笔巨款。 这可能会花费一些时间,但从长远来看,这对您和您的团队都是有好处的。

翻译自: https://www.freecodecamp.org/news/test-driven-development-i-hated-it-now-i-cant-live-without-it-4a10b7ce7ed6/

测试驱动开发 测试前移

测试驱动开发 测试前移_我如何以及为什么认为测试驱动开发值得我花时间相关推荐

  1. 测试驱动开发 测试前移_测试驱动开发简介

    测试驱动开发 测试前移 I've been programming for five years and, honestly, I have avoided test-driven developme ...

  2. 测试驱动开发 测试前移_测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做...

    测试驱动开发 测试前移 by Navdeep Singh 通过Navdeep Singh 测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做 (Test-driven developmen ...

  3. 测试驱动开发 测试前移_测试驱动陷阱,第2部分

    测试驱动开发 测试前移 单元测试中单元的故事 在本文的上半部分 ,您可能会看到一些不好但很受欢迎的测试示例. 但是我不是一个专业的批评家(也被称为"巨魔"或"仇恨者&qu ...

  4. 测试驱动开发 测试前移_测试驱动开发–双赢策略

    测试驱动开发 测试前移 敏捷从业人员谈论测试驱动开发 (TDD),所以许多关心代码质量和可操作性的开发人员也是如此. 我曾几何时,不久前设法阅读了有关TDD的文章. 据我了解,TDD的关键是: 编写测 ...

  5. 测试驱动开发 测试前移_测试驱动开发:它是什么,什么不是。

    测试驱动开发 测试前移 by Andrea Koutifaris 由Andrea Koutifaris Test driven development has become popular over ...

  6. 测试驱动开发 测试前移_为什么测试驱动的开发有用?

    测试驱动开发 测试前移 有关如何更有效地应用TDD的技巧,以及为什么它是一种有价值的技术 (Tips on how to apply TDD more efficiently, and why it' ...

  7. 发那科机器人override指令_发那科机器人程序是如何编写的呢——发那科机器人...

    发那科机器人为自动化设备,但在自动化运转之前,必须先告诉Robot 要自动完成哪些动作,透过「撰写Robot 程序」可达到此目的. Robot 程序主要由「动作指令」构成,只要熟悉手动操作Robot ...

  8. dt测试软件的学习心得,无线网络优化dt测试心得_适合新手入门,高手进阶_5年项目经验实战经验.docx...

    无线网络优化DT测试心得_适合新手入门,高手进阶_5年项目经验实战经验 无线网络优化DT测试心得_适合新手入门,高手进阶_5年项目经验实战经验 路测中不常见的问题和个人心得 1.深井子镇投诉测试报告 ...

  9. 车载毫米波雷达测试(1)_关于雷达的目标检测性能测试与雷达模拟器

    说明 本博文探讨车载毫米波雷达的性能测试,作为车载毫米波雷达研发及产品成型的总体测试架构_墨@#≯的博客-CSDN博客该框架之下的内容之一,雷达的性能测试可以说是最核心的一个部分.雷达的目标检测性能( ...

最新文章

  1. 人工神经网络研究的发展及特性,以前不叫人工智能
  2. 单臂路由实验-VTP
  3. yaf框架学习文件配置
  4. 对select的结果进行count统计
  5. TLV5618 双路12位DAC 模拟SPI驱动
  6. python进行数据分析需要安装哪两个库_对Python进行数据分析_关于Package的安装问题...
  7. 特斯拉2019年第二季度财报出炉:今年有望降低汽车售价
  8. java操作Linux 调用shell命令,shell脚本
  9. 设计模式的七大设计原则:其七:合成复用原则
  10. 学习Flask-SQLAlchmy管理数据库知识记录点
  11. 学习C/C++的经验谈
  12. 数据分析师初级—中级—高级,每个阶段都需要学习什么?
  13. 马士兵老师Java虚拟机调优
  14. 2019天津市二级计算机考试,天津市2019年9月计算机等级考试都有哪些考点可以报名?...
  15. 适合协作办公的在线Word文档-超级文档
  16. 仓库实现降本增效的秘密法宝,WMS智能仓储系统
  17. cents7+tomcat
  18. 华为智慧屏V55升级鸿蒙2,华为智慧屏将作为第一批升级鸿蒙 OS 2.0 系统的终端产品...
  19. 人生不该困于五环之外(3):3到5年离开五环之外
  20. 卷王指南,大学计算机专业,面临分专业,计科,软工,大数据,物联网,网络工程,该选什么?

热门文章

  1. 微信小程序之视图容器(swiper)组件创建轮播图
  2. 关于同时可用git命令clone和TortoiseGit拉取代码不需要密码
  3. 多个css样式合并到一个“目录”css文件中
  4. 课后作业-结队编程项目进度-贪吃蛇
  5. Arduino 控制超声波测距模块
  6. Console.Write(程序猿?开发?写代码?编程?移动、网页、桌面开发?Oh,我连菜鸟都不是!);...
  7. iframe css练习
  8. (二)单元测试利器 JUnit 4
  9. iOS Application Security
  10. net user 用户名 密码 /add 建立用户