<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 13.6.?完備性檢測 (Testing for sanity) 你經常會發現一組代碼中包含互逆的轉換函數,一個把 A 轉換為 B ,另一個把 B 轉換為 A。在這種情況下,創建“完備性檢測”可以使你在由 A 轉 B 再轉 A 的過程中不會出現丟失精度或取整等錯誤。 考慮這個[要求](index.html#roman.requirements): 1. 如果你給定一個數,把它轉化為羅馬數字表示,然后再轉換回阿拉伯數字表示,你所得到的應該是最初給定的那個數。因此,對于 `1..3999` 中的`n`,`fromRoman(toRoman(n)) == n` 總成立。 ## 例?13.5.?以 `toRoman` 測試 `fromRoman` 的輸出 ``` class SanityCheck(unittest.TestCase): def testSanity(self): """fromRoman(toRoman(n))==n for all n""" for integer in range(1, 4000): numeral = roman.toRoman(integer) result = roman.fromRoman(numeral) self.assertEqual(integer, result) ``` | | | | --- | --- | | \[1\] | 你已經見到過 [`range` 函數](../native_data_types/declaring_variables.html#odbchelper.multiassign.range "例?3.20.?連續值賦值"),但這里它以兩個參數被調用,返回了從第一個參數 (`1`) 開始到_但不包括_ 第二個參數 (`4000`) 的整數列表。因此,`1..3999` 就是準備轉換為羅馬數字表示的有效值列表。 | | \[2\] | 我想提一下,這里的 `integer` 并不是一個 Python 關鍵字,而只是沒有什么特別的變量名。 | | \[3\] | 這里的測試邏輯顯而易見:把一個數 (`integer`) 轉換為羅馬數字表示的數 (`numeral`),然后再轉換回來 (`result`) 并確保最后的結果和最初的數是同一個數。如果不是,`assertEqual` 便會引發異常,測試也便立刻失敗。如果所有的結果都和初始數一致,`assertEqual` 將會保持沉默,整個 `testSanity` 方法將會最終也保持沉默,測試則將會被認定為通過。 | [最后兩個要求](index.html#roman.requirements)和其他的要求不同,似乎既武斷而又微不足道: 1. `toRoman` 返回的羅馬數字應該使用大寫字母。 2. `fromRoman` 應該只接受大寫羅馬數字 (也就是說給定小寫字母進行轉換時應該失敗)。 事實上,它們確實有點武斷,譬如你完全可以讓 `fromRoman` 接受小寫和大小寫混合的輸入;但他們也不是完全武斷;如果 `toRoman` 總是返回大寫的輸出,那么 `fromRoman` 至少應該接受大寫字母輸入,不然 “完備性檢測” (要求 #6) 就會失敗。不管怎么說,_只_ 接受大寫輸入還是武斷的,但就像每個系統都會告訴你的那樣,大小寫總會出問題,因此事先規定這一點還是有必要的。既然有必要規定,那么也就有必要測試。 ## 例?13.6.?大小寫測試 ``` class CaseCheck(unittest.TestCase): def testToRomanCase(self): """toRoman should always return uppercase""" for integer in range(1, 4000): numeral = roman.toRoman(integer) self.assertEqual(numeral, numeral.upper()) def testFromRomanCase(self): """fromRoman should only accept uppercase input""" for integer in range(1, 4000): numeral = roman.toRoman(integer) roman.fromRoman(numeral.upper()) self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, numeral.lower()) ``` | | | | --- | --- | | \[1\] | 關于這個測試用例最有趣的一點不在于它測試了什么,而是它不測試什么。它不會測試 `toRoman` 的返回值是否[正確](testing_for_success.html#roman.testtoromanknownvalues.example "例?13.2.?testToRomanKnownValues")或者[一致](testing_for_sanity.html#roman.sanity.example "例?13.5.?以 toRoman 測試 fromRoman 的輸出");這些問題由其他測試用例來回答。整個測試用例僅僅測試大寫問題。你也許覺得應該將它并入到[完備性測試](testing_for_sanity.html#roman.sanity.example "例?13.5.?以 toRoman 測試 fromRoman 的輸出"),畢竟都要遍歷整個輸入值范圍并調用 `toRoman`。\[11\]但是這樣將會違背一條[基本規則](testing_for_success.html "13.4.?正面測試 (Testing for success)"):每個測試用例只回答一個的問題。試想一下,你將這個測試并入到完備性測試中,然后遇到了測試失敗。你還需要進一步分析以便判定測試用例的哪部分出了問題。如果你需要分析方能找出問題所在,無疑你的測試用例在設計上出了問題。 | | \[2\] | 這有一個和前面相似的情況:盡管 “你知道” `toRoman` 總是返回大寫字母,你還是需要把返回值顯式地轉換成大寫字母后再傳遞給只接受大寫的 `fromRoman` 進行測試。為什么?因為 `toRoman` 只返回大寫字母是一個獨立的需求。如果你改變了這個需求,例如改成總是返回小寫字母,那么 `testToRomanCase` 測試用例也應作出調整,但這個測試用例應該仍能通過。這是另外一個[基本規則](testing_for_success.html "13.4.?正面測試 (Testing for success)"):每個測試用例必須可以與其他測試用例隔離工作,每個測試用例是一個“孤島”。 | | \[3\] | 注意你并沒有使用 `fromRoman` 的返回值。這是一個有效的 Python 語法:如果一個函數返回一個值,但沒有被使用,Python 會直接把這個返回值扔掉。這正是你所希望的,這個測試用例并不對返回值進行測試,只是測試 `fromRoman` 接受大寫字母而不引發異常。 | | \[4\] | 這行有點復雜,但是它與 `ToRomanBadInput` 和 `FromRomanBadInput` 測試很相似。 你在測試以特定值 (`numeral.lower()`,循環中目前羅馬數字的小寫版) 調用特定函數 (`roman.fromRoman`) 會確實引發特定的異常 (`roman.InvalidRomanNumeralError`)。如果 (在循環中的每一次) 確實如此,測試通過;如果有一次不是這樣 (比如引發另外的異常或者不引發異常),測試失敗。 | 在下一章中,你將看到如何編寫可以通過這些測試的代碼。 ## Footnotes \[11\] “除了誘惑什么我都能抗拒。 (I can resist everything except temptation.)”――Oscar Wilde
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看