Skip to main content

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.

Comments

Popular posts from this blog

So sánh những framework hỗ trợ viết ứng dụng trên SmartPhone

Khi lập trình trên SmartPhone bạn không nhất thiết phải học những ngôn ngữ đặc thù trên từng loại hệ điều hành thì mới có thể lập trình được. Ví dụ như muốn lập trình trên iOS thì phải học ngôn ngữ Objective-C hay Swift, muốn lập trình được trên Android thì học ngôn ngữ Java, muốn lập trình trên WinPhone thì học ngôn ngữ C#. Hiện nay có rất nhiều những framework giúp đỡ cho các bạn rất nhiều khi các bạn muốn viết trên nhiều nền tảng smartphone bằng ngôn ngữ mà bạn yêu thích. Theo mình thấy thì hiện nay có 3 loại như: Native App, Hybrid Mobile App, Native Cross-Platform App. 1. Native App: là những ứng dụng sử dụng những framework và ngôn ngữ lập trình của hệ thống cung cấp sẵn. Ví dụ như bạn muốn lập trình iOS thì phải cài XCode, học ngôn ngữ Objective-C hay Swift, lập trình Android thì cài Android Studio và học ngôn ngữ Java. - Ưu điểm: Hiệu năng thực thi ứng dụng trên nền tảng nhanh và hiệu quả. Không bị phụ thuộc vào bên thứ 3. Khi phát hành ứng dụng trên những Mobile Store cũng dễ...

Hướng dẫn dùng Serverless sử dụng Lambda AWS

1. Lambda function là gì? AWS Lambda cho phép bạn chạy mã mà không cần cung cấp hay quản lý máy chủ. Bạn chỉ phải trả tiền cho thời gian xử lý thông tin đã sử dụng. Với Lambda, bạn có thể chạy mã cho gần như toàn bộ các loại ứng dụng hay dịch vụ backend – tất cả đều không cần quản trị. Chỉ cần tải đoạn mã của bạn lên và Lambda sẽ lo hết những gì cần làm để chạy và mở rộng mã của bạn với mức độ có sẵn cao. Bạn có thể thiết lập mã của bạn tự động kích hoạt từ các dịch vụ AWS khác, hoặc gọi trực tiếp từ bất cứ ứng dụng web hay di động nào. Chi phí chạy trên lambda function rẻ so với chi phí bạn mua 1 con server, duy trì và quản trị nó ( ví dụ như bạn phải xử lý bất đồng bộ những request, khi lượng user bạn tăng đột biến bạn phải có cơ chế auto scale, chứ không thì server bị sẽ bị treo, khi server bị treo bạn phải tự động khởi động lại sẽ mất thời gian,... ).

Phân biệt biến kiểu Property, Public, Protected, Private trong ngôn ngữ Objective C

- Theo kinh nghiệm làm việc của mình với các bạn trong nhóm khi lập trình Objective-C và cũng đọc qua code của những project cũ. Ít khi nào mọi người để ý và khai báo đúng với ý đồ của từng đối tượng, và vi phạm quy tắc tính đóng gói, tính bảo mật thông tin của đối tượng trong lập trình hướng đối tượng (Tham khảo lý thuyết Lập trình hướng đối tượng tại trang Wiki ). - Theo ngôn ngữ lập trình Java, người ta khuyến khích mỗi khi dùng biến kiểu public thì nên đặt 1 biến private và hỗ trợ những hàm getter/setter để truy suất biến private đó.     + Nguyên nhân họ nói là đảm bảo tính đóng gói, và nếu sau này có thay đổi gì trên biến đó bạn có thể sửa được dễ dàng, chi tiết về vấn đề này ở đây .     + Nói tóm tại thì nguyên nhân chính là có thể kiểm soát được truy xuất đến giá trị của 1 đối tượng từ bên ngoài, có thể dễ dàng mở rộng code bằng cách override lại những hàm getter/setter. - Các bạn có thể áp dụng nguyên tắc đó từ bên Java qua ngôn ngữ lập trình Object...