Unit Testing là gì? |
Unit Testing là một loại kiểm thử phần mềm trong đó các đơn vị hoặc thành phần riêng lẻ của phần mềm được kiểm tra. Mục đích là để xác thực rằng từng đơn vị mã nguồn phần mềm hoạt động như mong đợi. Unit Testing được thực hiện trong giai đoạn phát triển (giai đoạn viết mã) của một ứng dụng bởi các nhà phát triển. Các Unit Test cô lập một phần mã và xác minh tính chính xác của nó. Một đơn vị có thể là một hàm, phương thức, thủ tục, mô-đun hoặc đối tượng riêng lẻ.
Trong SDLC, STLC, Mô hình V, unit testing là mức kiểm thử đầu tiên được thực hiện trước kiểm thử tích hợp. Unit testing là một kỹ thuật kiểm thử WhiteBox thường được thực hiện bởi nhà phát triển. Tuy nhiên, trong thực tế do áp lực thời gian hoặc sự miễn cưỡng của nhà phát triển, các kỹ sư kiểm thử (QA) cũng có thể thực hiện unit testing.
Mục lục
Tại sao phải thực hiện Unit Testing?
Unit Testing quan trọng vì các nhà phát triển phần mềm đôi khi cố gắng tiết kiệm thời gian bằng cách thực hiện unit testing tối thiểu, và đây là một quan niệm sai lầm vì unit testing không phù hợp sẽ dẫn đến chi phí sửa lỗi cao trong Kiểm thử Hệ thống, Kiểm thử Tích hợp và thậm chí Kiểm thử Beta sau khi ứng dụng được xây dựng. Nếu thực hiện unit testing đúng đắn trong giai đoạn phát triển ban đầu, nó sẽ tiết kiệm thời gian và chi phí về lâu dài.
Dưới đây là những lý do chính để thực hiện unit testing trong kỹ thuật phần mềm:
- Các unit test giúp phát hiện và sửa lỗi sớm trong chu kỳ phát triển và tiết kiệm chi phí.
- Nó giúp các nhà phát triển hiểu rõ mã kiểm thử và cho phép họ thực hiện các thay đổi nhanh chóng.
- Các unit test tốt phục vụ như tài liệu dự án.
- Các unit test hỗ trợ việc tái sử dụng mã. Chuyển cả mã và các bài kiểm tra sang dự án mới. Điều chỉnh mã cho đến khi các bài kiểm tra chạy lại.
Cách thực hiện Unit Testing
Để thực thi các Unit Test, các nhà phát triển viết một đoạn mã để kiểm tra một chức năng cụ thể trong ứng dụng phần mềm. Các nhà phát triển cũng có thể cô lập chức năng này để kiểm tra kỹ hơn, điều này sẽ phát hiện các phụ thuộc không cần thiết giữa chức năng được kiểm tra và các đơn vị khác để loại bỏ các phụ thuộc đó. Các nhà phát triển thường sử dụng UnitTest framework để phát triển các test case tự động cho unit testing.
Unit testing có hai loại:
- Thủ công
- Tự động
Unit testing thường được tự động hóa nhưng vẫn có thể được thực hiện thủ công. Kỹ thuật phần mềm không ưu tiên một phương pháp nào hơn, nhưng tự động hóa được ưa thích hơn. Phương pháp thủ công để unit testing có thể sử dụng một tài liệu hướng dẫn từng bước.
Theo phương pháp tự động:
- Một nhà phát triển viết một đoạn mã trong ứng dụng chỉ để kiểm tra chức năng. Họ sẽ sau đó ghi chú lại và cuối cùng loại bỏ mã kiểm tra khi ứng dụng được triển khai.
- Một nhà phát triển cũng có thể cô lập chức năng để kiểm tra kỹ hơn. Đây là một thực hành unit testing kỹ lưỡng hơn, liên quan đến việc sao chép và dán mã vào môi trường kiểm tra riêng của nó thay vì môi trường tự nhiên. Việc cô lập mã giúp phát hiện các phụ thuộc không cần thiết giữa mã được kiểm tra và các đơn vị hoặc không gian dữ liệu khác trong sản phẩm. Các phụ thuộc này sau đó có thể được loại bỏ.
- Một lập trình viên thường sử dụng UnitTest Framework để phát triển các test case tự động. Bằng cách sử dụng framework tự động, nhà phát triển mã hóa các tiêu chí vào bài kiểm tra để xác minh tính chính xác của mã. Trong quá trình thực thi các test case, framework sẽ ghi lại các test case không đạt. Nhiều framework cũng sẽ tự động gắn cờ và báo cáo, một cách tóm tắt, những test case không đạt này. Tùy thuộc vào mức độ nghiêm trọng của một lỗi, framework có thể dừng các bài kiểm tra tiếp theo.
- Quy trình Unit Testing là:
- Tạo Test Cases
- Xem xét/Sửa đổi
- Chuẩn hóa
- Thực thi Test Cases
Kỹ Thuật Unit Testing
Các Kỹ Thuật Unit Testing chủ yếu được chia thành ba phần:
- Kiểm thử hộp đen (Black box testing) liên quan đến kiểm tra giao diện người dùng cùng với đầu vào và đầu ra.
- Kiểm thử hộp trắng (White box testing) liên quan đến kiểm tra hành vi chức năng của ứng dụng phần mềm.
- Kiểm thử hộp xám (Gray box testing) được sử dụng để thực thi bộ kiểm tra, các phương thức kiểm tra, các test case và thực hiện phân tích rủi ro.
Các kỹ thuật phủ mã sử dụng trong Unit Testing bao gồm:
- Phủ câu lệnh (Statement Coverage)
- Phủ quyết định (Decision Coverage)
- Phủ nhánh (Branch Coverage)
- Phủ điều kiện (Condition Coverage)
- Phủ Máy Trạng Thái Hữu Hạn (Finite State Machine Coverage)
Ví Dụ về Unit Testing: Đối Tượng Mô Phỏng (Mock Objects)
Unit testing dựa vào việc tạo ra các đối tượng mô phỏng để kiểm tra các phần mã chưa thuộc về một ứng dụng hoàn chỉnh. Các đối tượng mô phỏng sẽ thay thế các phần còn thiếu trong chương trình.
Ví dụ, bạn có thể có một hàm cần các biến hoặc đối tượng chưa được tạo. Trong unit testing, những thứ đó sẽ được thể hiện dưới dạng các đối tượng mô phỏng được tạo ra riêng cho mục đích kiểm tra phần mã đó.
Các Công Cụ Unit Testing
Có một số phần mềm unit test tự động để hỗ trợ unit testing trong kiểm thử phần mềm:
- JUnit: Là công cụ kiểm tra miễn phí dùng cho ngôn ngữ lập trình Java. Nó cung cấp các khẳng định để xác định phương thức kiểm tra. Công cụ này kiểm tra dữ liệu trước và sau đó chèn vào đoạn mã.
- NUnit: Là framework kiểm thử unit được sử dụng rộng rãi cho tất cả các ngôn ngữ .NET. Là công cụ mã nguồn mở cho phép viết script thủ công. Nó hỗ trợ các bài kiểm tra theo dữ liệu có thể chạy song song.
- JMockit: Là công cụ unit testing mã nguồn mở. Đây là công cụ đo phủ mã với các số liệu về đường dẫn và dòng lệnh. Nó cho phép mô phỏng API với cú pháp ghi và xác minh. Công cụ này cung cấp Phủ dòng lệnh, Phủ đường dẫn và Phủ dữ liệu.
- EMMA: Là bộ công cụ mã nguồn mở để phân tích và báo cáo mã được viết bằng ngôn ngữ Java. EMMA hỗ trợ các loại phủ như phương thức, dòng lệnh, khối cơ bản. Vì là công cụ dựa trên Java nên không phụ thuộc vào thư viện bên ngoài và có thể truy cập mã nguồn.
- PHPUnit: Là công cụ unit testing dành cho các lập trình viên PHP. Nó lấy các phần nhỏ của mã (gọi là các đơn vị) và kiểm tra từng phần riêng biệt. Công cụ còn cho phép các nhà phát triển sử dụng các phương thức khẳng định được định nghĩa trước để khẳng định rằng hệ thống hoạt động theo một cách nhất định.
Đây chỉ là một số ít các công cụ unit testing có sẵn. Còn rất nhiều công cụ khác, đặc biệt là cho các ngôn ngữ C và Java, nhưng bạn chắc chắn sẽ tìm được một công cụ unit testing phù hợp với nhu cầu lập trình của mình bất kể ngôn ngữ bạn sử dụng.
Phát Triển Theo Hướng Kiểm Thử (Test Driven Development - TDD) & Unit Testing
Unit testing trong TDD liên quan đến việc sử dụng rộng rãi các framework kiểm thử. Một framework unit test được sử dụng để tạo các unit test tự động. Các framework kiểm thử unit không chỉ riêng TDD, nhưng chúng rất thiết yếu với TDD. Dưới đây chúng ta sẽ xem xét những gì TDD mang lại cho thế giới unit testing:
- Các bài kiểm tra được viết trước mã
- Phụ thuộc nhiều vào các testing framework
- Tất cả các lớp trong ứng dụng đều được kiểm tra
- Tích hợp nhanh chóng và dễ dàng được thực hiện
Các Quan Niệm Sai Lầm về Unit Testing
Quan niệm sai lầm: Nó mất thời gian, và tôi luôn quá tải! Mã của tôi là "rắn chắc"! Tôi không cần unit tests.
Các quan niệm sai lầm theo bản chất đều là những giả định sai. Những giả định này dẫn đến một chu kỳ xấu như sau:
Càng cảm thấy vui vẻ -> Càng ít viết bài kiểm tra -> Mã của bạn càng kém ổn định -> Bạn càng kém hiệu quả và chính xác -> Càng cảm thấy vui vẻ.
Sự thật là unit testing tăng tốc độ phát triển.
Các lập trình viên nghĩ rằng Kiểm thử Tích hợp sẽ bắt được tất cả các lỗi và không thực thi unit test. Một khi các đơn vị được tích hợp, những lỗi rất đơn giản mà đáng lẽ có thể được phát hiện và sửa dễ dàng trong unit test lại mất rất nhiều thời gian để truy tìm và sửa chữa.
Ưu Điểm của Unit Testing
- Các nhà phát triển muốn tìm hiểu chức năng của một đơn vị và cách sử dụng nó có thể xem xét các unit test để có được sự hiểu biết cơ bản về API của đơn vị đó.
- Unit testing cho phép lập trình viên tái cấu trúc mã sau này, và đảm bảo rằng mô-đun vẫn hoạt động chính xác (tức là Kiểm thử Hồi quy - Regression Testing). Quy trình là viết các test case cho tất cả các hàm và phương thức để bất cứ khi nào một thay đổi gây ra lỗi, nó có thể được phát hiện và sửa nhanh chóng.
- Do tính chất mô-đun của unit testing, chúng ta có thể kiểm tra các phần của dự án mà không cần chờ các phần khác hoàn thành.
Nhược Điểm của Unit Testing
- Không thể mong đợi unit testing sẽ bắt được mọi lỗi trong một chương trình. Không thể đánh giá tất cả các đường dẫn thực thi thậm chí trong những chương trình đơn giản nhất.
- Unit testing theo bản chất của nó tập trung vào một đơn vị mã. Do đó, nó không thể bắt được các lỗi tích hợp hoặc các lỗi ở cấp độ hệ thống rộng.
Khuyến nghị nên sử dụng unit testing kết hợp với các hoạt động kiểm thử khác.
Các Phương Pháp Hay Nhất cho Unit Testing
- Các test case unit phải độc lập. Trong trường hợp có bất kỳ nâng cấp hoặc thay đổi yêu cầu nào, các test case unit không bị ảnh hưởng.
- Chỉ kiểm tra một mã tại một thời điểm.
- Tuân theo các quy ước đặt tên rõ ràng và nhất quán cho các unit test của bạn.
- Trong trường hợp thay đổi mã ở bất kỳ mô-đun nào, hãy đảm bảo có một Test Case unit tương ứng cho mô-đun đó, và mô-đun đó phải vượt qua các bài kiểm tra trước khi thay đổi cách triển khai.
- Các lỗi được xác định trong quá trình unit testing phải được sửa trước khi chuyển sang giai đoạn tiếp theo trong SDLC.
- Áp dụng phương pháp "kiểm tra khi bạn viết mã". Càng nhiều mã bạn viết mà không kiểm tra, bạn càng có nhiều đường dẫn để kiểm tra lỗi.
Tóm Lược
- UNIT TESTING được định nghĩa là một loại kiểm thử phần mềm trong đó các đơn vị hoặc thành phần riêng lẻ của phần mềm được kiểm tra.
- Như bạn có thể thấy, có rất nhiều thứ liên quan đến unit testing. Nó có thể phức tạp hoặc khá đơn giản tùy thuộc vào ứng dụng được kiểm tra và các chiến lược, công cụ và triết lý kiểm thử được sử dụng. Unit testing luôn cần thiết ở một mức độ nào đó. Đó là một điều chắc chắn.