測試驅動開發 測試前移_我如何以及為什么認為測試驅動開發值得我花時間

測試驅動開發 測試前移

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/

測試驅動開發 測試前移

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/394102.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/394102.shtml
英文地址,請注明出處:http://en.pswp.cn/news/394102.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

P2921 [USACO08DEC]在農場萬圣節Trick or Treat on the Farm

對于一個牛,它存在兩種狀態:1.處于聯通分量 2.不處于聯通分量。對于處于聯通分量的牛,求出聯通分量的大小;對于不處于聯通分量的牛,求出其距離聯通分量的路程聯通分量大小。 不同的聯通分量,染上不同的顏色…

ASP.NET MVC5+EF6+EasyUI 后臺管理系統(1)-前言與目錄(持續更新中...)

開發工具:VS2015(2012以上)SQL2008R2以上數據庫 您可以有償獲取一份最新源碼聯系QQ:729994997 價格 666RMB 升級后界面效果如下: 日程管理 http://www.cnblogs.com/ymnets/p/7094914.html 任務調度系統界面 http://www.cnblogs.com/ymnets/p/5065154.h…

leetcode106. 從中序與后序遍歷序列構造二叉樹(dfs)

根據一棵樹的中序遍歷與后序遍歷構造二叉樹。注意: 你可以假設樹中沒有重復的元素。例如,給出中序遍歷 inorder [9,3,15,20,7] 后序遍歷 postorder [9,15,7,20,3] 返回如下的二叉樹:3/ \9 20/ \15 7解題思路 根據后序遍歷的最后一個元素是父節點&…

【FRDM-K64F學習筆記】使用ARM mbed和Keil MDK下載你的第一個程序

FRDM-K64F開發平臺采用MK64FN1M0VLL12微控制器。該控制器包含一個帶有浮點單元的ARM Cortex-M4內核。其最高工作頻率為120MHz,具有256KB的RAM、1MB閃存以及許多其他外設。它非常適合大多數可以采用以太網、SD卡存儲以及板載模擬-數字轉換器的IoT應用。但是&#xff…

php 實時更新內容_億級視頻內容如何實時更新?優酷視頻背后的技術揭秘

簡介: 優酷視頻內容數據天然呈現巨大的網絡結構,各類數據實體連接形成了數十億頂點和百億條邊的數據量,面對巨大的數據量,傳統關系型數據庫往往難以處理和管理,圖數據結構更加貼合優酷的業務場景,圖組織使用…

ios集成firebase_如何使用Firebase將Google Login集成到Ionic應用程序中

ios集成firebaseby Ryan Gordon通過瑞安戈登(Ryan Gordon) 如何使用Firebase將Google Login集成到Ionic應用程序中 (How to integrate Google Login into an Ionic app with Firebase) A lot of apps these days need to maintain some form of user authentication. This hel…

面向對象三大核心特點,封裝、繼承和多態

封裝 封裝其實是一種思想,將事物狀態和功能裝進一個容器,那么這個容器在python中就是類,由這個類產生的對象都擁有類的屬性和功能 在面向對象的思想中,推崇將具有某些共同特征的事物歸為一類,那么這些事物就可以看做是…

java編寫某計算器控制臺程序_用java程序編寫一個計算器

點擊查看用java程序編寫一個計算器具體信息答:給你一個參考,希望不要被百度吞了當晚餐 import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.text.Decimal…

物聯網商機迸發 LPWAN芯片現身 本文轉自d1net(轉載)

聯發科技發表首款NB-IoT系統單芯片MT2625。來源:MediaTeK 物聯網(IoT)帶動的龐大商機吸引各方業者積極投入,尤其是各種聯網技術不斷現身,爭奪各式各樣極富發展潛力的應用領域。 根據IDC的調查報告,物聯網市場在2017年聲勢看漲&…

jquery之stop()的用法

工作中遇到過的實際案例: 1、我在項目里做的一個下拉菜單,當鼠標移上去的時候就菜單顯示,當鼠標離開的時候菜單隱藏 如果我快速不斷地將鼠標移入移出菜單(即,當菜單下拉動畫未完成時,鼠標又移出了菜單&…

leetcode1123. 最深葉節點的最近公共祖先(dfs)

給你一個有根節點的二叉樹,找到它最深的葉節點的最近公共祖先。 回想一下: 葉節點 是二叉樹中沒有子節點的節點 樹的根節點的 深度 為 0,如果某一節點的深度為 d,那它的子節點的深度就是 d1 如果我們假定 A 是一組節點 S 的 最近…

sed空格替換成回車_【一題試水平】 利用sed命令將test.txt中所有的回車替換成空格?...

題目背景,這個題也很有年頭了,看似簡單,實則坑很大,good luck! 先不要看答案 看看自己能寫出多少方法.方法1 把每一行內容追加到Hold Space中,最后1行弄回到Pattern space中.然后進行替換基礎版[rootoldboyedu-show01 …

github 和git_學習編碼時如何學習Git和GitHub

github 和gitby Iago Rodrigues通過Iago Rodrigues 學習編碼時如何學習Git和GitHub (How you can learn Git and GitHub while you’re learning to code) In this article, I’ll give you some hints about how to become a Git/GitHub ninja. Also, as a bonus, I’ll show…

015_ICMP專項研究監控

一、數據demo cat /proc/net/snmp Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates …

leetcode129. 求根到葉子節點數字之和(dfs)

給定一個二叉樹,它的每個結點都存放一個 0-9 的數字,每條從根到葉子節點的路徑都代表一個數字。例如,從根到葉子節點路徑 1->2->3 代表數字 123。計算從根到葉子節點生成的所有數字之和。說明: 葉子節點是指沒有子節點的節點。示例 1:輸…

java for i i 區別,i ++amp;和i ++之間的區別是什么? ++我在for循環(Java)?

hello, Ive just started learning Java and now Im into for loop statement. I dont understand how i i works in a for loop statement.I mean how they work in mathematics operations like addition and subtraction. I hope some one will explain this to me.解決方案…

php 設置中文 cookie, js獲取

參考鏈接:http://www.nowamagic.net/librarys/veda/detail/1271 http://www.ruanyifeng.com/blog/2008/06/base64.html cookie.js 文件 var Cookies {}; /** * 設置Cookies */ Cookies.set function(name, value){ var argv arguments; var argc arguments.length; var exp…

學會這二十個正則表達式,能讓你少些1000行代碼!

正則表達式,是一個強大且高效的文本處理工具。通常情況下,通過一段表達準確的表達式,能夠非常簡短、快速的實現復雜業務邏輯。因此,正則表達式通常是一個成熟開發人員的標配,可以輔助實現開發效率的極強提升。在需要實…

mergesort_Mergesort算法的功能方法

mergesortby Joe Chasinga通過喬查辛加(Joe Chasinga) Mergesort算法的功能方法 (A functional approach to mergesort algorithm) Algorithms are often difficult for people to understand. I believe that this is because they are most often programmed or explained i…

循環內部異步函數處理相關問題解析

需求分析:根據一級標題ID篩選出所有對應的二級標題,返回一級標題ID,標題名和二級標題ID,標題名組成的數組 問題:通過forEach遍歷所有一級標題取對應的ID,根據ID條件查找所有的二級標題,遍歷符合…