<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 27.測試驅動開發 假設你在馬戲團中,一個漂亮的女孩正在空中飛人表演,她錯過了抓地力并摔倒了,你希望那里有一個安全網來捉住她嗎? 你必須瘋了才能拒絕。 以類似的方式,可以說你正在開發軟件,犯了一個錯誤,使用該軟件的人會付出很多代價,擁有制衡能力不是一件好事,這樣即使在錯誤發生之前就可以知道該錯誤。 軟件已發貨? 歡迎來到測試驅動開發。 在這種方法中,我們首先編寫測試,然后編寫足夠的代碼來滿足測試。 通過遵循這種方法,我能夠以最大的信心進行編碼,并且能夠知道存在安全網以防萬一我做錯了事,從而能夠更改代碼并使之更好(也稱為重構)。 讓我們想象一個場景。 你的任務是編寫聊天機器人程序,其初始要求如圖所示 * 必須有一個聊天機器人 * 一個人必須能夠設定年齡和名字 * 它的問候語必須是:“你好,我叫&lt;,名字叫&gt;,我的年齡是&lt;,年齡&gt;,很高興認識你!” 通常,要求不會像上面顯示的那樣精確,但是作為一名程序員,應該可以考慮一下。 現在,我們開始編寫測試文件,而不是編寫代碼來解決任務,將其命名為 test_chat_bot.rb 并將需求放入其中,如下所示: ```rb # test_chat_bot.rb # There must be a chat bot # One must be able to set its age # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" ``` 現在,這些要求已在我們的程序中變成了單詞,我們需要將其轉換為 Ruby。 幾乎所有編程語言都內置了一個測試框架,Ruby 也有一個測試框架,其名稱為 Minitest &lt;sup class="footnote"&gt;[ [63](#_footnotedef_63 "View footnote.") ]&lt;/sup&gt; 。 我們將在這里使用它。 為了包括 Minitest,我們添加下面突出顯示的行 ```rb # test_chat_bot.rb require "minitest/autorun" # There must be a chat bot # One must be able to set its age # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" ``` 現在我們包含了 Minitest,現在讓我們編寫一個測試類,如下所示 ```rb # test_chat_bot.rb require "minitest/autorun" class TestChatBot < Minitest::Test # There must be a chat bot # One must be able to set its age # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" end ``` 完成上面顯示的內容后,現在讓我們為第一個測試用例編寫代碼,看看下面的代碼 ```rb class TestChatBot < Minitest::Test # There must be a chat bot def test_there_must_be_a_chat_bot assert_kind_of ChatBot, ChatBot.new end # One must be able to set its age # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" end ``` 上面的代碼中發生了很多事情,首先我們通過編寫一個測試函數 ```rb def test_there_must_be_a_chat_bot end ``` 注意此功能如何以`test_`開頭,這對于將其識別為測試至關重要。 接下來,我們必須測試此功能中的某些內容。 只有在`ChatBot`類存在的情況下,我們才能使用`ChatBot`類的實例,因此我們嘗試在下面的突出顯示的代碼中創建一個新的`ChatBot`實例,并檢查其類是否為`ChatBot`。 ```rb def test_there_must_be_a_chat_bot assert_kind_of ChatBot, ChatBot.new end ``` 如果你想知道這些內容,讓我來解釋一下`assert_kind_of`。 這些稱為斷言。 你可以在此處查看哪些斷言 [http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html#method-i-assert_respond_to](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html#method-i-assert_respond_to) 。 斷言是用于驗證天氣是否發生某些預期事件的函數,如果發生,則表示測試已通過,否則測試已失敗。 現在讓我們運行測試文件 test_chat_bot.rb ```rb $ ruby test_chat_bot.rb Run options: --seed 53866 # Running: E Finished in 0.000875s, 1142.2906 runs/s, 0.0000 assertions/s. 1) Error: TestChatBot#test_there_must_be_a_chat_bot: NameError: uninitialized constant TestChatBot::ChatBot test_chat_bot.rb:9:in `test_there_must_be_a_chat_bot' 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips ``` 因此,我們得到上面的輸出,表明不存在名為`ChatBot`的常量。 很好,我們尚未定義`ChatBot`是什么,因此我們將對其進行定義。 在 test_chatbot.rb 中,我們添加`require_relative "chat_bot.rb"`行,如下所示 ```rb # test_chat_bot.rb require "minitest/autorun" require_relative "chat_bot.rb" class TestChatBot < Minitest::Test # There must be a chat bot def test_there_must_be_a_chat_bot assert_kind_of ChatBot, ChatBot.new end # One must be able to set its age # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" end ``` 然后,我們創建一個名為 chat_bot.rb 的新文件,其中包含以下內容 ```rb # chat_bot.rb class ChatBot end ``` 現在運行測試。 ```rb $ ruby test_chat_bot.rb Run options: --seed 19585 # Running: . Finished in 0.000720s, 1388.5244 runs/s, 1388.5244 assertions/s. 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips ``` 我們做了什么? 我們有一個需求,我們編寫了涵蓋該需求的測試,我們運行了測試,但失敗了,通過了,我們編寫了足以使它通過的代碼。 現在想象一個場景,你正在一個有 10 個開發人員的項目中,其中一個偶然地犯了一個錯誤,該錯誤將重命名此`ChatBot`類,并且你的測試將抓住它。 簡而言之,如果你編寫了足夠的測試,則可以提早發現錯誤。 它不能保證沒有錯誤的代碼,但是會使錯誤彈出更加困難。 這些測試還將使你有信心重構代碼。 假設你進行了更改,則不必擔心你的更改可能會造成嚴重破壞,只需運行測試一次,你將獲得有關失敗和通過的報告。 讓我們編寫另一個測試,一個應該能夠給聊天機器人一個`age`。 因此,讓我們編寫一個測試,在其中可以設置它的年齡并重新讀取它。 查看下面的函數`test_one_must_be_able_to_set_its_age`中的代碼 ```rb # test_chat_bot.rb require "minitest/autorun" require_relative "chat_bot.rb" class TestChatBot < Minitest::Test # There must be a chat bot def test_there_must_be_a_chat_bot assert_kind_of ChatBot, ChatBot.new end # One must be able to set its age def test_one_must_be_able_to_set_its_age age = 21 chat_bot = ChatBot.new chat_bot.age = age assert_equal age, chat_bot.age end # One must be able to set its name # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" end ``` 看上面的代碼,看這行`assert_equal age, chat_bot.age`,在這里我們斷言 chat_bot 返回設置的年齡。 ```rb $ ruby test_chat_bot.rb Run options: --seed 59168 # Running: .E Finished in 0.000855s, 2338.4784 runs/s, 1169.2392 assertions/s. 1) Error: TestChatBot#test_one_must_be_able_to_set_its_age: NoMethodError: undefined method `age=' for #<ChatBot:0x0000558b89da5380> test_chat_bot.rb:16:in `test_one_must_be_able_to_set_its_age' 2 runs, 1 assertions, 0 failures, 1 errors, 0 skips ``` 如果你看到上面的測試結果,則說明沒有方法錯誤,并說明缺少函數`age=`,因此請對其進行修復。 ```rb # chat_bot.rb class ChatBot attr_accessor :age end ``` 因此,我們在`attr_accessor :age`行上方添加了內容,然后運行測試并通過了如下所示的測試 ```rb $ ruby test_chat_bot.rb Run options: --seed 42767 # Running: .. Finished in 0.000774s, 2583.4820 runs/s, 2583.4820 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips ``` 現在讓我們在名稱上也做同樣的事情,在年齡上我將不做解釋,在本書中也不再贅述。 讓我說說最后的測試。 它必須打招呼。 為此,我們編寫了一個測試,如下面的函數`test_greeting_message`所示: ```rb # test_chat_bot.rb require "minitest/autorun" require_relative "chat_bot.rb" class TestChatBot < Minitest::Test # There must be a chat bot def test_there_must_be_a_chat_bot assert_kind_of ChatBot, ChatBot.new end # One must be able to set its age def test_one_must_be_able_to_set_its_age age = 21 chat_bot = ChatBot.new chat_bot.age = age assert_equal age, chat_bot.age end # One must be able to set its name def test_one_must_be_able_to_set_its_name name = "Zigor" chat_bot = ChatBot.new chat_bot.name = name assert_equal name, chat_bot.name end # Its greeting must say "Hello I am <name> and my age is <age>. # Nice to meet you!" def test_greeting_message name = "Zigor" age = 21 expected_message = "Hello I am #{name} and my age is #{age}. Nice to meet you!" chat_bot = ChatBot.new chat_bot.name = name chat_bot.age = age assert_equal expected_message, chat_bot.greeting_message end end ``` 現在我們運行它,如你所見,它自然會失敗,如下所示 ```rb $ ruby test_chat_bot.rb Run options: --seed 8752 # Running: .E.. Finished in 0.001075s, 3720.5045 runs/s, 2790.3784 assertions/s. 1) Error: TestChatBot#test_greeting_message: NoMethodError: undefined method `greeting_message' for #<ChatBot:0x000055b4ae5a8620 @name="Zigor", @age=21> test_chat_bot.rb:39:in `test_greeting_message' 4 runs, 3 assertions, 0 failures, 1 errors, 0 skips ``` 因此我們修改了文件 [chat_bot.rb](code/chat_bot.rb) ,如下所示 ```rb # chat_bot.rb class ChatBot attr_accessor :age, :name def greeting_message "Hello I am #{name} and my age is #{age}. Nice to meet you!" end end ``` 現在我們運行測試,它通過如下所示: ```rb $ ruby test_chat_bot.rb Run options: --seed 16324 # Running: .... Finished in 0.001149s, 3480.2007 runs/s, 3480.2007 assertions/s. 4 runs, 4 assertions, 0 failures, 0 errors, 0 skips ``` 因此,現在我們有了一個應用程序和一個安全網,因此它具有更多的錯誤證明。 # 設計模式 **需要設計模式** 與現在使用的軟件相比,當軟件開始時,它很小,計算機功率很低,并且只能用于非常艱巨的任務,所以人們對單個人或緊密聯系的小組可以維護的小程序感到滿意。 但是,隨著計算機變得越來越強大,計算機變得越來越復雜,項目變得越來越龐大,代碼的結構成為一個重要的問題。 那就是設計模式揭曉的時候。 閱讀本書的大多數人可能是 Ruby 初學者或中級,但是你可能需要從事實際項目。 即使你為個人項目選擇了 Ruby,也更好地組織代碼,因此對設計模式的需求變得至關重要。
                  <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>

                              哎呀哎呀视频在线观看