iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
Mobile Development

在 iOS 專案上加上 Unit testing - 因為 You need testing系列 第 4

D4 - 在 iOS 專案加上測試-You need testing {情境假設: 在專案中擴充 feat 時,你會遇到的狀況}

  • 分享至 

  • xImage
  •  

以下是某種情境假設,在「app 迭代的過程中,Unit testing 可以怎麼幫你」

  • 你寫一個 app,裡面有個類別-使用者。
  • 需要在某一個頁面,呈現後端儲存的資料,其中有 first name & last name
  • 但前端顯示的時候,要組合起來,變成 firstName lastName

這個物件可以這樣宣告

struct Customer {

    let firstName: String

    let lastName: String

    var displayName: String {

        return firstName + lastName
    }
}

• App 推出後大賣,不過!歐美 sales 反應,他們的客戶有些有 middle name,而且被強烈要求在 UI 上呈現出 middle name。所以需要在 user 顯示名稱那邊,顯示 middle name。因為有一個成員剛進來

struct Customer {

    let firstName: String

    let lastName: String

    var middleName: String?

    var displayName: String {
        /// 因為這任務交給一個剛來的人寫,所以那個人就這樣寫了
        return firstName + middleName! + lastName
    }
}

果不其所然,沒有意外的話,就要發生意外了。新的使用者,可能都沒問題,但如果是舊版本的使用者升級到新版,原來的程式並沒有存下 middleName,因為那個時期這個 property 不存在,所以每個升級的使用者都遇到了 app 閃退的問題。

修復後,這個物件宣告長這樣。

struct Customer {

    let firstName: String

    let lastName: String

    var middleName: String?

    var displayName: String {

        /// 如果是有中間名的 user,就呈現中間名
        if let middleName = middleName {

            return firstName + middleName + lastName
        }

        /// 如果是沒有中間名的,就不處理 middle name
        return firstName + lastName
    }
}

然後再經過幾次行銷活動,這個 app 更紅了。某天你被叫進需求會議,接到了亞洲區 Sales 的需求。

• App 修改完後更大賣,但亞洲區 sales 反應,姓要在名字前面。且中間不要空格

這邊就省略程式碼,不斷的進行時間快轉。

下一個需求

• 日本 sales 反應。日本 UI 如果呈現姓加名字黏在一起,會讓特殊姓氏不知道怎麼念,而且日本人習慣姓和名中間空一格

下一個需求

• 馬來西亞 sales 反應,他們的中間名可能有五個起跳,但習慣上可能用不同於其他國家的方式進行呈現。所以需要先判斷 x 條件,然後符合 y 條件時,呈現 z UI。

上面所述的這個狀況,是會不斷的發生的。改需求,改文案,增加銷售地區,因為增加銷售地區所以增加了新的需求。當你手上的程式碼註定會碰到這樣的變化,Unit testing 會在哪些狀況下幫到你呢?

繼續擴充 Customer 物件時,Unit testing 會怎麼幫你

我們遇到了單一 data model 在不同 locale 時,要呈現不同的排列方式。在這個情況下, Unit testing 會怎樣幫助你的專案呢?

/// 
struct Customer {

    let firstName: String

    let lastName: String

    var displayName: String {

        return firstName + lastName
    }
}

針對 Customer 物件的第一版 Unit testing

在 Xcode 中,要讓一個 func 能在 unit testing 中被認知到,func 宣告時前四個字母要是 test,才能被模組認知到這是 test。這邊宣告 func testCustomerDisplayName()。按一下 cmd + B,這時這一行左方的行數號碼,應該會變成一個菱形,表示這是測試 func。

https://ithelp.ithome.com.tw/upload/images/20230915/201406223usRwAUVb5.png

final class CustomerNameTests: XCTestCase {

    override func setUpWithError() throws {}

    override func tearDownWithError() throws {}
    
    func testCustomerDisplayName() {
        
        let customer = Customer(firstName: "Foo", lastName: "Bar")
        
        let answer = "FooBar"
        /// 第一次跑 unit testing,會讓 testing failed,來確保 unit testing 是正確運作的
        XCTAssertEqual(customer.displayName, answer)
    }

}

開始跑完 Unit testing,你會看到錯誤,表示 Unit testing 有正確運作,未來如果 data model 有錯時,這個 Unit testing 可以正確的告訴你程式有錯誤。接下來,我們把 XCTAssertEqual 的第二個參數改成 answer。改完後跑一次 Unit testing,這時原來的錯誤就消失了。

https://ithelp.ithome.com.tw/upload/images/20230915/20140622mLxEW9BkqX.png

如果那位工程師擴充了 middleName, 並使用了 force unwrap 在 displayName 中,會怎樣呢?

/// 第二版 Customer 物件,而 property 的擴充交給另一個工程師
struct Customer {

    let firstName: String

    let lastName: String

    var middleName: String?

    var displayName: String {
        /// 因為這任務交給一個剛來的人寫,所以那個人就這樣寫了
        return firstName + middleName! + lastName
    }
}

https://ithelp.ithome.com.tw/upload/images/20230915/20140622qm6P8JI8pJ.png

從圖上可以看到,Unit testing 運行時,他在這一行會停下來,因 Unit testing crash 了。這就表示這段程式碼在產品上,也可能造成 app 閃退。

修改後的程式碼

struct Customer {

    let firstName: String

    let lastName: String

    var middleName: String?

    var displayName: String {

        /// 如果是有中間名的 user,就呈現中間名
        if let middleName = middleName {

            return firstName + middleName + lastName
        }

        /// 如果是沒有中間名的,就不處理 middle name
        return firstName + lastName
    }
}

運行後,都是綠燈,表示程式碼是安全的。但現在的 Unit testing,並沒有辦法測到有 middleName 的 user,因為 Unit testing 中並不存在測試 middle name 的程式碼,我們現在把這一段補上。

step1: 要先讓 unit testing failed。

https://ithelp.ithome.com.tw/upload/images/20230915/20140622imTToNwTis.png

step2: 換上 answer 並確保前一個 test 也通過

https://ithelp.ithome.com.tw/upload/images/20230915/20140622UDF27XC7dI.png

如果同一個專案的開發者是有寫 testing,並正確的使用 testing,那個會讓客戶閃退的程式碼,就不會發出去了。而接下來的各區 sales 的要求,在這個習慣下,也能穩定的產出符合 sales 需求的程式碼。

還記得後面的虛擬需求嗎?你可以試著寫一下這些需求的程式碼

• App 修改完後更大賣,但亞洲區 sales 反應,姓要在名字前面。且中間不要空格

• 日本 sales 反應。日本 UI 如果呈現姓加名字黏在一起,會讓特殊姓氏不知道怎麼念,而且日本人習慣姓和名中間空一格

• 馬來西亞 sales 反應,他們的中間名可能有五個起跳,但習慣上可能用不同於其他國家的方式進行呈現。所以需要先判斷 x 條件,然後符合 y 條件時,呈現 z UI。


上一篇
D3 - 在 iOS 專案加上測試-You need testing {可測試的程式碼的通常長什麼樣子}
下一篇
D5 - 在 iOS 專案加上測試-You need testing {從後端回來的 json 開始寫測試 part 1}
系列文
在 iOS 專案上加上 Unit testing - 因為 You need testing32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言