code

顯示具有 Software Testing 標籤的文章。 顯示所有文章
顯示具有 Software Testing 標籤的文章。 顯示所有文章

2017年11月27日 星期一

Software Testing 5 - Code Review and Defects

Code review

code review / inspection對找出defects很有幫助,不過實務上似乎很少進行。通常能透過code review找到的defects如下:

1. 缺少或是錯誤的comments
2. 重複性的code
3. 過於複雜的設計
4. 無法測試的路徑
5. 錯誤使用技術
6. coding errors (這啥?!)

 細分的話,其實code review還可以分成以下三類:
1. walkthru:
找個senior的幫你看一些部分,稱為peer review。

2. code review:
這是最常進行的,可能牽涉多個reviewers,主要檢查implementation。


3. inspection
這是最正式的code review流程,可以有以下腳色:

Moderator – works with author to schedule inspection, send out materials, runs meeting, follows up with author on follow-ups from inspection (often team lead or project manager)
·         Author – provides moderator with inspection material, explains material as needed, responds to questions, responsible for rework based on inspection comments
·         Reader – walks though the code, saying what it does in English and stops for comments on that piece
·         Reviewer – technical experts for the document being inspected; provides comments and questions

·         Recorder – one of the reviewers who agrees to document issues raised at the meeting; usually compiles a list with categories (defect, suggestion, comment, etc.) and distributes to all after meeting; opens internal defect reports to help track fixes


Defect Management

俗稱bug XD,就是不按照design發生的行為。

defect不一定能找出來,找出來也不一定要或能修改,修改後也不一定正確。
所以必須要有系統性的方法來面對defects,需要一個defect tracking system。

defect 可以有類似以下的tracking status:



Defect Report


defect reports不只是展現QA人員的專業,也是developers的重要資產。
defect report需要包含以下:
1. isolation: 切割出可以復現的操作方法
2. generalization: 即便切割出來,但仍需要考量此defect對整體性的影響
3. severity: bug分級定義,根據發生機率以及衝擊性

綜合以上,一個可能的defect report template長這樣:

Item
Description
Title
A unique, concise and descriptive title for a defect is vital. It will allow the defect to be easily identified and discussed.
Good : “Closed” field in “Account Closure” screen accepts invalid date
Bad : “Closed field busted”
Severity
An assessment of the impact of the defect on the end user
Status
The current status of the defect
Initial configuration
The state of the program before the actions in the “steps to reproduce” is to be followed. All too often this is omitted and the reader must guess or intuit the correct pre-requisites for reproducing the defect.
Software
Configuration
The version and release of software-under-test as well as any relevant
hardware or software platform details (e.g. Win 7 vs Win Vista)
Steps to Reproduce
An ordered series of steps to reproduce the defect
Good :
1. Enter “Account Closure” screen
2. Enter an invalid date such as “54/01/07” in the “Closed” field
3. Click “Okay”
Bad: If you enter an invalid date in the closed field it accepts it!
Expected behavior
What was expected of the software, upon completion of the steps to reproduce.
Good: The functional specification states that the “Closed” field should only
accept valid dates in the format “dd/mm/yy”
Bad: The field should accept proper dates.
Actual behavior
What the software actually does when the steps to reproduce are followed.
Good: Invalid dates (e.g. “54/01/07”) and dates in alternate formats (e.g.
“07/01/54”) are accepted and no error message is generated.
Bad: Instead it accepts any kind of date.
Impact
An assessment of the impact of the defect on the software-under-test. It is
important to include something beyond the simple “severity” to allow readers to understand the context of the defect report.
Good: An invalid date will cause the month-end “Account Closure” report to crash the system and corrupt all affected customer records.
Bad: This is serious dude!
(Proposed solution)
An optional item of information testers can supply is a proposed solution.
Testers often have unique and detailed information of the products they test and suggesting a solution can save designers and developers a lot of time.
Priority
An optional field to allow development managers to assign relative priorities to defects of the same severity
Root Cause
An optional field allowing developers to assign a root cause to the defect such as “inadequate requirements” or “coding error”



Root Cause Analysis

root cause analysis通常有助於降低未來defect發生的可能性,可能的種類如下:

Classification
Description
Requirements
The defect was caused by an incomplete or ambiguous requirement with the result assumption differing from the intended outcome.
Design Error
The design differs from the stated requirements or is ambiguous or incomplete resulting in assumptions.
Code Error
The code differs from the documented design or requirements or there was a syntactic or structural error introduced during coding.
Test Error
The test as designed was incorrect (deviating from stated requirements or design) or was executed incorrectly or the resultant output was incorrectly interpreted by the tester, resulting in a defect “logged in error”.
Configuration
The defect was caused by incorrectly configured environment or data.
Existing bug
The defect is existing behavior in the current software (this does not determine whether or not it is fixed).



2017年11月25日 星期六

Software Testing 4 - Test case, suite, report

Testing the design

requirement / documentation / spec 其實也可以test,主要針對以下五個方向去檢驗:
1. specific: 越明確越好
2. measurable: 能夠量化
3. testable: 其實就是1. 2. 的結果
4. consistent: 要跟先前的spec一致
5. exclusive: 把"不該做的"也明列出來。


non-functional (non-feature) test cases

非功能性的tests,包括:
1. usability
2. scalability
3. performance
4. security
5. logging
6. reliability
.
.
.
通常是functional test通過之後,才會進行non-functional tests。


Performance testing

舉performance testing來說,一個明顯困難點在於通常不能用production environment來測試,因為會影響營運,所以必須有一個test environment來模擬production environment。

此外performance testing重點在測試系統弱點,這屬於白箱測試,只有系統開發者知道哪些是可能的弱點,不要因為"政治因素"害怕去測試這些點的極限。

此外要有baseline當比較對象,因為有些時候performance improvement沒什麼太大意義,如果baseline profile已經達到,可能不需要投入資源去提升performance。

performance testing包括以下種類:
1. load testing: 測試在不同的load狀態下,系統有什麼behavior
2. stress testing: 找出系統能承受的最大capacity
3. soak(endurance) testing: 主要瞄準長時間狀態下,系統的在某個load的承受能力
4. spike testing: 這是測試突然增加極大load會讓系統產生什麼行為


Test plan的重要性

test是要規劃的! 不是自己隨興加減測試,事實上這是一個挑戰!
先要有個認知是: 100% coverage是不可能的。

事實上要把test plan當成一個project,所以也會有project management中需要考量的三元素: resource / budget / schedule。

所以選擇測試標的,也是一個學問,可能的方向:
1. 趕時間做出來的item
2. remote data / api 接介
.
.

test coverage廣度: 盡可能發現系統中潛在bug
test coverage深度: 在某些容易發生bug的系統,大量重複深入測試


Test Suite

就是一堆test cases的集合,歸類成某一類。


Test report

可能包含以下項目:

1. scope: 測試涵蓋了那些範圍,也該列出未涵蓋的範圍
2. 測試通過標準: 那些問題一定要fix,test cases通過率
3. 測試方法
4. 最後結果
5. defects/status: 列出目前測試出來,尚未解決的defects

上面講的有點籠統,主要是還是要看相關人員想要看到資訊才能做後續決策。




2017年11月18日 星期六

Software Testing 3 - UAT (User Acceptance Testing) and Usability Testing

Human Testing

UAT就是提出requirement的user去驗證(validation)我們寫的程式是否符合他們requirement。
UAT test plan在design phase就會底定,UAT會在開發完成後進行。
UAT不只是以requirement為基礎來validate,也應該要以user scenario來驗證。

UAT的主要挑戰

如果定義UAT在開發完成後才進行,所以要改變需求或是feature是很困難的,通常是不允許的。

敏捷開發建議客戶參與開發流程的意味,事實上這是比較好的方式,漸進式mini UAT變成正式開發流程之一,要求UAT測試者簽署測試通過文件(formal acceptance),確保嚴重的design defects不會在開發結束才發現。


各種Acceptance Testing

不是只有UAT,還有:

1. Factory Acceptance Testing: 經銷商在供貨前測試
2. Site Acceptance Testing:在客戶端安裝後測試,主要是整合性
3. Operation/Production acceptance testing: 主要測試功能性
4. Compliance/Regulation acceptance testing:法規測試

Usability Testing

這是關於好用與否,主要領域是HCI / UX,在此掠過。


Alpha/Beta Testing

alpha主要是內部測試,beta是外部測試。
alpha階段應該就要找出工程上的major defects,讓beta階段著重在使用者回饋修改,因為beta階段可以算是模擬營運階段。


Software Testing 2 - Autotest and Statement Coverage

節省成本

長期來說,理想上寫一次test case卻能無限多次測試,這是非常節省時間與成本,又增進software robustness的方法。

多人共同開發的必須流程

特別是在agile methods的規範中,一天可能會release several times,每次integration回去main branch一定要經過大量的測試,此時需要auto test cases。


製作Auto test cases的代價

unit test很簡單,也很快速可以寫完,在開發過程就可以順便做完。
function test (integration test)則要花更多時間,因為他是要測試模組間的互動,以及一些code path,所以有時候其實手動測試會比寫一個function test快,視情況而定。

事實上 testing program 也是code,理論上所有開發流程都也該應用在test cases上,包括test the test cases!
不過這樣有點弔詭,理論上寫得夠清楚的話,test cases不需要再被test,要不然不就沒完沒了。

test cases也要被放入一個testing repository,就跟一般的code一樣需要版本管理與維護,這些都是成本!

如果test cases需要時常更改變動,那可能這個project不適合auto test,因為維護成本會大於效益。


Automate 什麼標的?

1. 有testing framework support的語言或是開發環境
2. 很穩定不常變動的requirement / spec
3. 重複性高的測試,regression bugs
4. 人類能力無法勝任的test
5. 多組input data / cross platform tests
6. concurrency
7. 花大量時間者 (可以auto test就跑回家睡覺)


JUnit

JUnit可以寫unit test也可以寫function test,語言當然就是Java,所以叫JUnit。

JUnit提供一些predicates,回傳某些條件的true or false,unit test最好只要測試一個predicate,這樣才能說是"unit test",否則如果使用了兩個以上的predicates,由於第一個predicate failed的話, JUnit就會停止測試這個test,那會讓測試者誤以為整體program的test failure很少的錯覺,因為同一個unit test中的其他的predicates都沒被測試到。


Code Statement Coverage

下圖的default constructor需要兩個test cases,分別測試constructor中的兩個instance variable值是否正確:


注意每個test case應該都只能測試一個值!
為什麼我們要測試這個相當簡單的assignment statement? 因為這是spec,如果未來有人改變了constructor中的assignment,就是違反了spec,則我們的test cases就能抓到!

test cases如下:




以下的second constructor需要四個test cases,分別是執行line32, 36, 39, 40,if statement不需要測試,因為那無法驗證什麼東西:


相對應的test cases如下:





通常我們不需要測試getters,因為他的執行是trivial顯而易見的:


以下這個method事實上只需要一個test case就可以測試所有statements line 59,62,63,65:


因為全部都是連動的。

test case如下:




Branch coverage

branch coverage重點在要執行過所有conditional statement的true / false test,在上面提到的constructor中:


這邊需要4個test cases來測試兩個if,else statement則是跟隨著第一個if被測試了。
如果同時做statement coverage的話(已經測試所有if 為true,以及else為true,共3個branch被covered),我們這邊只需要再做一個test case 來測試第二個if 是false的狀態即可。

同樣的,對以下的method來說,如果已經做了statement coverage,則branch coverage只要再加上一個while condition evaluates to false的condition即可:





Path Coverage

path就是測試所有method最後return的路徑,例如上述的constructor:


有三個paths: 兩個throw statement,以及都沒有throw exception,最後隱性的從Line41 return的path。



Data Coverage

這邊稍微紀錄一下data coverage,主要就是測試spec中的臨界值,光是statement coverage是無法測試到所有的臨界值或是極大小或是特殊值。

2017年11月11日 星期六

Software Testing 1 - test basics

Validation & Verification

validation = 達到使用者的需求功能
verification = 做出來的需求功能,有正確implement

這兩個面向都正確,才能說這個software正確


好的Test Cases特徵

1. 一次只測試一個部分
2. 測試的目的必須要明確符合規範
3. 描述方式要簡單清楚
4. 範圍要小
5. 要獨立,不依賴任何其他test cases
6. 要最可能精簡
7. 要跟spec/requirement相關
8. 要能重複結果
9. 描述用詞要一致


Software Development Life Cycle (SDLC) model

理想上來說,testing應該要發生在SDLC的各個階段:
1. 需求分析階段:  分析需求是否能測試
2. 系統設計階段: 發展test coverage plan, 以及設計usability test
3. 實作階段: 實作unit tests / automatic tests
4. 整合階段: integration tests
5. 發布階段: UAT (user acceptance test) / usability test (scenario based)
6. 營運階段: regression test如果有任何code change

以上是理想狀態 XD


白箱與黑箱測試

白箱:測試者能 access source code,e.g. unit tests
黑箱:白箱的相反,e.g. UAT


Test Coverage

有三種coverages:

1. code coverage: 理想上是100% statement coverage,也就是所有的code都有tests“照顧”到。很多開發framework都有code coverage tools,例如Android Studio。

又可依照詳細程度分為statement coverage / path coverage / branch coverage

2. data coverage: 測試涵蓋一些代表性的input數據。我們通常不可能有100% data coverage,例如不可能測試所有的integers。不過可以測試一些特殊cases:


  • boundary condition - 各種邊界值
  • typical data - 代表性的input
  • pre / post conditions - input前後的facts
  • bad data - 測試不合API的值,例如null / 極多極少量 / 空集合 / 未初始化
3. model-based coverage: 這個採用分析整個程式與input domain來建立test case的測試模型,算是非常分析導向的,在此略過了,因為我現實上應該不會採用這樣的approach。


Unit Test

通常這是開發者的責任,可以視為開發過程跟寫code一樣重要的產出,某些agile methods可以讓testers跟developers一起合作寫出unit tests。

unit tests最好是很小的單位,例如function / method / class,而且最好能100% code coverage。
如果有100 code coverage,不能保證沒有bug,但是能提高code change時的信心與品質,特別是需要做refactoring的時候。


Functional Test 

這應該就是integration test,測試整個program的inputs / outputs / features。
這可以算是黑箱測試,你要假裝不知道整個program的implementation。

當然最好是automated tests。