Một trong những yếu tố mang đến thành công cho AngularJS chính là khả năng áp dụng kiểm thử (Testing) vào quá trình phát triển các ứng dụng SPA. AngularJS hỗ trợ thực hiện các phạm vi kiểm thử khác nhau, bao gồm kiểm thử đơn vị (Unit Testing), kiểm thử từng phần (Midway Testing) và kiểm thử đầu-cuối (End-to-End Testing). Bài viết này giới thiệu sơ lược các khái niệm có liên quan đến kiểm thử trong AngularJS.
Nội dung trình bày
Tại sao phải kiểm thử ứng dụng?
Trước khi đi vào nội dung chính - áp dụng kiểm thử phần mềm vào ứng dụng xây dựng bằng AngularJS - tôi muốn đề cập sơ lược về khái niệm và sự cần thiết của kiểm thử trong quá trình phát triển phần mềm, cụ thể là phần mềm xây dựng trên nền tảng AngularJS.
Để thuận tiện cho việc trình bày, tôi sẽ lấy một ví dụ cụ thể về một ngành sản xuất để minh họa cho các khái niệm cần được giải thích ở đây.
Ví dụ về kiểm thử trong sản xuất xe hơi
Giả sử hãng xe hơi Atoyot thiết lập một dây chuyển sản xuất xe hơi bao gồm nhiều nhà máy sản xuất linh kiện và lắp ráp đạt tại nhiều quốc gia như sau:
Trong hình minh họa ở trên, ta có thể thấy các bộ phận của ô tô có thể được sản xuất tại các nhà máy ở các quốc gia khác nhau. Các bộ phận này được tạo ra tuân theo các thông số thiết kế, do đó có thể được lắp ghép thành một chiếc ô tô hoàn chỉnh. Tuy nhiên trong thực tế, mọi hoạt động đều có khả năng tiềm tàng và phát sinh những sai sót. Điều gì xảy ra nếu sai sót của một số bộ phận chỉ bị phát hiện khi đã chuyển đến nhà máy lắp ráp hoặc thậm chí sau khi đã đến tay người dùng? Dễ thấy rằng những sai sót chậm phát hiện này sẽ tiêu tốn nhiều thời gian và chi phí cho việc phát hiện, vận chuyển, thay thế khắc phục, thu hồi sản phẩm, đền bù nếu có thiệt hại xảy ra. Thậm chí, uy tín của hãng bị ảnh hưởng nghiêm trọng.
Chính vì vậy, các hãng sản xuất đều xây dựng quy trình sản xuất chặt chẽ, trong đó việc kiểm thử được thực hiện càng sớm càng tốt và áp dụng trong suốt quá trình sản xuất và lắp ráp sản phẩm.
Kiểm thử trong xây dựng phần mềm
Ngày nay, quá trình phát triển phần mềm cũng được thực hiện theo cách phân rã phần mềm lớn thành các phần nhỏ. Các bộ phận nhỏ của phần mềm được phát triển rời nhau và được lắp ghép lại thành sản phẩm phần mềm hoàn chỉnh. Do được xây dựng trên nền tảng logic nên phần mềm tiềm tàng rất nhiều sai lệch so với những gì chúng ta hình dung về nó khi xây dựng. Thêm vào đó, phần mềm là dạng kết cấu không trực quan nên những sai lệch này rất khó phát hiện và tích tụ theo thời gian.
Theo tính toán của NIST (National Institute of Standards and Technology), chi phí khắc phục lỗi trong phần mềm theo thời gian sẽ gia tăng theo cấp độ mũ.
Việc phát hiện sớm lỗi trong phần mềm có ý nghĩa hết sức quan trọng trong việc đảm bảo tiến độ cũng như làm giảm rủi ro và chi phí phát triển. Có nhiều hướng tiếp cận trong kiểm thử phần mềm, trong đó phổ biến nhất là phân loại kiểm thử phần mềm theo cấp độ, bao gồm:
- Kiểm thử đơn vị (Unit Testing) còn gọi là kiểm thử thành phần (Component Testing) là phương pháp kiểm thử chú trọng vào việc kiểm tra chức năng của một “đơn vị” chức năng chương trình (thông thường là một hàm, tuy nhiên trong một số mô hình, chẳng hạn AngularJS, “đơn vị” có thể là Controller, Directive hoặc Service). Kiểm thử đơn vị được thực hiện bởi chính lập trình viên tạo nên chức năng chương trình đó.
- Kiểm thử tích hợp (Integration Testing): là dạng kiểm thử định hướng vào việc kiểm tra tính đúng đắn của giao tiếp thông qua giao diện giữa các thành phần của phần mềm. Kiểm thử tích hợp thông thường cũng được thực hiện bởi lập trình viên.
- Kiểm thử hệ thống (System Testing): còn gọi là kiểm thử 2 đầu (End-to-End Testing), là dạng kiểm thử toàn diện phần mềm đã được lắp ghép hoàn chỉnh để kiểm tra xem các yêu cầu phần mềm có được đáp ứng đầy đủ hay không? Kiểm thử hệ thống thường do đội QA (Quality Assurance) đảm trách.
- Kiểm thử chấp nhận (Acceptance Testing): là dạng kiểm thử được thực hiện tại nơi triển khai thực tế của sản phẩm, do người đặt hàng thực hiện nhằm đảm bảo sản phẩm tiếp nhận đáp ứng được đầy đủ các yêu cầu đã đề ra. Trong kiểm thử phần mềm, các bộ kiểm thử chấp nhận thường do khách hàng phát triển, hoặc do khách hàng cộng tác với đơn vị xây dựng tạo ra.
Các loại kiểm thử trong AngularJS
Trong quá trình áp dụng phương pháp TDD vào phát triển phần mềm, các dự án luôn có xu hướng tự động hóa quá trình kiểm thử (Automation Testing). Các dự án phát triển bằng AngularJS cũng không ngoại lệ. Với vai trò là khung ứng dụng, AngularJS cung cấp các công cụ kiểm thử nhằm hỗ trợ người phát triển áp dụng các phương pháp kiểm thử cũng như tự động hóa quá trình kiểm thử được dễ dàng và nhanh chóng. AngularJS cung cấp 2 loại kiểm thử chính: Unit Testing và End-to-End Testing. Mặc dù còn một loại nữa là Midway Testing là một trường hợp của End-to-End Testing, tuy nhiên trong thực tế loại này ít được sử dụng.
Kiểm thử thành phần (Unit Testing)
Unit testing hoạt động dựa trên nguyên tắc chia tách và cô lập các đơn vị chương trình để có thể kiểm thử chức năng của từng đơn vị chương trình một cách độc lập với những phần còn lại. Để dễ dàng hình dung, chúng ta có thể thấy trong sản xuất xe hơi, mỗi một bộ phận khi sản xuất đều được kiểm thử riêng rẽ trong một môi trường giả lập thực tế. Hình ảnh bên dưới minh họa việc kiểm thử bánh xe hơi:
Kiểm thử đầu-cuối (End-to-End Testing)
End-to-End testing thực hiện kiểm thử hoạt động tổng thể của ứng dụng bằng cách kiểm thử quá trình thực hiện chức năng từ đầu đến cuối quá trình xử lý, đi từ giao diện đến giao tiếp với nguồn dữ liệu (truy cập dịch vụ web hoặc vùng lưu trữ cục bộ). Có thể hình dung một kiểm thử End-to-End là quá trình thực hiện một chức năng của ứng dụng được một Robot thao tác trên một trình duyệt ẩn theo một kịch bản do chúng ta lập trình sẵn. Xét trong phạm vi ứng dụng phát triển bằng AngularJS, End-to-End Testing chính là System Testing.
Liên hệ với ví dụ về kiểm thử trong ngành sản xuất xe hơi, quá trình kiểm thử đầu-cuối (End-to-End Testing) tương ứng với công đoạn kiểm soát chất lượng sản phẩm sau khi lắp ráp như trong hình ảnh minh họa bên dưới: