Unit Test là gì ?
UT là hoạt động để kiểm thử cho một đơn vị trong chương trình phần mềm nhằm đảm bảo đơn vị phần mềm đó hoạt động đúng.
UT bao gồm 2 thành phần cơ bản sau:
Tại sao phải UT?
UT được thực hiện bởi team phát triển nhằm:
- Đảm bảo chất lượng của phần mềm.
- Phát hiện lỗi sớm.
- Giảm effort đảm bảo chất lượng và effort chỉnh sửa (correction cost).
Biểu đồ chi phí tương ứng với các phase mà lỗi được phát hiện. Lỗi càng phát hiện muộn thì chi phí để chỉnh sửa, test lại ở các phase sau càng lớn.
Vấn đề thường gặp.
Khi dev được giao thực hiện 1 màn hình thì effort đã bao gồm cả Coding & UT.
Tuy nhiên khi thực hiện thì thời gian coding lại bị quá so với plan ban đầu, do đó đã sử dụng cả thời gian mà đáng ra dùng để làm UT để coding tiếp. Khi code xong tất nhiên là bao gồm compile, build các kiểu để show được màn hình lên, chạy được normal case thì đã hết luôn cả thời gian để thực hiện UT rồi.
Về lý do thì có nhiều lý do, tựu chung lại thì có 2 lý do sau:
- Under-estimation.
- Năng lực của team member.
Hướng giải quyết 2 lý do trên:
Under-estimation => PM/PL dự án cần estimate lại và update lại project detail plan. Khách hàng có thể không dễ dàng chấp nhận việc update estimation ở phase này, khi đó cần có thảo luận trong nội bộ công ty để xử lý như là internal estimation.
Năng lực member => Lựa chọn member phù hợp cho dự án, training member trước khi làm dự án, tạo template code, code mẫu đầu dự án cho các member sử dụng và làm theo.
Trang bị kiến thức về UT
Có 2 loại UT cơ bản sau.
Black box test
Đặc điểm của black box test:
- Chỉ quan tâm đến input đầu vào và kiểm tra kết quả, không confirm việc chương trình thực hiện cụ thể như thế nào.
- Không đảm bảo code coverage 100%
- Black box test thường áp dụng cho test hoạt động của chức năng và test business của chương trình hoạt động đúng theo requirement.
White box test
Đặc điểm của white box test:
- Dựa vào code để viết test case
- Đảm bảo các dòng code đều được chạy ít nhất một lần, không có dead code.
- White box test thường được sử dụng để đảm bảo code coverage, check giá trị biên, xử lý exception.
Độ bao phủ – Coverage:
- Statement coverage: Độ bao phủ câu lệnh => đảm bảo mọi dòng code đều được thực hiện
- Branch coverage: Độ bao phủ nhánh => đảm bảo mọi xử lý phân nhánh của program đều được thực hiện
- Path coverage: Độ bao phủ theo flow => đảm bảo mọi flow xử lý của program đều được thực hiện.
Con số mục tiêu:
- Số test case trên 1 KLOC: tiêu chuẩn ít nhất là 45 test case trên 1 KLOC. (1000 line of code)
Các chú ý khi thực hiện UT:
Xem xét thực hiện quy trình UT theo flow bên dưới.
- Viết kịch bản chương trình – test scenario
Trước khi bắt đầu viết test case: nên viết ra các kịch bản của chương trình mà mình code ra, bao gồm cả các case normal và exception case, có thể chỉ cần là cách gạch đầu dòng vào bản nháp. Đây là ý tưởng chương trình sẽ hoạt động như thế nào khi lắp ghép vào cả hệ thống. Xử lý khi có exception ra sao. Việc viết kịch bản này đòi hỏi dev phải hiểu rõ requirement, biz của màn hình mình làm.
- Viết black box test case
Viết các test case để đảm bảo function hoạt động đúng theo requirement của khách hàng.
- Bổ sung white box test case
Add thêm các test case handle các exception, test giá trị biên.
- Review test case theo check list và bổ sung test case
Sau khi viết UT case xong thì thực hiện review lại theo UT check list.
Việc này là cần thiết, vì trong lúc viết UT case có thể ko nghĩ hết được các trường hợp, check list sẽ nhắc nhở chúng ta xem còn thiếu những case nào để bổ sung. Có một lưu ý là UT check list ngoài các nội dung common thì sẽ khác nhau theo từng dự án. Trong 1 dự án chắc chắn sẽ có các phần có thể sử dụng chung (common) về business cũng các phần UI. Vì thế PM/PL hoặc BA cần bổ sung vào UT check list để cả team không bị lack các case liên quan đến business của dự án.
- Thực hiện UT theo test case
- Log bug UT lên hệ thống và fix bug.
Note:
- Template UT case: Không quan trọng bằng nội dung của các UT case, có thể dùng template tùy ý nhưng phải thống nhất trong project team.
- Script test: Đối với dự án viết script test thì step viết black box, write box test được thay bằng viết code script test. Junit, NUnit…
Thực hiện code với tư tưởng test ở trong đầu.
Code càng phức tạp thì test sẽ phải càng nhiều, vì thế khi code cần chú ý giảm độ phức tạp của function bằng 1 số quy tắc sau.
- Tránh việc phân nhánh không cần thiết.
- Trong xử lý phân nhánh (branching) thì nên viết ít code nhất có thể.
- Quy tắc early return.
- Thay thế các câu điều kiện như if/else if, switch case bằng tính đa hình trong OOP.
Tìm hiểu thêm: https://refactoring.guru/replace-conditional-with-polymorphism
- Thực hiện code tuân theo các tiêu chuẩn đã có như SOLID.
Tìm hiểu thêm về SOLID: https://techtalk.vn/solid-la-gi-ap-dung-cac-nguyen-ly-solid-de-tro-thanh-lap-trinh-vien-code-cung.html
Lời kết
Tóm lại, quan trọng nhất vẫn là mindset về việc thực hiện UT. Mindset chính là tư duy, ý thức thấy việc làm UT là cần thiết, dần dần hình thành thói quen thực hiện UT đầy đủ.
Ngay cả khi thực hiện các training, seminar về UT vẫn có nhiều dev có kinh nghiệm đều nói đã biết hết rồi, thế nhưng việc nắm được kiến thức liên quan đến UT là một chuyện, việc thực tế khi làm dự án có thực hiện theo đúng những kiến thức đã học hay không lại là một chuyện hoàn toàn khác. Vì thế cần hình thành mindset làm UT một cách có ý thức và chuyên nghiệp để nâng cao giá trị của phần mềm mình viết ra cũng là nâng cao giá trị bản thân trong ngành công nghiệp IT.