# 軟體工程 Week 4 ###### tags: `軟體工程` # 測試 ## ACM 調查 * 校園很少介意 ## QA & QC ### Good quality product requirement (將軟體視為一項產品) * Quality control 品質控制 * Quality assurance 品質確保 * Testing 軟體測試(品質確保中的一環) * 把Bug抓出來的一手段 ### 製造業案例 * 希望生產與可販售的數量相符 * Process Improment(工業工程領域):製造流程改,提高良率 * 最好提升品質方式,使用機器 * 但機器有磨損問題 * 生產線: * 讓每個人做簡單工作,使他們【不易出錯】 * 不需要太過聰明 * 切割小步驟,每個步驟能在最短時間完成 * 使其發現產品問題不困難 ### 能如法炮製嗎? * 並不能 * 軟體發展是設計的工作 ### Programmer VS Assembly line worker (生產線作業員) * Programmer * requires perfection ### The Big GAP  * Demo-Oriented reasearch * Don't Touch * research prototypes * Major Features are usable (主要功能) * prove of concpts (概念證明) * not responsible for bugs (不負責任) * user friendly not guaranteed (不保證) * crappy UI (糟糕的UI) * Product * all features * bugs are not allowed * usable * user friendly * the generic data format * performance is tuned. * UI is well designed and pleasant ### Other engineer VS software engineer * Other engineer * Idea * Marketing(Requirement) Analysis * Analysis and Design (分析與設計) * Manufacturing (QC) (製造) * Testing (QA)(測試) * Release product (產品出廠) * software engineer * Idea (概念) * Requirement analysis and specification (100% design) (需求分析與規格) * Design and analysis (分析與設計)(100% design, QC here?) * Implementation (程式實做)(95% design?, QC here?) * Manufacturing (製造)(compilation – no cost manufacturing) * Testing(測試) ## Tradiction 1. Marketing 2. Develop 3. QAs(Testing) * QAs 必須與Programmer 站在對立面 * 管帳的不管錢,管錢的不管帳 * 法官判案,承認判案是錯的 ## Software Testing V model  * 瀑布模型 開發模式 ### Testing 1. 模組設計(小塊) => Unit Test * Programmer 3. 設計與分析 => Integration Test * Programmer / QA 負責 4. 規格 => System Testing * 系統已經完成 5. 需求 => User Acceptance testing (UAT): 驗收測試 6. Regression testing(回歸測試) 7. Alpha testing: 整合測試完成後,程式功能皆已大致完畢且完成測試(程式一Run就當掉都修的差不多嘞) * Most software function & feature are basiclly completed: 程式碼已經完成 * freezing : 新功能不再添加功能。All function are tested, no function will be added beyond this point * Serious flaws(high severity) are sloved and addressed(show stopper) 8. Beta Testing * Sub-serious bug all fixed: 嚴重Bug 皆以解決 * Text plan has been completely excuted: QAs 已經完成 Testing Report * Bug discovering rate is lower than fixing rate,發現頻率低於修復頻率 ## SDLC(Software Development Life Cycle)  * Release * Bug discovering rate is lower than fixing rate for 【long period of time】 * The version after fixing bugs has been regressively tested (regression test): 版本修復後,且經過回歸測試 * Quality is formally proved by QA team: QAs正式證明質量 * All documents are ready: 文件皆已經齊全 ## Testing tasks to be done * Write Test plan * often seen in large software company with formal QA team * write test cases, prepare test data * test case management * file bugs * Bug 回報系統(文件) * regression testing * test automation (with tools): 測試自動化 * QA team 來做 * stress testing/load testing * security testing * test as assets. ### How to plan * (要或不)測什麼 * 測試代價有多高 * 前後順序 ### 很重要的一句話 #### No test case No quality # Test Case * Test ID * Revision History * Summary * Tested Story * Creator * Test Step *  ## Test ID * 可包含之元素 * Test Suite name * Computer or Requirement abbreviation(縮寫) * ID 值可使用有意義之值 * A: automatically Excuted : 測試自動化 * M: Manually Excuted : 需透過人工 * P: Positive case * N: Negative case : 故意操作超出範圍之值 * B: Boundary case : 故意測試邊界值,如:<0,會測試0與1 * 0: cast priority * 1....9 ## Bug Report System * 紀錄Bug * 確認測試足夠的 * 能夠與未來的人溝通 * 若有人來詢問Bug代表敘述不清楚 * Attach any files * input file * output file * dump * 也可利用 OBS: 影片錄影 ### Severity of Software Defect * Severity 1(Show Stop): 非常嚴重,一跑就當掉嘞 * Severity 2: 不會當掉,但會無法繼續操作 * Microsoft 1-30 # Devops ## Regression Testing *  =>  * 敏捷開發 => 回歸測試自動化 ## Buttom up But Fow ### AFILE * 不斷 Release * 先顯示可以動的部分,不等成品完成 * Quality 要由底部向上完成 ### Module Test * 雖然不是整段程式,屬於片段程式,但還是能夠進行測試 #### Test Bench * Module under test * Component under test * Program under test * dependecy * 需要透過其他的人合作的程式組件才能執行 * 需建置一個API Server才能夠處理 * Test Driver *  * Test Runner * Dummy r(): 假的 = fack * 使用造假輸入,並回傳 * 設定中斷點 * 使用假的 Server ### Testing in isolation  ## Parafigm Shift * 徒然讓Proggramer 加入 Testing文化 * Tools: Coverage ### Google * 讓Proggramer 工作增加但薪水也增加 * 讓Proggramer 每天習慣與實踐 ### Unit Test Benefits * Unit Test = Black Box + While Box * 有Source Code * Unit Test 1 : Unit testing provides documentation (測試及文件) * basic picture * carry information * appropriate * inappropriate * Unit Test 2 : Reusable and Reliable (可重用性且可靠性) * 因為由Buttom up , 因此程式品質本就好 * Unit Test 3 : Unit testing help gauge performance (能幫助測量程式):(你可以在更早的時間進行效能測試) * Unit Test 4 : Unit testing improves code coverage (改進測試覆蓋率) ## Bottom up Vs Top Down * Project vs Product * Short-term fix product vs long-term maintained project? * 你的老舊系統 (legacy) 要不要回去補單元測試? (其實你想補也大概補不動) * 一個可能的 good timing – 老系統因為效能,功能改善得重構 -> 圈出一個範圍補單元測試 # Junit * @Test * assertEquals(比對值,呼叫函數<被Test>) *  * BeforeEach : Test Case Run之前會先呼叫 * 不能添加 Static * AfterEach: Test Case 每個Run完成以後呼叫 * 不能添加 Static * AfterAll : Test Case 全部 Run完成以後呼叫 * 一定要添加Static # Test Oracles * 能判斷 Program Behavior 是否出錯,針對程式的輸入輸出做一比較 * monkey tests: 隨便亂點按鈕 * Teating automation 測試自動化困難之處 * 無法判別程式的正確與否 * 決定規格與一致性是否不符合 * 規格=> 正確性 * * 人是最厲害的 Test Oracles * 聖杯(holy grail)問題 ## About * 驗證是否與程式執行結果一樣 * 視為一個黑箱 * 使用CUT 建立物件 ### Unit Test單元測試 * Unit Test = Black Box + White Box * 有Source Code * 需要額外增加 * 讀取Internal Value(內部變數)判斷 * Construction injection * 當你需要使用 fake object * 像是 test stub, mocks. * 案例一: Construction injection #### white box * 能夠知道source code * 推倒Test Case * 能夠知道 Iternal behaviors 的狀況 ### 案例一: Construction injection *  * 在Test Case呼叫後, * 可提供給其他函數使用: Object 都會重新被建立,重新New ### 案例二: assertTrue Run For(){} *  *  ## True Oracle  * X 你寫的Program: 不確定是否正確 * 應用情境: 舊版改寫須重購、改良 * 不一定存在  ## Partial Oracle  * X 你寫的Program: 不確定是否正確 * Detect X 輸出的值是否正確,不正確輸出 Failed * 並不容易撰寫 * AVL Tree 案例實作 * 應用情境: * Program Prove * Precondiction PostCondiction  ## Test-Oriented oracle(xUnit test) ## ParameterizedTest vs Partial Test Oracles 哪裡不一樣?? # 要寫多少測試才夠 * Code Coverage * Paryition Test * Boundery Test * Negative Test ## Code Coverage  * Statement coverage: 每條路都走過 *  * You only need 3 test cases to have each statement at least executed once. * Testing 的最低測試標準 ## Branch coverage: 分支測試  * there are 3 branches, so at most 2 * 2 * 2 branching *  ## Path Coverage: 窮舉測試  *  * 最困難達成,理論上達不到 * exhaustive testing *  * Omega(大寫Ω,小寫ω): infinite 無窮 ## Summary 總結  * 左座標: 現實中是否能夠達成 * intractable: 棘手的;太困難的 * feasible: 可行的 * 金管會 要求到 Branch * 基本上不可能達到 * 根據時間與資源決定測試的位置 ## Partition Test * 人類最古老的測試理論 *  * Input 以及對應的 Domain * 只需要挑橢圓形區域中的一個就可以嘞 * Equivalence partitioning(partition testing) * White box 白箱測試 * 案例一: Bobble sort * 測試案例 *  ## Boundery Test: 測試邊緣人,不只是邊界 * 通常 Boundery Test + Partial Test * boundery values 被暴露出來 *  * X=Y * X=0,整數最大值、最小值 * Y=0 *  *  *  *  * 999999..., 根據規格書 * 字串超出範圍 ## Negative Tests :(給不合法,超出範圍的參數值,看看你的程式碼會不會掛掉) * 測試字串超出長度 * 字串不符合規定的跳脫字元 * 有非Ascii亂碼 # Unit test in Isolation  * Other Class 讀取檔案 * 不會包那麼大包的原因 * 因為會讓測試成本、代價過高 * 如改寫資料庫 * 因此使用假的Dummy Object來做取代  ## Mocks and Other Test Double  * Dummy Object * New 一個 Dummy 物件,只為了能夠讓Player建立出來 * Fack Object * 已經有Interface,需要去繼承 * 建立一個新的Class * Test Stub * Constructor injection * 讀檔案,會直接讀取,但測試實不希望干擾到系統 * 建立Constructor injection:  * 將CUT的Code做更動,放入假資料mgr Fack Object VS Test Stub?? # External Dependency: Test Stub ## External Dependenncy in a CUT * 一個物件與你的系統必須有互動 * 對他沒有控制力 * 初始代價過高 * 牽涉到不可分離性: 會做實體的操作 * 對資料庫修改 ## A Stub * 可控制的取代依存之物件,創建一個假的模擬你需要的物件 * A stub can never fail the Test * Intercept 攔截 * Unit Test單元測試的基本 ### Aproach 1 : Fakes via Duplication: 類似Copy   * 無法隨心所欲單元測試 ## Aproach 2 : Dependency Injection : 修改建構值 * constrictor Injection (建構值隔離) * 只需要動態轉換物件即可 * Constroctor 只需要專注初始化記憶體與變數即可 ### 物件導向的原則: LoD(Law of Demeter) * 是否有複雜化的行為 * 給店員25元,是直接給錢包,還是拿25就好D * 建構值:  * engine = factory.... => 不應該出現在這裡,汽車何必知道工廠的資訊 * 應該在外面New 再丟進來 * 太多的物件繼承 :  * 有太多的問號,不知道該測哪一個 * 物件繼承被濫用 *  * 正確 :  * If you dont't take advatage of polumorphism : 如果沒有要用多形,請把繼承拿掉 * B繼承A,B is A * 把不對的繼承換成Composition * (絕對不要!!)不要用繼承來Reuse你的Code * Testability * Seams (介面) ### Exaple 3  * 該測試為甚麼難寫 * 牽涉兩個物件 * Customer * Money( wallet ) * 歸咎於你的Poor物件導向 *  * 修正後的結果:  * 將原本在purhase 呼叫 錢包 的動作,更改成只Input錢錢 * 相較上述,明顯少了兩個物件的宣告 * 原本應該專注於 Good,卻有多放入Money與Customer,以至於無法 test isolation * 若兩個物件是正確的倒還好 * 最壞情況,會導致無法準確精準測試Good ## Approach 3: Testing with Mocking Framework * legency 老舊系統是否能夠Testing?? * 想補也很難補救 * 可能需要重構 * 透過圈出小範圍 ### Proble, with Stub * 必須重新撰寫或新增另一個 * 測試不一樣的測試資料 * 動態測試資料 * 當測試Stub 會隨著修改或新增 * Stub 會隨著不一樣的條件回傳不同值 * 當 Interface 更新 也需要一起更新 * #### Fragility of test case: 脆弱 * 開發時的變動,也讓你經常更動一大堆單元測試,表示程式或單元測試有一些脆弱與易碎性 * 開發階段常更動 * Class * methods * methods signature * interface * 必須探討開發流程是否有問題 * 物件導向 * 系統設計 * 隕石開發法 * 上帝 * 老闆 * 客戶端 ### Mocking framework * JUnit * Mockito * JMockit * EasyMock #### Mocking to replace * 相關方法:  * 程式碼案例:..... .....  * tuormock => TeachStub取代:  * 語法:  * 介面宣告:  * tutormock.checkin(): 確認是否有值 * When(...).thenRewturn(...): 負責造假 * V.S.:  * 都被取代掉了 * 語法2(callBack):  ### Another External Dependecy: Mock  * 測試的麻煩事情 * TCP 測試 * 需要再準備一個TCP Server * 無準備,會卡住 Block *  * #### State-Based vs Interaction testing (behavior testing) * 如何知道灑水裝置定時灌溉 * state-based: 在乎結果,有許多狀況未被測試到,較為不精準(shit屎) * 跑12小時 * 跑完後 * 檢查花草 * 檢測土壤濕度 * 是否枯萎 * 目前大部分的測試 * Interaction Testing: 在乎過程 (behavior object) * 頭尾安裝: 流量偵測器 * Mock: 0記錄所有呼叫行為 #### TestStub vs Mock * State-base Testing * A stub can never fail the test * Stub 通常模擬 內部物件之正確行為 * TestOracle 所要 assert 的正確性在 CUT的行為,不會再Stub 裡面 *  * assert(,XXX()) * Interaction-Based * Mock 通常模擬 內部物件接收 SUT 送出的Information * Mock 會記錄CUT與自己的所有內部互動 * Tesr Oracle 所要的 asser 的正確型,會在Mock 收的訊息 *  * 比較Care * 呼叫什麼 * 每一次的參數 * API 倍呼叫的頻率 * 常見行為 * Real external objects (dependency) 在呼叫之後沒有回傳值,或是任何可以讓你驗證external objects 狀態(state)的方法 * 硬碟讀寫 * 資料庫讀寫 * 網路讀寫 (這是最常見的例子) * 檔案讀寫 * Real external object 會實質更改資料 * Real external object 有 nondeterministic (不確定性)行為 * Real external object 很難觸發 * Real external object 很慢 * Real external object 是 user interface * Real external object 使用 call back * Real external object 的行為不容易觸發 * verify().XXX(): 根據流程驗證,是否是相同 Func  *  ##### Exception Handling   # test-isolation    * DummyObject *  * Fack Objet * a Test Stub acts as a control point to inject indirect inputs into the SUT the Fake Object does not. It merely provides a way for the interactions to occur in a self-consistent manner ## Exceptions from teststub ### 真實的 external dependency – Teacher 會丟 exception 嗎? * SC SHOULD catch 並且處理掉 * SC IS DESIGNED NOT to catch,pass the exception upward * * 如果會,那 tutormock 也應該模擬丟出 exception * 一般而言 test stub never fail the test,而且模擬所有正確的行為 * 產生了一個不存在學生的名字 * 呼叫 Teacher 的時候,傳的參數都沒有問題,但是真實 Teacher 因為學校的資料庫系統有問題 #### Case 1 :StudentCollection (SC) SHOULD catch (by design)  一般的原則是你在 test code 裡面是不會去 try catch 的。其原因如上 #### Case2: SC IS DESIGNED NOT to catch,pass the exception upward  test cases ALWAYS fail,你的 DEVOP pipeline 永遠都不會過 !
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up