Getting started with Xcode UI testing in Swift



  • UI Testing là phương pháp tuyệt vời để đảm bảo rằng, các tương tác UI vẫn hoạt động tốt sau khi add thêm các tính năng mới hoặc refactoring code. Đây cũng là một cách hay để tự động hóa các tác vụ lặp đi lặp lại khi làm việc trên UI code (khi bạn phải điều hướng sâu vào ứng dụng của mình để test một cái gì đó bạn đang làm việc).
    Viết và chạy UI Test khác so với Unit Test, vì bạn thực hiện tương tác với ứng dụng, so với việc kiểm tra theo chương trình với một API nhất định. Cả hai đều có rất nhiều ý nghĩa, nên tốt nhất là dùng cả hai cho các task khác nhau.
    Xcode đính kèm với UI Testing trong XCTest framework, là framework bạn đã sử dụng cho Unit test. Những feature của UI Testing này đã có vài năm, nhưng thường bị các developer bỏ qua vì thiếu ổn định, và khó sử dụng. Tuy nhiên, bây giờ chúng đã tốt hơn rất nhiều và chung ta có thể sử dụng nó một cách hiệu quả.

    Setting things up

    Nếu ứng dụng chưa có một UI Testing target, tất cả những gì bạn phải làm là File > New > Target.. và chọn “UI testing bundle”. Sau đó sửa app scheme để chạy UI test các các bước Product > Scheme > Edit Scheme.. và add UI Testing Bundle bên dưới “Test”.

    Let’s write a test

    Một ví dụ về cách sử dụng UI Testing có lẽ là một giải pháp tuyệt nhất, khi đó bạn muốn test user flow.
    Giả sử onboard flow bao gồm 4 màn hình mà bạn phải vuốt qua để hoàn thành. Cuối cùng, nút "Done" xuất hiện ở góc trên bên phải màn hình, cần được tapped để đóng onboarding flow, giống như thế này

    Hãy viết đoạn test thực hiện chính xác

    class OnboardingUITests: XCTestCase {
        var app: XCUIApplication!
        
        // MARK: - XCTestCase
        
        override func setUp() {
            super.setUp()
            
            // Since UI tests are more expensive to run, it's
            // usually a good idea to exit if a failure was encountered
            continueAfterFailure = false
            
            app = XCUIApplication()
            
            // We send a command line argument to our app,
            // to enable it to reset its state
            app.launchArguments.append("--uitesting")
        }
        
        // MARK: - Tests
        
        func testGoingThroughOnboarding() {
            app.launch()
            
            // Make sure we're displaying onboarding
            XCTAssertTrue(app.isDisplayingOnboarding)
            
            // Swipe left three times to go through the pages
            app.swipeLeft()
            app.swipeLeft()
            app.swipeLeft()
            
            // Tap the "Done" button
            app.buttons["Done"].tap()
            
            // Onboarding should no longer be displayed
            XCTAssertFalse(app.isDisplayingOnboarding)
        }
    }
    
    

    Như bạn thấy ở trên, chúng ta thực hiện UI Testing bằng cách thực hiện các tương tác giao diện người dùng, thực hiện swipes và tap chứ không phải gọi các API. Trong thực tế, các Test case được thực hiện theo các quy trình khác nhau, vậy không thể can thiệp được vào đoạn mã của chính chúng ta, theo quy trình của chương trinh. Vì thê, chúng ta phải thực hiện test thực sự chứ k thể giảo mạo được chúng.
    Chúng ta hãy xem xét kỹ hơn hai dòng trên, bắt đầu bằng một trong những cách sau:

    app.launchArguments.append("--uitesting")
    

    Như đã đề cập, chúng ta cho phép ứng dụng chạy UI Test và nó có thể reset các trạng thái. Đây thường là một thực hành tốt, vì nếu không bạn sẽ kết thúc với các bài kiểm tra sẽ chỉ vượt qua trong điều kiện nhất định (= flakiness).

    Resetting your app’s state

    Vậy làm thế nào để reset lại các trạng thái? Cách đơn giản nhất là kiểm application(didFinishLaunchingWithOptions:)

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
        if CommandLine.arguments.contains("--uitesting") {
            resetState()
        }
        
        // ...Finish setting up your app
        
        return true
    }
    

    Chính xác những gì cần làm trong resetState () sẽ khác nhau tùy thuộc vào trạng thái ứng dụng của bạn vẫn tồn tại. Ở đây bạn muốn xóa các giá trị mặc định của người dùng, cơ sở dữ liệu và bất kỳ thứ gì bạn đã lưu (ví dụ các tệp trên đĩa). Ví dụ: dưới đây là cách đặt lại UserDefaults:

    let defaultsName = Bundle.main.bundleIdentifier!
    UserDefaults.standard.removePersistentDomain(forName: defaultsName)
    

    Verifying state in a UI test

    Trở lại với chương trình test, 1 dòng code khác mà tôi muốn đi sâu là

    XCTAssertTrue(app.isDisplayingOnboarding)
    

    Chúng ta sử dụng để xác minh trạng thái hiện tại là đúng, và UI hoạt động như mong đợi. Nó hoạt động như một thuộc tính mở rộng trên XCUIApplication. Đây là một patterm tôi khuyên dùng, vì nó giữ các test cases ngắn, đơn giản và dễ dàng sử dụng lại.

    Dưới đây là cách triển khai isDisplayingOnboarding:

    extension XCUIApplication {
        var isDisplayingOnboarding: Bool {
            return otherElements["onboardingView"].exists
        }
    }
    

    Đoạn code trên tìm kiếm UIView có accessIdentifier là "onboardingView". Tất cả chúng ta cần làm bây giờ là thêm định danh này vào các view OnboardingViewController:

    final class OnboardingViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            view.accessibilityIdentifier = "onboardingView"
        }
    }
    

    Conclusion

    Để làm cho các UI Test của bạn dễ maintain và chạy nhanh, tôi khuyên bạn nên làm càng đơn giản càng tốt và để phần logic phức tạp cho Unit test.

    [Nguồn]https://medium.com/@johnsundell/getting-started-with-xcode-ui-testing-in-swift-ac7b1f5101e5
    Nguồn: Viblo


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.