Secrets of the JavaScript Ninja 邊譯邊學(10)

Secrets of the JavaScript Ninja 邊譯邊學(10)

2.4 The Fundamentals of a Test Suite
2.4 測試套件的基本原理

The primary purpose of a test suite is to aggregate all the individual tests that your code base might have into a single location, so that they can be run in bulk - providing a single resource that can be run easily and repeatedly.
測試套件的主要作用是將核心代碼庫的所有單個測試聚合到一個位置,以便它們可以批量運行-前提是批量運行的集合操作方便並且是可重複運行的。

  To better understand how a test suite works it makes sense to look at how a test suite is constructed. Perhaps surprisingly JavaScript test suites are really easy to construct and a functional one can be built in only about 40 lines of code.
  爲了更好地理解測試套件是如何工作的,一個很有意義的方法是查看如何構建測試套件。事實也許讓人非常驚訝:JavaScript的測試套件很容易構建,一份大約40行的代碼就可以構建一個有用的測試套件。

  One would have to ask, though: Why would I want to build a new test suite? For most cases it probably isn’t necessary to write your own JavaScript test suite, there already exist a number of good-quality suites to choose from (as already shown). It can serve as a good learning experience though, especially when looking at how asynchronous testing works.
  有人可能會問,既然這樣,爲什麼還要創建一個新的測試套件?大多數情況下,確實不需要編寫自己的JavaScript測試套件,現在已經存在大量高質量的套件供我們挑選(正如之前提到的那樣)。但是它可以爲我們提供很好的學習經驗,尤其是當我們研究異步測試如何工作的時候。

2.4.1 The assertion
2.4.1 斷言

The core of a unit-testing framework is its assertion method; usually named assert() . This method usually takes a value – an expression whose premise is asserted – and a description that describes the purpose of the assertion. If the value evaluates to true , in other words is “truth-y”, then the assertion passes, otherwise it is considered a failure. The associated message is usually logged with an appropriate pass/fail indicator.
單元測試框架的核心是斷言方法;該方法通常命名爲assert()。該方法通常傳入一個值-或者一個結果確定的表達式-以及一段描述該斷言目的的說明。如果傳入的值等於真,也就是"truth-y",那麼斷言通過,否則爲失敗。相關的描述說明通常使用合適的通過/失敗指示器記錄下結果。

  A simple implementation of this concept can be seen in Listing 2.8.
  清單2.8展示了以上概念的一份簡單實現。

  The function named assert() (#1) is almost surprisingly straight-forward. It creates a new < li > element containing the description, assigns a class name pass or fail, depending upon the value of the assertion parameter ( value ), and appends the new element to a list element in the document body (#4).
  這個方法直接以assert命名(#1)。它創建了一個新的< li >標籤,其中包含了描述,賦給它一個類名:pass或者fail,該值由斷言的參數value確定,然後把這個元素附加到頁面的一個list列表中(#4)

  The simple test suite consists of two trivial tests (#2): one that will always succeed, and one that will always fail.
  這個簡單的測試套件包含兩個小用例(#2):一個總是返回成功,另一個總是返回失敗。
  Style rules for the pass and fail classes (#3) visually indicate success or failure using color.
  通過和失敗通過不同的樣式類名來區分(#3),這些樣式類中定義了不同的顏色分別代表通過和失敗。
  This function is simple - but it will serve as a good building block for future development, and we’ll be using this assert() method throughout this book to test various code snippets, verifying their integrity.
  該方法很簡單-但卻可以作爲未來開發的基礎版本,我們會在本書中使用該assert方法去測試各種代碼片段,驗證其完整性。

2.4.2 Test groups
2.4.2 測試分組

Simple assertions are useful, but really begin to shine when they are grouped together in a testing context to form test groups.
簡單的斷言很有用,但是當它們在一個測試上下文中組合在一起成爲測試組的時候纔開始真正發揮其作用。

  When performing unit testing, a test group will likely represent a collection of assertions as they relate to a single method in our API or application. If you were doing behavior-driven development the group would collect assertions by task. Either way the implementation is effectively the same.
  當作爲單元測試而存在時,由於和我們的API或者應用中的單個方法相關,所以測試分組可能代表斷言的集合。若進行行爲驅動開發,測試分組會按照任務收集斷言。無論哪種方式,實現都一樣高效。

  In our sample test suite, a test group is built in which individual assertions are inserted into the results. Additionally if any assertion fails then the entire test group is marked as failing. The output in Listing 2.8 is kept pretty simple, some level dynamic control would prove to be quite useful in practice (contracting/expanding the test groups and filtering test groups if they have failing tests in them).
  在我們接下來的測試套件示例中,構建了一個測試分組,單個斷言被插入其結果集中。若任何斷言失敗,則整個測試組標記爲失敗。保持了列表2.8代碼的簡單輸出,並且加入了一定程度的動態控制,證明它確實在實踐中很有用(收縮/展開測試分組,如果存在失敗測試用例,可以過濾測試分組)

清單2.9 一個測試分組的實現
``` Test Suite
    
    <b>運行結果如下:</b>
    
    ![](https://img-blog.csdnimg.cn/20190628111534512.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dxeTI0OA==,size_16,color_FFFFFF,t_70)
    
    &emsp;&emsp;As we cab see seen in Listing 2.9, the implementation is really not much different from our basic assertion logging. The one major difference is the inclusion of a results variable, which holds a reference to the current test group (that way, the logging assertions are inserted correctly).
    &emsp;&emsp;如清單2.9所示,和我們之前的基礎斷言版本的實現區別不大。最大的區別是它包含了一個指向當前測試組的引用的結果變量(這樣的話,斷言可以插入到正確的地方)。
    
    <b>個人理解</b>
    這個指向所屬測試組的引用是代碼中的results,如下所示:
    

    var results;

    該變量在即時執行函數function開頭部分定義,在test中賦值,在assert中使用。
    
    
    &emsp;&emsp;Beyond simple testing of code, another important aspect of a testing framework is handling of asynchronous operations.
    &emsp;&emsp;除了簡單測試,測試框架的另一個重要方面是處理異步操作。
    
    
    2.4.3 Asynchronous Testing
    2.4.3 異步測試
    
    A daunting and complicated tasks that many developers encounter while developing a JavaScript test suite, is handling asynchronous tests. These are tests whose results will come back after a non-deterministic amount of time has passed; common examples of this situation could be Ajax requests or animations.
    許多開發者在開發JavaScript測試套件時遇到的一個棘手的問題時構建異步測試。在這些測試中,結果需要在程序運行一段不確定的時間以後纔會出現;在Ajax請求或者動畫中經常出現上述情形。
    &emsp;&emsp;Often handling this issue is over-though and made much more complicated than it needs be. To handle asynchronous tests we need to follow a couple of simple steps:
    &emsp;&emsp;我們通常過度處理了這個問題,讓它變得比需要的更加複雜。解決異步測試問題,我們需要遵循以下幾個簡單的步驟:
    
    1. Assertions that are relying upon the same asynchronous operation will need to be grouped into a unifying test group.
    2. Each test group will need to be placed on a queue to be run after all the previous test groups have finished running.
    3. Thus, each test group must be capable of run asynchronously.
    
    
    
    1. 依賴於相同異步操作的斷言需要分組到一個統一的測試組中。
    2. 每個測試組都需要放在一個隊列中,這樣就可以保證該隊列在上一個測試組完成運行後才運行。
    3. 而且,每個測試組都必須具備異步運行的能力。
    
    Let’s look at the example of Listing 2.10.
    讓我們來看看清單2.10中的示例。
    
    <table><tr><td bgcolor=#880015><font color=white><b>清單2.10 一個簡單的異步測試的實現</b></font></td></tr></table>
    
    Test Suite
      
      <b>個人理解</b>
      該程序運行步驟如下所示:
      ![](https://img-blog.csdnimg.cn/20190701094255699.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dxeTI0OA==,size_16,color_FFFFFF,t_70)
      
      <font color=green><b>函數名後面跟()代表立即執行。比如上例中queue.shift()();queue.shift()返回的是隊列中取出的函數本身的定義對象,後面跟()代表立即執行該函數。</b></font>
      
      &emsp;&emsp;Let’s break down the functionality exposed in in Listing 2.10. There are three publicly accessible functions: test() , pause() , and resume() . These three functions have the following capabilities:
      &emsp;&emsp;現在讓我們來分解清單2.10中顯示的函數實現。這裏面由三個公共方法:test(),pause(),resume()。這三個函數具有以下功能:
      
      - test(fn) takes a function which contains a number of assertions, that will be run either synchronously or asynchronously, and places it on the queue to await execution.
      - pause() should be called from within a test function and tells the test suite to pause executing tests until the test group is done.
      - resume() unpauses the tests and starts the next test running after a short delay pu inyo place to avoid long-running code blocks.
      
      - test(fn) 是一個接收許多斷言語句作爲傳入參數的函數,這些斷言既可以異步執行也可以同步執行,該函數將其放入一個隊列中等待執行。
      - pause() 應該在一個測試函數中調用該函數,通知測試套件暫停執行,直到整個測試組執行完畢。
      - resume() 在短暫的停止之後,取消暫停,開始執行下一個測試,防止長時間的代碼中斷。
      
      &emsp;&emsp;The one internal implementation function, runTest() , is called whenever a test is queued or dequeued. It checks to see if the suite is currently unpaused and if there's something in the queue; in which case it'll dequeue a test and try to execute it. Additionally, after the test group is finished executing it will check to see if the suite is currently 'paused' and if not (meaning that only asynchronous tests were run in the test group) it will begin
      executing the next group of tests.
      &emsp;&emsp;唯一的內部實現功能,runTest(),當測試入列或出列時被調用。它檢查該套件當前是否處於暫停狀態,隊列裏有沒有待執行的測試。另外,如果測試組執行完畢,它還需要檢查該套件當前是否處於暫停狀態,如果不是處於暫停狀態的話(也就是說測試組裏面只有異步測試),纔會執行下一組測試。
      
      &emsp;&emsp;We’ll be taking a closer look in chapter 8 which focuses on Timers, where we’ll make an in-depth examination of much of the nitty-gritty relating to delayed execution.
      &emsp;&emsp;我們將在第8章中更詳細地介紹計時器,在第8章中,我們將深入研究與延遲執行有關的許多細節。
      
      
      2.5 Summary
      2.5 總結
      
      In this chapter we've looked at some of the basic technique surrounding debugging JavaScript code and constructing simple test cases based upon those results.
      在這一章中,我們瞭解了一些關於調試JavaScript代碼的基本技術,並且基於這些技術構建了一些簡單測試用例。
      
      &emsp;&emsp;We started off by examining how to use logging to observe the actions of our code as it is running and even implemented a convenience method that we can use to make sure that we can successfully log information in all modern browsers, despite their differences.
      &emsp;&emsp;我們首先研究瞭如何使用日誌記錄來觀察代碼運行時的行爲,然後甚至實現了一個簡便的函數,用它我們可以確保在任何現代瀏覽器中都能成功地記錄信息,不論這些瀏覽器之間存在多少差異。
      
      &emsp;&emsp;We then explored how to use breakpoints to halt the execution of our code at a certain point, allowing us to take a look around at the state within which the code is executing.
      &emsp;&emsp;然後,我們研究瞭如何使用斷點在某一點上停止代碼的執行,從而允許我們查看各項代碼運行時狀態。
      
      &emsp;&emsp;Our attention then turned to test generation, defining and focusing on the attributes of good tests: repeatability, simplicity and independence. The two major types of testing, deconstructive and constructive testing were then examined.
      &emsp;&emsp;然後,我們將注意力轉向構建測試,定義並關注好的測試的屬性:可重複性、簡單性和獨立性。然後分析了兩種主要的測試類型:解構測試和構造性測試。
      
      &emsp;&emsp;Data collected regarding how the JavaScript community is using testing was presented, and we took a brief survey of existing test frameworks that you might want to explore and adopt should you want use a formalized testing environment.
      &emsp;&emsp;介紹了收集到的有關JavaScript社區如何使用測試的數據,我們對現有的測試框架進行了簡短的調查,如果您希望使用正式的測試環境,那麼您可能希望探索並採用這些測試框架。
      
      &emsp;&emsp;Building upon that, we introduced the concept of the assertion, and created a simple implementation that will be used throughout the remainder of this book to verify that our code does what we intend for it to do.
      &emsp;&emsp;在此基礎上,我們引入斷言的概念,並創建了一個簡單的實現,該實現將在本書的其餘部分中使用,以驗證我們的代碼是否按照希望的方式執行。
      
      &emsp;&emsp;Finally, we looked at how to construct a simple test suite capable of handling asynchronous test cases. Altogether, these techniques will serve as an important cornerstone to the rest of your development with JavaScript.
      &emsp;&emsp;最後,我們研究瞭如何構建一個能夠處理異步測試用例的簡單測試套件。總之,這些技術將成爲您使用JavaScript開發其餘部分的重要基礎。
      
      發表評論
      所有評論
      還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
      相關文章