Thursday, April 19, 2018

Làm thế nào để kiểm tra Auto Layout trên nhiều loại thiết bị iOS?

Chào các bạn, mấy bài trước tôi có hướng dẫn các bạn làm auto layout trên iOS, nếu bạn nào chưa đọc thì có thể xem lại tại đây. Vậy sau khi làm auto layout xong các bạn có tự tin rằng nó đã thực sự chạy tốt và không có bug xảy ra?

Các bạn có thể viết unit test cho phần logic rất dễ dàng nếu các bạn chia những code xử lý logic thành từng hàm có input và output rõ ràng, công việc này rất là tốt. Nếu sau này các bạn viết thêm những đoạn code khác hoặc fix bug khác làm logic đó sai, bạn có thể chạy unit test để phát hiện ra lỗi ngay. Một khi bạn làm unit test tốt và độ bao phủ cao thì số bug chắc chắn sẽ ít và thời gian bạn test bằng tay cũng giảm đi nhiều, và bạn sẽ rất tự tin khi nói với khách hàng của bạn rằng: code của mình sẽ không sinh những bug vặt.

Nhưng mặt hạn chế trước giờ  mình gặp phải là mình chỉ có thể viết unit test cho phần logic, còn phần layout thì mặc định công cụ XCode chưa hỗ trợ nhiều, thành ra số bug mình khó thấy và không test kỹ được là phần layout trên những loại thiết bị khác nhau. Những bug về layout tuy nhỏ nhưng cũng rất là khó chịu, đa số các công ty lớn cũng đau đầu vì chuyện này, thành ra công ty Linkedin đã hỗ trợ viết ra 1 thư viện giúp cho các bạn phát hiện ra những bug về layout 1 cách dễ dàng và nhanh chóng đó chính là thư viện LayoutTest-iOS. Tôi đáng giá cao thư viện này thành ra hôm nay tôi sẽ giới thiệu cho các bạn cách xài cũng như có cái nhìn tổng quát về như viện này.

Trong ví dụ của thư viện này họ đã viết bằng ngôn ngữ Swift với đối tượng Cell, vì thế tôi sẽ không dùng swift và cell để làm ví dụ nữa, mà sẽ hướng dẫn viết code bằng Objective-C. Đầu tiên tôi tạo 1 dự án tên là LayoutTest và khai báo trong pod file như sau để tải thư viện và tích hợp chúng vào dự án:
Lưu ý: Bạn phải mở comment 'use_frameworks!' để có thể xài được thư viện này trên Objective-C. Nếu không sẽ báo error khi sử dụng thư viện. Hiện tại thư viện mình tải về phiên bản 4.0.0.

I. Custom UIView:

Ví dụ thứ nhất tôi sẽ chỉ cho các bạn làm cách nào thể làm unit test cho 1 custom view, Giả sử tôi tạo 2 Label trong custom view như sau:

- Bước 1: Tạo 1 Category để khai báo những hàm để hỗ trợ chạy Unit Test, ví dụ mình đặt tên cho Category này là 'UITest', sau khi tạo xong nó sẽ sinh ra 2 tập tin 'CustomView+UITest.h' và 'CustomView+UITest.m'
Trong file .h: bạn khai báo để implement đối tượng 'LYTViewProvider'.
Sau đó trong file .m: 2 hàm bạn quan tâm bắt buộc phải thực thi là hàm 'dataSpecForTest' (dùng để khởi tạo dữ liệu test) và 'viewForData' (dùng để khởi tạo và sử dụng lại view).
Nếu bạn muốn hỗ trợ nhiều kích thước màn hình thì thêm hàm 'sizesForView' này vào.
Đối tượng 'LYTStringValues' chứa danh sách bộ test case mặc định cho kiểu NSString, nếu các bạn muốn tạo bộ dữ liệu cho riêng bạn thì nên kế thừa đối tượng này và override lại hàm trả danh sách 'values'.
Hàm 'setupWithJSON' dùng để truyền dữ liệu và cập nhật UI.
- Bước 2: Bạn tạo 1 file unit test và viết 1 hàm như sau:
Sau khi bạn viết hàm này xong thì chạy Test thử, thì sẽ trả về thành công.

Giả sử mình cho 2 label này chồng lên nhau để xem thư viện này có báo lỗi hay không như sau:

Sau đó mình chạy lại Unit Test thì sẽ báo như hình sau:
Bạn để ý trong console của XCode có báo dòng chữ "Snapshots of failing tests can be found in:", đây là dòng chữ chỉ cho bạn biết layout của bạn đang bị lỗi chồng lên nhau như thế nào, bạn copy đường dẫn này và past lên trên browser thì sẽ thấy màn hình của bạn đang bị lỗi gì:

Nếu việc chồng lên này là cố tình bạn muốn như vậy thì bạn có thể thiết lập để chúng bỏ qua lỗi này. Theo tôi tốt nhất khi thiết kế giao diện không nên để những đối tượng này chồng lên nhau.

II. Custom UIViewController:

Giả sử tôi tạo 1 ViewController trong storyboard như sau:
Tại đối tượng Top Right, mình cố tình tạo bug cho nó để có thể xuất lỗi như 'line of number' bằng 0, và không tạo constraint cho height. Nếu bộ dữ liệu test của bạn không đủ dài thì sẽ không thấy bug này.

Cách làm cho UIViewController hơi khác so với custom view, ở chỗ khai báo trong Category như sau:
Bạn thấy hàm 'viewForData' mình đã dùng đối tượng static để có thể reuse lại ViewController.
Sau khi chạy Unit Test xong thì sẽ báo lỗi như sau:
Bạn có thể thấy với 1 chuỗi dài do mình không giới hạn chiều cao nên nó sẽ bị kéo dài xuống và bị chồng đối tượng với nhau.

Ngoài việc kiểm tra có bị chồng lên nhau hay không thì các bạn có thể viết thêm những unit test trong file test để kiểm tra chính xác vị trí của đối tượng đó như sau:
Thế là xong những bước căn bản thiết lập thư viện và kiểm tra giao diện có bị chồng lên nhau hay không. Các bạn có thể xem toàn bộ source code của mình tại đây. Nếu thấy hay và hữu ích hãy vote +1 cho mình tại blog này hay nhấn nút star trên GitHub nhé. Cám ơn các bạn rất nhiều.

Các bạn có thể xem thông tin chi tiết tại trang chủ của thư viện LayoutTest-iOS tại đường dẫn sau. Để biết thêm chi tiết các bạn có thể xem thêm tài liệu hướng dẫn của Linkedin.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.