Testing ứng dụng của bạn trong Xcode (Phần 1 Unit test)

Ứng dụng hoặc bất kì sản phẩm nào trước khi đến tay người dùng, đều phải trải qua 1 quá trình test cẩn thận. Khi nói về test nhiều người sẽ nghĩ người tester sẽ ngồi hàng giờ kiểm tra từng màn hình, từng nút bấm để phát hiện ra điều bất thường và báo lại cho nhà phát triển,thường một ứng dụng lớn thì đội tester sẽ mất rất nhiều thời gian để kiểm thử từng chức năng, thậm chí sau đó dev có thể thay đổi code và sau đó tất cả các việc test của tester sẽ phải bắt đầu lại khá mất thời gian Vì lý do đấy nhiều công ty đang bắt đầu viết automation test cho project của họ, hình ảnh phía giới biểu thị các loại test

Tính từ giới kim tự tháp đầu tiên là Unit test, sau đó đến Integration Test và cuối cùng là UI test

Unit testing là gì ?

Unit test là một trong những khái niệm căn bản nhất của automation test, là phương pháp kiểm tra tính đúng đắn của một đoạn mã nguồn

Integration test

Tương tự như Unit test điều khác biệt ở đây là nó có thể cover rộng hợn so với Unit test, đối với Unit test thì nó chỉ cover được một phạm vi logic rất nhỏ của app, còn Integration test có thể cover được chức năng của một hệ thống nhỏ kết hợp giữa class và function

UI test

Là bước cuối cùng của automation test ,UI test chạy lâu nhất so với hai thằng còn lại, nó có khả năng gi lại những tương tác của user lên giao diện và chuyển nó thành mã nguồn

Performance Testing

Unit test chạy nhanh nhất
Tiếp đến integration test
UI test tốc độ chạy chậm nhất

Trong bài viết này chúng ta sẽ tìm hiểu ở bước căn bản nhất của testing đó chính là Unit test

Lợi ích của Unit test

Unittest hữu ích khi làm việc với codebase lớn, khi dự án phải làm việc với nhiều dev khác tiết kiệm thời gian thay đổi chỉnh sửa chức năng mà không sợ ảnh hưởng đến code của ông khác hạn chế bug phát sinh, mình đã từng đau khổ khi maintain các dự án cũ nhưng không có unittest kết quả là sửa tính năng này, thì lại hỏng tính năng kia vì các tính năng đều liên quan đến nhau nên code có unittest thì sẽ gíup bạn gỉai được quyết vấn đề này

Thực hành

Bước 1 Tạo project

Chúng ta tích vào include Unit test và UI test như mình mô tả

Bước 2 Chúng ta sẽ có 2 thư mục UI test và Unit test

Chúng ta sẽ tiến hành viết code test cho từng phương thức test trong 2 thư mục này

Một unit test sẽ test 1 case cụ thể, và trong một phương thức thường sẽ có 4 bước

1 Setup

Khởi tạo classs mà bạn muốn test

2 Execution

Gọi những phương thức ở trong class

3 Expection

Kiểm tra kết quả mong đợi của kết quả trả về

4 Clean up

Chúng ta có test case đơn giản như sau

Case 1 Người dùng đăng nhập tài trạng thái active

Setup:Tạo một function phương thức đăng nhập user

Execution:chạy function

Expection: trả về True

Case 2 Người dùng đăng nhập tài trạng thái inactive

Setup:Tạo một function phương thức đăng nhập user

Execution:chạy function

Expection: trả về False

Bây giờ chúng ta sẽ chuyển đoạn mã giả trên thành code nào, đầu tiên khi tạo project chúng ta sẽ tích vào Unit test nhé

 enum UserStatus:Int {
    case  active = 1
    case inactive = 2
}

enum BiometricType:Int {
    case figgerPrint = 0
    case faceId = 1
    case enterText = 2
    case wrongPass = 3
}

enum LoginStaus:Int {
    case scucess = 0
    case failure = 1
}

 func performGetStatusUser(userStatus: UserStatus, biometric: BiometricType) -> LoginStaus {
            if userStatus == .active {
                switch biometric {
                case .figgerPrint:
                    return .scucess
                case .faceId:
                    return .scucess
                case .enterText:
                    return .scucess
                case .wrongPass:
                    return .failure
                }
            } else {
                
                return .failure
            }
        }

Bây giờ chúng ta sẽ viết test cho function trên chúng ta tạo một class kế thừa từ thằng XCTestCase nó chứa các test function test case

import XCTest
@testable import Binance // import tên project chúng ta muống test vào 

class BinanceTests: XCTestCase {
    public var viewHome = HomeViewModel()
    
    override func setUp() {
        super.setUp()
        viewHome.binding(delegate: self) // khởi tạo  class mà chúng  ta  muốn test  
        
    }
    
    override func tearDown() {
        super.tearDown()
        viewHome.unbinding(delegate: self)
    }
    
    func test_UserStatus () {
        let userStatus  = viewHome.interactor.performGetStatusUser(userStatus:.active, biometric: .faceId) == .scucess
        XCTAssertTrue(userStatus, "valid")
    }

Setup là phương thức khởi tạo các phương thức test TearDown là phương thức clean sau mỗi phương thức hoàn thành test case nó thực thi theo cơ chế LIFO

Để chạy được test case chúng ta có thể dùng tổ hợp phím Comand + Shift+ U để chạy toàn bộ test case or chúng ta có thể bấm vào test case mà chúng ta muốn chạy

Với test case đầu tiền kết quả mà chúng ta mong đợi là True

Với test case thứ 2 kết quả mà chúng ta mong đợi là False

Chúng ta có một class Helper như này, nhiệm vụ của chúng ta là viết test case để xem cái function stringToDate này có sau khị truyền 2 tham số là date dạng string và kiểu format thì có convert được về date hay không


import Foundation

class AppHelper {
    
    static let shareInstance = AppHelper()
    
    func stringToDate(dateStr:String,format:String) ->Date? {
        let dateFormatterGet = DateFormatter()
        dateFormatterGet.dateFormat = format
        
        guard let dateResult  = dateFormatterGet.date(from: dateStr) else { return  nil}
                
        return dateResult
    }
    
}



Chúng ta sẽ test function stringToDate này chúng ta sẽ có Test case như sau

Case 1 Dữ liệu truyền vào đúng format

Setup:Tạo một function truyền kiểu date dạng string và,và format mong muốn

Execution:chạy function

Expection: trả về khác nil

Case 2 Dữ liệu truyền vào đúng format

Setup:ạo một function truyền kiểu date không đúng định dạn, và format mong muốn

Execution:chạy function

Expection: trả về bằng nil

Bây giờ chúng ta sẽ viết code để chuyển đoạn mã giã trên thành code


import XCTest
@testable import Binance
class HelperTest: XCTestCase {

    var sut:AppHelper!
    
    override func setUp() {
        super.setUp()
        sut = AppHelper()
    }
    override  func tearDown() {
        sut = nil
        super.tearDown()
        
        
    }

    func test_formatDate() {
        let isValidDateFormat = sut.stringToDate(dateStr: "10/10/2021", format: "dd/MM/yyyy")
        XCTAssertNil(isValidDateFormat)
       
    }

Kết quả của test case đầu tiên là

Kết quả test case thứ 2 là :

Kết luận

Bài viết này mình đã giới thiệu cho các bạn những khái niệm căn bản nhất của Unit test, và chúng ta cũng ta cũng đã thử viết 1 unit test căn bản, hy vọng bài viết của mình sẽ hữu ích cho bạn khi mới tiếp cận đến unit test, trong bài viết sắp tới mình sẽ chia sẻ cho các bạn về UI test, mọi ý kiến đóng góp mong các bạn gửi về địa chỉ phamtrungkiendev@gmail.com hoặc bình luận phía giới của bài viết này nhé!

Bài viết tham khảo của Apple document

Written on October 4, 2021