qkhanhpro1
Senior Member
Nếu bác xài RDBM thì cho cái test vào transaction ở setUp nhưng đừng commit transaction đó. Còn xài NoSQL thì seed db rồi delete cả db cho khoẻ. Cái Seed cũng quan trọng, bác đầu tư phần này đáng lắm.
Edit: kinh nghiệm là không nên re-use db cho nhiều test cases. Tôi đoán bác đang xài No-SQL nên gặp vấn đề này, 1 db cùng lắm nên xài cho 1 test suite, đừng nên xài chung quá nhiều. Có 2 lý do:
- DB là lưu state, trong khi test nên là stateless, nếu lưu db mà không xoá sẽ có nhiều side-effect và maybe là flaky tests.
- Tách db để run test multi-thread -> deploy nhanh hơn.
Tôi nghĩ #39 nói rất đúng. Thật sự tôi không rõ định nghĩa Unit Test của mỗi người là như thế nào để chúng ta có thể thảo luận được một cách tử tế về chủ đề này
(1) Nếu Unit Test nhắm tới các khối code nhỏ nhất như #1 nói đến hoặc như nhiều người "preach" thì đúng... nó sẽ rất "dễ" ... dễ đến mức Unit Testing không còn ý nghĩa gì nữa ?
Để có được mức độ Isolation như vậy thì Unit Test này phải test các khối code rất nhỏ, các phép toán như createSaltedPassword() hay CustomGraphGetNodeByPropertyValue()
(2) Tôi tin phần lớn các test chúng ta viết rơi vào trường hơp "Integration Test / Integration Unit Test" khi đã có đủ các thể loại ban bệ (dependency) trong source code của bạn. Giả sử bạn có 1 hàm như thế này - từ Jellyfin
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
Nhìn thì có vẻ rất đơn giản - chỉ có 2 parameter. Tuy nhiên mỗi object được gửi vào có một tấn property và bản thân hàm này cũng cho ra 1 tấn các kết quả khác nhau. Vậy chúng ta làm gì với nó?
- Mock tất cả mọi thứ và test tất cả mọi thứ? ... well nhắc đến mock thì nó lại là một ổ sâu khác
- Không test nó?
- "Hàm trên chưa được viết tốt, khi chúng ta đã phân chia công việc một cách tử tế / đủ nhỏ để unit test thì sẽ không bao giờ xảy ra trường hợp như thế này, bản thân các hàm khác nhỏ hơn được hàm này gọi đã được test thì chúng ta sẽ không bao giờ gặp trường hợp như thế này" - Tôi nghĩ lập luận này là cứt bò. Nếu đập tất cả mọi thứ nhỏ đến mức có thể làm một cái "unit test" hoàn toàn độc lập, nhỏ đến mức trivial như ở điểm (1) thì cái chúng ta có sẽ là x10 số lượng hàm ( Để giảm độ phức tạp từng hàm?) , x10 số lượng class (Để giảm số property trên mỗi class?) , x10 độ sâu call stack ( Hậu quả của việc xẻ nhỏ hàm) và x100 LOC mà không mang lại giá trị gì thật sự cả
Nhận định cá nhân: Nếu một developer thực sự nghĩ trước khi implement một thứ gì trong cùng một lượng thời gian với một developer dùng thời gian đó để nghĩ và viết unit test thì tôi tin tưởng nhiều hơn vào chất lượng của người nghĩ và không viết unit test. Thứ mà unit test mang lại là nó ép developer phải nghĩ. Chất lượng code tốt hơn vì developer đó đã nghĩ kỹ trước khi implement, không phải vì bản thân việc viết Unit Test
Điểm tốt khác là sớm phát hiện breaking changes. Cái này thực sự là một điểm + lớn, không phải bàn cãi