以下內容轉自 https://codeutopia.net/blog/2015/04/11/what-are-unit-testing-integration-testing-and-functional-testing/
What are Unit Testing, Integration Testing and Functional Testing?
Finding your way around the maze that is JavaScript testing can sometimes be difficult. There are unit tests, integration tests, functional tests, E2E tests, browser tests… With so many buzzwords, who knows what they do and which one to use, what for, and when?
To help with that problem, in this article I’ll give you a guide comparing the different kinds of testing types available, and some recommendations for their use.
找出測試javascript的方法有時候非常困難。現在有單元測試,集成測試, 功能測試,E2E測試,瀏覽器測試,如此多時髦的測試,誰知道它們是怎么做的或者我們要用哪一個,什么時候用等等?
Unit Testing
Unit testing is the practice of testing small pieces of code, typically individual functions, alone and isolated. If your test uses some external resource, like the network or a database, it’s not a unit test.
Unit tests should be fairly simple to write. A unit tests should essentially just give the function that’s tested some inputs, and then check what the function outputs is correct. In practice this can vary, because if your code is poorly designed, writing unit tests can be difficult. Because of that, unit testing is the only testing method which also helps you write better code – Code that’s hard to unit test usually has poor design.
In a sense, unit testing is the backbone. You can use unit tests to help design your code and keep it as a safety net when doing changes, and the same methods you use for unit testing are also applicable to the other types of testing. All the other test types are also constructed from similar pieces as unit tests, they are just more complex and less precise.
Unit tests are also great for preventing regressions – bugs that occur repeatedly. Many times there’s been a particularly troublesome piece of code which just keeps breaking no matter how many times I fix it. By adding unit tests to check for those specific bugs, you can easily prevent situations like that. You can also use integration tests or functional tests for regression testing, but unit tests are much more useful because they are very specific, which makes it easy to pinpoint and then fix the problem.
When should you use unit testing? Ideally all the time, by applying test-driven development. A good set of unit tests do not only prevent bugs, but also improve your code design, and make sure you can later refactor your code without everything completely breaking apart.
Popular tools for unit testing include Mocha, Jasmine and Tape.
單元測試
單元測試是檢測一小段代碼的良好實踐,典型的單元測試是測試獨立的function,要保證這個測試是單獨孤立的。如果你寫的測試用了外部的資源,比如網絡或者數據庫,它就不是一個單元測試。
單元測試應該是寫起來很簡單的。它基本上是給了這個要測的function的輸入,檢測這個function的輸出是否正確就可以了。如果你的代碼設計不好,單元測試就很難寫,所以單元測試是唯一的能幫助你寫好代碼的測試方法-(重復一下)一般測試很難寫的代碼它的設計往往也不好。
某種意義上,單元測試像是一個脊椎骨。單元測試可以幫助你設計你的代碼,並且在你重構或者修改代碼的時候有保證不會破壞代碼功能。你寫單元測試的方法可以被應用到寫其他類型的測試上。其他類型的測試也可以和單元測試有相同的結構,只是它們更加復雜,不夠簡潔而已。
單元測試也可以很好的阻止bug重復發生(regressions)。我們經常會遇到這種情況,有段很煩人的代碼,無論我們修多少次,還是會有問題。通過增加單元測試來檢查那些特定的bug,你可以很容易的阻止類似的情況發生。你也可以用集成測試或者功能測試來做回歸測試,但是單元測試因為其能夠更加針對細節而更加有用,單元測試可以很容易的定位問題並且解決問題。
什么時候用單元測試合適呢?理想情況下任何時候,可以用測試驅動開發。好的單元測試不僅可以避免bugs產生,也可以幫助提高代碼設計,還可以在以后重構代碼的時候保證代碼不會被改的四分五裂。
現在比較時髦的單元測試工具有Mocha, Jasmine 和 Tape。
Integration Testing
As the name suggests, in integration testing the idea is to test how parts of the system work together – the integration of the parts. Integration tests are similar to unit tests, but there’s one big difference: while unit tests are isolated from other components, integration tests are not. For example, a unit test for database access code would not talk to a real database, but an integration test would.
Integration testing is mainly useful for situations where unit testing is not enough. Sometimes you need to have tests to verify that two separate systems – like a database and your app – work together correctly, and that calls for an integration test. As a result, when validating integration test results, you could for example validate a database related test by querying the database to check the database state is correct.
Integration tests are often slower than unit tests because of the added complexity. They also might need some set up or configuration, such as the setting up of a test database. This makes writing and maintaining them harder than unit tests, so you should focus on unit tests unless you absolutely need an integration test.
You should have fewer integration tests than unit tests. You should mainly use them if you need to test two separate systems together, or if a piece of code is too complex to unit test. But in the latter case, I would recommend fixing the code so it’s easy to unit test instead.
Integration tests can usually be written with the same tools as unit tests.
集成測試
就像這個測試的名字(集成)所表達的意思一樣,集成測試想要測試的是這個系統的各個部分在一起合作的如何-將各個代碼塊集成在一起。集成測試和單元測試很類似,但是有一個很大的不同:單元測試是不依靠於其他組件的,只測試某段代碼,但是集成測試不是。舉個例子,一段數據庫訪問代碼的單元測試是不需要和真正的數據庫連接的,但是集成測試不是這樣。
有的情況下,單元測試不能夠滿足測試要求,這個時候集成測試就大有用處。有時候你需要驗證兩個不同的系統是否在一起正常的通信和正常運轉,比如你的應用程序和數據庫是否集成正確,運轉正常,這個時候就需要集成測試了。結果是,當驗證集成測試結果時,你通過寫數據庫連接語句檢查數據庫狀態是否正常而順便做了數據庫連接測試。
集成測試比單元測試會慢一些,是因為它比單元測試更加復雜。集成測試可能需要配置環境,例如建一個測試數據庫之類。這就使得寫集成測試和維護集成測試比單元測試難,所以你應該更專注於寫單元測試,除非你真的需要集成測試再寫它。(本翻譯者並不認同最后一句話,我覺得它們的職責不一樣,所以集成測試還是有必要寫的)
你應該寫更多的單元測試,更少的集成測試。如果你要測試兩個分開的系統部分或者一段代碼很復雜不容易寫單元測試,你可以用集成測試。但是對於后一種情況(代碼復雜到不容易寫單元測試),我建議是修改代碼使它容易些單元測試。
集成測試也可以用單元測試的那些工具來做。
Functional Testing
Functional testing is also sometimes called E2E testing, or browser testing. They all refer to the same thing.
Functional testing is defined as the testing of complete functionality of some application. In practice with web apps, this means using some tool to automate a browser, which is then used to click around on the pages to test the application.
You might use a unit test to test an individual function and an integration test to check that two parts of the play nice. Functional tests are on a whole another level. While you can have hundreds of unit tests, you usually want to have only a small amount of functional tests. This is mainly because functional tests can be difficult to write and maintain due to their very high complexity. They also run very slowly, because they simulate real user interaction on a web page, so even page load times become a factor.
Because of all this, you shouldn’t try to make very fine-grained functional tests. You don’t want to test a single function, despite the name “functional” perhaps hinting at it. Instead, functional tests should be used for testing common user interactions. If you would manually test a certain flow of your app in a browser, such as registering an account, you could make that into a functional test.
While in unit and integration tests you would validate the results in code, functional test results should be validated the same way as you would validate it if you were a user of the page. Going with the registration example, you could validate it by checking that the browser is redirected to a “thanks for registering page”.
You should use functional tests if you have some repeated tests you do manually in the browser, but be careful to not make them too fine-grained, as they can easily become a nightmare to maintain. I know, because I’ve seen it happen many times.
The most common tool used for functional testing is Selenium. Running Selenium is usually done with Selenium WebDriver, or Protractor. Sometimes PhantomJS and CasperJS can be used as well, especially if you don’t need to test in real browsers.
功能性測試也被稱為E2E測試,或者瀏覽器測試。它們指的是一件事情。
功能測試被解釋為測試應用程序的全部的完整的功能。對於互聯網應用程序來說,這意味着用一些工具在瀏覽器上自動化測試,在頁面上自動點擊來測試應用程序。
你可以用單元測試來測試單獨的function,也可以用集成測試來測試兩個部分是否一起正常工作。功能測試完全是另外一個級別上的。一般情況下,你有幾百個單元測試但是往往只想要少量功能測試。一個主要原因是因為功能測試的復雜度高,所以不容易寫和維護它。功能測試通常運行很慢,是因為它們模擬的是web頁面上的真實用戶交互,頁面加載時間也算是運行慢的一個原因。
根據以上原因,你不應該做粒度太小的功能測試。你不想測試一個單獨的功能,盡管這個測試的名字是這樣。功能測試應該做的是測試普通用戶的交互行為。如果你想手動用瀏覽器測試一個確定的使用過程,例如注冊賬戶,那么你應該使用功能測試。
單元測試和集成測試是用代碼來驗證結果,功能測試結果驗證就和網站用戶驗證結果一樣。還拿注冊的例子來說,測試成功標准就是瀏覽器直接跳到“thanks for registering page感謝注冊”這個頁面。
如果你有大量重復的瀏覽器上要手動做的測試,你可以試試功能測試,但是要仔細不要把測試做的太細粒度了,因為這樣維護起來會很麻煩。我知道這個結果是因為它在我身上發生了很多次。
最常見的功能測試工具是Selenium。我們可以用Selenium WebDriver和 Protractor做功能測試,也可以用PhantomJS ,CasperJS,尤其是在你不需要在真正的瀏覽器上測試時。
In closing
Unit tests should be your main focus when testing JavaScript code. They are the easiest to write and maintain, and provide many benefits beyond reducing bugs. Integration and functional tests should be in a supporting role, for where unit tests are not suitable.
For more on how unit tests relate to some other testing types, you should also check out my article discussing the differences between Unit Testing, TDD and BDD.
最后
在javascript代碼中,單元測試是最應該花費你的精力去寫的。它們最容易寫和維護,而且有很多好處,這些好處包括減少bug。當有的地方不適合寫單元測試時,可以謝謝集成測試和功能測試。
你如果想看更多的關於單元測試和其他測試的關系,你可以看看我的文章:the differences between Unit Testing, TDD and BDD。