Skip to content

Commit

Permalink
update unit. testing barryclark#2
Browse files Browse the repository at this point in the history
  • Loading branch information
codedeman committed Oct 4, 2021
1 parent bcaafde commit 313e3f4
Showing 1 changed file with 249 additions and 0 deletions.
249 changes: 249 additions & 0 deletions _posts/2021-10-04-unit-test-phan-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
---
layout: post
title: Testing ứng dụng của bạn trong Xcode phần 1 Unit test
categories: ios developer
---
Ứ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
![](https://docs-assets.developer.apple.com/published/20b3426c34/93cc7b80-dd57-423d-be85-f937da693ec3.png)

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
<img src="https://i.imgur.com/h2qJt9L.png" width=50% />

Unit test chạy nhanh nhất <br/>
Tiếp đến interaction test <br/>
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

## Thực hành
### Bước 1 Tạo project
<img src="https://i.imgur.com/Zz0zQHF.png" width=50% />

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
<img src="https://i.imgur.com/twfc7Jd.png" width=50% />

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
</br>
Khởi tạo classs mà bạn muốn test
</br>
2 Execution
</br>
Gọi những phương thức ở trong class
</br>
3 Expection
</br>
Kiểm 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 </br>
Case 1 Người dùng đăng nhập tài trạng thái active
</br>
Setup:Tạo một function phương thức đăng nhập user
</br>
Execution:chạy function
</br>
Expection: trả về True
</br>

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
</br>
Execution:chạy function
</br>
Expection: trả về False
</br>


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é

``` Swift
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]("https://developer.apple.com/documentation/xctest/xctestcase")
nó chứa các test function cho class và function

``` Swift

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
</br>
**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
<br>
<img src="https://i.imgur.com/Q7nZ9KV.png" width=40% />
<br>

Với test case thứ 2 kết quả mà chúng ta mong đợi là False
<br>
<img src="https://i.imgur.com/sCVURKf.png" width=40% />
<br>

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

``` Swift

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
</br>
Case 1 Dữ liệu truyền vào đúng format
</br>
Setup:Tạo một function truyền kiểu date dạng string vào và format mong muốn
Execution:chạy function
</br>
Expection: trả về khác nil
</br>

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

Setup:Tạo một function phương thức đăng nhập user
</br>
Execution:chạy function
</br>
Expection: trả về bằng nil
</br>
Bây giờ chúng ta sẽ viết code để chuyển đoạn mã giã trên thành code


``` Swift

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à
<br>
<img src="https://i.imgur.com/GYYOpKr.png" width=40% />
<br>

Kết quả test case thứ 2:
<br>
<img src="https://i.imgur.com/KDafLvt.png" width=40% />
<br>

## 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ỉ sphamtrungkiendev@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](https://developer.apple.com/documentation/xcode/testing-your-apps-in-xcode)

0 comments on commit 313e3f4

Please sign in to comment.