測試


Posted by TempuraEngineer on 2022-03-12

測試是甚麼?

軟體測試是一種自動化的過程,它能對code進行斷言來判定結果,進而確保codebase的不崩壞。

測試可以粗略分成以下幾種

  1. 單元測試(unit test):測一個獨立的module、fuction、class的邏輯
  2. 組件測試(component test)
  3. 整合測試(intergation test):測試module、fuction、class之間交互作用
  4. 功能測試(functional test)
  5. 系統測試(system test)
  6. E2E test:模擬使用者行為去操作產品,測畫面

測試前的準備工作

撰寫測試前需要先通用和抽象的要求淬煉成細節,然後寫成測試文件。

  1. 「管理員要能成功登入後台網站」
  2. 淬鍊成「管理員要可以在帳號、密碼input輸入正確的帳號、密碼,點下登入後成功登入」
  3. 寫成測試文件


測試的替身物件(test double)們

test double有5種-dummy、stub、fake、mock、spy。在測試時,SUT會是用真物件,而DOC通常會用假物件,這個假物件就是test double。

  • SUT(System Under Test / 測試目標)
  • DOC(Depended-on Component / 依賴元件)

dummy object

就只是個讓程式成功跑的假資料,不會對SUT造成影響。

export fakeData = [{name:'Bella', age:20, gender:'F'}, {name:'Jack', age:25, gender:'M'}, {name:'Vivian', age:50, gender:'F'}];


test stub(虛設常式)

寫死的假物件,方法的回傳值是寫死的,不會依測試時的情況做改變。著重在試狀態(state testing)

// 假設有一個真的function如下

declare type op = '=' | '>' | '<';

async function getData(tableName:string, condition:{left:string; op:op; right:string|number}[]):{name:string; age:number; gender:string}[]{
    await fetch('https:.....',{
        method:'GET',
        header:{
                 Authorization: Authorization,
                 "X-Date": GMTString,
                 "Content-Type": "application/x-www-form-urlencoded"
               },
       body:JSON.stringfy({table:tableName, condition:condition}),
       Accept-Encoding: 'gzip'                         
       })).then((d) => {return d.data;})
}
// stub可能長這樣
const stub1 = jest.fn(() => {
    return [{name:'Bella', age:20, gender:'F'}, {name:'Jack', age:25, gender:'M'}, {name:'Vivian', age:50, gender:'F'}];
});

// 或者這樣,之所以是空的是因為有時只是要確認有叫到function而已
const stub2 = jest.fn();


fake object

真物件的簡化版。裡面的資料都是寫死的,它只會模擬真物件的行為來回傳資料。

// 跟上一個例子一樣有一個getData function,它的mock可能長這樣

const fake = (tableName:string, condition:{left:string; op:op; right:string|number}[]) => {
    if(condition[0].left === 'name'){
        return fakeData.find((i:any) => i.name === 'Bella');
    }

    if(condition[0].left === 'age'){
        return fakeData.find((i:any) => i.age === 20);
    }

    if(condition[0].left === 'gender'){
        return fakeData.find((i:any) => i.gender === 'F');
    }
}


mock object(模擬物件)

一個幾乎完全替代真物件的假物件。驗證方法預期被調用的情況(ex:呼叫function次數及返回值),著重在行為(behavioral testing)

// 跟上一個例子一樣有一個getData function,它的mock可能長這樣

const mock = (tableName:string, condition:{left:string; op:op; right:string|number}[]) => {
    let res = fakeData;

    condition.forEach(d => {
        switch(d.op){
            case '>':
                res = res.filter((i:any) => i[d.left] > d.right);
                break;
            case '<':
                res = res.filter((i:any) => i[d.left] < d.right);
                break;
            default:
                res = res.filter((i:any) => i[d.left] === d.right);
                break;
        }
    })

    return res;
}

簡單說的話stub、fake、mock都是真物件的簡化版,差在模擬的精細度。

difference betweeen mock & stub

mocks vs stubs

difference between faking, mocking and stubbing


TDD & ATDD & BDD

  • TDD(test driven development / 測試驅動開發)
    從單元測試的角度出發(開發者的視角)。只有在測試失敗時才來改code,在敏捷開發的領域很受歡迎。

    1. 開發者根據規格文件制定test case
    2. 跑測試
    3. 改沒通過測試的code
  • ATDD(acceptance test driven development / 驗收測試驅動開發)
    從軟體需求的角度出發(著重在使用者的視角)。需要跨部門合作。

    1. 先討論需求(真實操作時會發生的情況)
    2. 訂定驗收測試,
    3. 開始根據規格寫test case
    4. 跑測試
    5. 改沒通過測試的code
  • BDD(behavior driven development / 行為驅動開發)
    衍生自BDD,TDD與ATDD的綜合體,從系統行為(Then)的角度出發。常用Given-When-Then格式來規劃test case。

    1. 用(Given-When-Then格式)描述行為

      Given the user has entered valid login credentials
      When a user clicks on the login button
      Then display the successful validation message
      
    2. 寫test case

    3. 跑測試
    4. 改沒通過測試的code


📖

什麼是SUT與DOC
Unit Test 中的替身
BDD vs TDD vs ATDD : Key Differences


#測試 #mock #stub







Related Posts

『Android』ADB Debug by wifi 用Wifi連線來Debug

『Android』ADB Debug by wifi 用Wifi連線來Debug

Python 串列 list 和元組 tuple入門教學

Python 串列 list 和元組 tuple入門教學

Linkedin  Java 檢定題庫 static import

Linkedin Java 檢定題庫 static import


Comments