Skip to main content

Độ bao phủ code của unittest


Nếu bạn là một developer, chắc hẳn bạn phải thừa nhận rằng unittest đóng một vai trò cực kỳ quan trọng trong việc giúp ta phát hiện sớm các vấn đề của dự án trong quá trình phát triển, cả về mặt thực thi lẫn các requirement. Một yếu tố quan trọng của unittest chính là độ bao phủ code, thứ giúp ta đo lường được bao nhiêu phần trăm của code được test qua khi chạy unittest. Về mặt tổng quan, số phần trăm này càng cao thì mức độ đảm bảo của code càng cao, và đa số mọi người đều muốn vậy.
Vậy thì làm thế nào để đo lường được con số này? Từ version 7, Xcode đã có tính năng code coverage cho phép ta đo và hình dung được độ bao phủ code. Bài viết này sẽ giới thiệu cách đo đại lượng này và làm sao để tăng độ bao phủ lên.

Xem độ bao phủ code trong Xcode

Xcode cung cấp sẵn cho người dùng giao diện để xem được độ bao phủ một cách chi tiết nhất, để xem được chức năng này, vào Product > Scheme > Edit Scheme
Sau đó chọn tab Test > Options, tick chọn Code Coverage - Gather coverage
Tiếp theo, hãy chạy unittest, bài viết này sử dụng một demo projects để chạy test, bạn có thể sử dụng app của mình để thực hiện:
Tất cả các testcase đều đã pass, kích vào Report Navigator, ta sẽ thấy được báo cáo về độ bao phủ mà unittest đang đạt được:
Demo này đạt được 58.18%, ta còn có thể xem được chi tiết từng file đang được bao phủ bao nhiêu phần trăm:

Tăng độ bao phủ cho unittest

Để tăng độ bao phủ ta có thể rà soát toàn bộ dự án, kiểm tra những nơi unittest chưa chạy qua và viết test cho tất cả những nơi có thể.
Ta có thể áp dụng các cách sau:
  1. Viết test cho mọi phương thức public
  2. Tăng độ bao phủ cho các phương thức public bằng việc kiểm tra xem dòng code nào chưa được chạy qua.
Trong ví dụ trên, ta có 3 class, hai class AppDelegate và BullsEyeGame đều đạt 100%, chỉ còn class ViewController mới đạt được 45.88%, nếu tăng độ bảo phủ của class này thì sẽ tăng được giá trị của toàn app. Dòng màu xanh này đánh dấu đoạn code đã được test:
Và dòng màu đỏ đánh dấu đoạn code này chưa được test
Dựa vào những phân tích này ta có thể viết thêm các test case phù hợp để nâng code coverage lên.
Ngoài ra, còn có một cách để nâng độ bao phủ code rất hiệu quả đó là viết UI test, nếu ta chỉ viết logic, thì mới đảm bảo tầm 30-40% độ bao phủ, tuy nhiên, nếu sử dụng cả UI test thì hầu như có thể đạt được khoảng 80%, vì code UI chiếm một lượng khá lớn trong toàn app.
Để viết UI test, bạn có thể tham khảo một số framework như Quick and Nimble (https://github.com/Quick/Nimble), KIF (https://github.com/kif-framework/KIF).
Tuy nhiên, độ bao phủ cao chưa chắc đã đảm bảo được ứng dụng có chất lượng tốt, điều quan trọng là phải đảm bảo testcase cover được những luồng logic quan trọng của dự án, và cover được càng nhiều trường hợp càng tốt. Vì vậy ta cần đảm bảo cả về mặt chất lượng lẫn số lượng thì chất lượng của dự án càng được nâng cao.

Comments

Popular posts from this blog

Swift GCD part 1: Thread safe singletons

Preview Singletons are entities, referenced to the same instance of a class from everywhere in your code. It doesn't matter if you like them or not, you will definitely meet them, so it's better to understand how they work. Constructing and handling a set of data doesn't seem to be a big challenge at first glance. The problems appear when you try to optimise the user experience with background work and your app starts acting weird. ??‍♂️ After decades of watching your display mostly with a blank face, you finally realize that your data isn't handled consistently by the manager because you're accessing it (running tasks on it) from multiple threads at the same time. So you really do have to deal with making your singletons thread safe. This article series is dedicated to thread handling using Swift. In the first part below you will get a comprehensive insight into som...

Kiến thức cơ bản về RxSwift

Bài viết với mong muốn cung cấp thông tin cơ bản về kiến trúc, các thuật ngữ được sử dụng phổ biến về RxSwift, giúp những lập trình viên lần đầu làm quen RxSwift sẽ trở nên dễ dàng hơn. Trong bài viết có sử dụng một số từ khóa tiếng Anh, mình xin phép sẽ giữ nguyên bản không sử dụng tiếng Việt vì có lẽ sẽ dễ hiểu hơn cho người đọc. Observable Sequences Mọi hoạt động trong RxSwift từ việc đăng ký và xử lý sự kiện đều thông qua một Observable Sequences Trong RxSwift , các kiểu dữ liệu như Arrays , Strings hoặc Dictionary sẽ được convert sang Observable Sequences . Ta có thể tạo ra "Observable Sequences" của bất kỳ kiểu đối tượng nào tuân theo Sequence Protocol của Swift Standard Library . let helloSequence = Observable.just( "Hello Rx" ) let fibonacciSequence = Observable. from ([ 0 , 1 , 1 , 2 , 3 , 5 , 8 ]) let dictSequence = Observable. from ([ 1 : "Hello" , 2 : "World" ]) Đăng ký nhận event từ ""Observable Se...

Thread safe singleton’s in Swift

What are singletons? — Singleton is design patterns which says that there should be only one instance of the class for the lifetime of the application. One the best example of Singleton is AppDelegate . How to write a singleton class ? class DefaultDict{ private var dict:[String:Any] = [:] public static let sharedManager = DefaultDict() private init(){ } public func set(value:Any,key:String){ dict[key] = value } public func object(key:String) -> Any?{ dict[key] } public func reset(){ dict.removeAll() } }   Testing singleton class under concurrent circumstances. We are going to write an example where we will set values in dict from various threads and even try to access some with different threads. When we do this we will encounter a crash. If you look closely it will be because of race condition and the crash will be on line set(value:Any,key:String) . class ViewController: UIViewController { ...