Ở bài viết trước mình đã giới thiệu về một kỹ thuật vô cùng hiệu quả nhưng hay bị bỏ qua trong kiểm thử phần mềm. Đó là kỹ thuật review. Trong bài viết này, mình sẽ tiếp tục cùng các bạn tìm hiểu về một số checklist thường được sử dụng trong review. Nào, hãy bắt đầu ngay bây giờ nhé!
Design Review Checklist
Review checklist này là ý tưởng của L. Peter Deutsch và những cộng sự tại Sun Microsystems. Đây là công ty đi đầu trong việc thiết kế và phát triển ứng dụng phân tán. Review checklist này dành cho việc đánh giá thiết kế. Chúng bao gồm các hạng mục sau đây:
- Vấn đề về Network: Network được tạo thành từ phần cứng và phần mềm. Chúng ta đã biết rằng dù phần cứng hay phần mềm đều có thể bị lỗi. Nguồn điện có thể bị gián đoạn, dây cáp có thể bị ngắt kết nối. Mọi người có thể làm những điều ngu ngốc. Về lâu dài, bạn có thể chắc chắn rằng mạng thỉnh thoảng sẽ ngừng hoạt động. Câu hỏi đặt ra là điều gì sẽ xảy ra với ứng dụng của bạn khi nó xảy ra.
- Vấn đề về độ trễ: Mất bao lâu để dữ liệu của bạn đi từ đây đến đó? Có vẻ như nó rất nhanh – tốc độ ánh sáng, phải không? Nếu mạng cục bộ, nó có thể gần bằng 0. Điều gì xảy ra nếu đó là mạng diện rộng? Người dùng ở cách xa hai lục địa. Chà, liệu nó có đủ nhanh không?
- Vấn đề băng thông: Các vấn đề về băng thông cần được xem xét khi review thiết kế. Bởi các sự cố về băng thông có thể tạo ra một số lỗi về hiệu suất.
- Vấn đề bảo mật. Bạn đã nghe nói về tin tặc, kẻ bẻ khóa, kẻ tìm kiếm cảm giác mạnh và đủ loại kẻ phá hoại mọi thứ chỉ vì một cú đá. Mạng không bao giờ an toàn.
- Cấu trúc liên kết không thay đổi. Ít nhất là không cho đến khi bạn đưa ứng dụng vào vận hành thực tế. Không thành vấn đề nếu ứng dụng được phân phối của bạn là nội bộ hay trên toàn thế giới; hằng số duy nhất trong mạng là sự thay đổi. Nó có thể không thay đổi hôm nay hoặc ngày mai. Ứng dụng của bạn sẽ được sử dụng trong bao lâu? Ngay cả những nhà tiên đoán giỏi nhất trong doanh nghiệp cũng không biết những tiến bộ kỹ thuật nào sẽ xuất hiện vào tuần tới hoặc năm tới. Mạng phải được trừu tượng hóa để không phụ thuộc vào bất kỳ tài nguyên nhất định nào.
- Có một quản trị viên. Ngay cả khi bạn ứng dụng đã có sẵn trong nhà, mọi người vẫn tiếp tục. Nó có vấn đề gì? Chuyên môn, đào tạo, giải quyết vấn đề: Tất cả những điều này và hơn thế nữa sẽ do quản trị viên hệ thống xử lý. Sẽ cần có các công cụ để giải quyết các vấn đề khi triển khai. Họ sẽ lấy công cụ, đào tạo, chuyên môn ở đâu? Hệ thống thực sự sẽ thân thiện với người dùng như thế nào? Khi bắt đầu xem xét chi tiết việc triển khai, hãy tìm ra ít nhất một quản trị viên để đối phó với các vấn đề đó.
- Chi phí vận chuyển bằng 0. Ở đây bạn cần phải xem xét cả thời gian và tiền bạc. Để có được dữ liệu từ đây đến đó cần có thời gian. Điều này liên quan đến ý tưởng về độ trễ mà chúng ta đã thảo luận trước đó. Phải mất thời gian để đi qua nhiều phần mềm, chương trình cơ sở và phần cứng, sau đó là cáp đồng hoặc cáp quang, đến phần cứng, chương trình cơ sở và phần mềm ở đầu bên kia. Việc này cần có thời gian và chu trình xử lý và những thứ đó không miễn phí. Ngoài ra, bạn đang đặt thêm tải lên các hệ thống vốn đã quá tải; đôi khi sẽ cần đến phần mềm và phần cứng mới. Hệ thống của bạn càng kém hiệu quả thì điều này càng đúng.
- Mạng lưới đồng nhất. Ví dụ bạn đang viết một ứng dụng Windows? Điều gì xảy ra nếu khách hàng của bạn sử dụng Linux? Ứng dụng của bạn hoạt động trong UNIX, nhưng máy khách của bạn có máy chủ ứng dụng Series? Các giao thức và dịch vụ độc quyền sẽ giúp bạn mọi lúc. Khả năng tương tác sẽ rất cần thiết đối với bất kỳ ứng dụng nào sắp được chuyển ra ngoài phòng thí nghiệm. Bạn đã thiết kế cho điều đó chưa?
Marick’s Code Review Checklist
Code review checklist được Brian Marick giới thiệu bao gồm danh sách các câu hỏi hữu ích, đặc biệt cho các ngôn ngữ lập trình hướng đối tượng. Khi review source code, hãy đặt ra cho mình những câu hỏi sau đây.
Đối với việc khai báo biến:
- Giá trị hằng số (literal values) có đúng không? Bằng cách nào chúng ta biết được?
- Mỗi biến có được đặt thành một giá trị đã biết trước khi sử dụng lần đầu không? Khi code thay đổi, bạn rất dễ bỏ lỡ việc thay đổi những đoạn code này.
- Chúng ta đã chọn đúng kiểu dữ liệu cho nhu cầu sử dụng chưa? Giá trị có thể âm không?
Đối với mỗi hạng mục dữ liệu và các thao tác trên các mục dữ liệu:
- Có phải tất cả các chuỗi NULL đều bị chấm dứt? Nếu chúng ta rút ngắn hoặc kéo dài một chuỗi hoặc xử lý nó theo bất kỳ cách nào thì byte cuối cùng có bị thay đổi không?
- Chúng ta có kiểm tra độ dài của mọi phép gán vào bộ đệm không?
- Khi sử dụng trường bit, các thao tác của chúng ta (dịch chuyển, xoay, v.v.) có khả dụng với các kiến trúc và sơ đồ endian khác không?
- Mọi lệnh gọi hàm sizeof() có thực sự đi đến đối tượng mà chúng ta mong muốn không?
Đối với mỗi lần phân bổ, giải phóng và tái phân bổ bộ nhớ:
- Dung lượng bộ nhớ có đủ đáp ứng mục đích mà không bị lãng phí không?
- Bộ nhớ sẽ được khởi tạo như thế nào?
- Tất cả các trường có được khởi tạo chính xác nếu đó là cấu trúc dữ liệu phức tạp không?
- Bộ nhớ có được giải phóng đúng cách sau khi sử dụng không?
- Chúng ta có bao giờ gặp tác dụng phụ từ việc lưu trữ tĩnh trong các hàm hoặc phương thức không?
- Sau khi phân bổ lại bộ nhớ, chúng ta có còn con trỏ nào tới vị trí bộ nhớ cũ không?
- Có khả năng nào bộ nhớ có thể được giải phóng nhiều lần không?
- Sau khi giải phóng, có còn con trỏ tới bộ nhớ không?
- Có phải chúng ta đang giải phóng nhầm dữ liệu mà chúng ta không cố ý?
- Có thể con trỏ chúng ta đang sử dụng để giải phóng bộ nhớ đã là NULL không?
Đối với tất cả các thao tác trên tệp:
- Chúng ta có cách nào đảm bảo rằng mỗi tệp tạm thời chúng ta tạo ra là duy nhất không?
- Có thể sử dụng lại con trỏ tập tin khi nó đang trỏ tới tập tin đang mở không?
- Chúng ta có khôi phục được từng phần xử lý tập tin sau khi xử lý xong không?
- Chúng ta có đóng từng tập tin một cách rõ ràng sau khi hoàn thành nó không?
Với mỗi phép tính:
- Dấu ngoặc đơn có đúng không? Chúng có đang sử dụng đúng mục đích không?
- Khi sử dụng đồng bộ hóa, chúng ta có cập nhật các biến trong các phần với nhau không?
- Chúng ta có cho phép phép chia cho 0 xảy ra không?
- Các số có dấu phẩy động có được so sánh để có sự bằng nhau chính xác không?
Đối với mọi thao tác liên quan đến con trỏ:
- Có chỗ nào trong code mà chúng ta có thể thử hủy đăng ký con trỏ NULL không?
- Khi xử lý các đối tượng, chúng ta muốn sao chép con trỏ (bản sao nông) hay nội dung (bản sao sâu)?
Đối với tất cả các phép gán (assignments):
- Có phải chúng ta đang gán các loại dữ liệu khác nhau khiến chúng ta có thể mất đi độ chính xác?
Đối với mỗi lệnh gọi hàm:
- Hàm đúng với đối số đúng có được gọi không?
- Các điều kiện tiên quyết của hàm có thực sự được đáp ứng không?
Cuối cùng, Marick đưa ra một số câu hỏi chung:
- Chúng ta đã loại bỏ tất cả code gỡ lỗi và thông báo lỗi không có thật chưa?
- Chương trình có giá trị trả về cụ thể khi thoát không?
Như bạn có thể thấy, đây là danh sách kiểm tra đánh giá code rất chi tiết. Tuy nhiên, việc tùy chỉnh dựa trên kinh nghiệm của chính bạn và nhu cầu của tổ chức bạn được khuyến khích.
The OpenLaszlo Code Review Checklist
Nếu Marick’s Code Review Checklist đưa ra các câu hỏi để thực hiện đánh giá cho chính đoạn code đó. Thì trong phần này, chúng ta sẽ thảo luận các câu hỏi nên hỏi về những thay đổi đối với hệ thống. Đây thực chất là những siêu câu hỏi về những thay đổi xảy ra trong quá trình bảo trì. Chúng đến từ trang web OpenLaszlo. Khi review source code, hãy đặt ra cho mình những câu hỏi sau đây.
Đối với tất cả các thay đổi về code:
- Chúng ta có hiểu tất cả những thay đổi về code đã được thực hiện và lý do của chúng không?
- Có trường hợp thử nghiệm nào cho tất cả các thay đổi không? Chúng đã được chạy chưa?
- Những thay đổi này có được ghi chép chính thức theo hướng dẫn của chúng ta không?
- Có bất kỳ thay đổi trái phép nào được đưa vào không?
Về mặt tiêu chuẩn mã hóa (giả sử bạn không thực thi các tiêu chuẩn mã hóa thông qua phân tích tĩnh):
- Tất cả những thay đổi về quy tắc có đáp ứng các tiêu chuẩn và nguyên tắc của chúng ta không? Nếu không thì tại sao không?
- Tất cả các giá trị dữ liệu được truyền có được tham số hóa chính xác không?
Về mặt thay đổi thiết kế:
- Bạn có hiểu những thay đổi về thiết kế và lý do chúng được thực hiện không?
- Việc triển khai thực tế có phù hợp với thiết kế không?
Về khả năng bảo trì:
- Có comment code không? Liệu chúng có đúng và đủ không?
- Tất cả các biến có được ghi chép đầy đủ thông tin để hiểu tại sao chúng được chọn không?
Về các tài liệu liên quan tới code:
- Tất cả các đối số dòng lệnh có được ghi lại không?
- Có phải tất cả các biến môi trường cần thiết để chạy hệ thống đều được xác định và được ghi lại?
- Tất cả các chức năng hướng tới người dùng đã được ghi lại trong tài liệu hướng dẫn sử dụng và tệp trợ giúp chưa?
- Việc triển khai có phù hợp với tài liệu không?
Bài viết hôm nay khá dài. Hi vọng chúng đem lại thông tin hữu ích cho bạn. Hẹn gặp lại các bạn trong các bài viết tiếp theo.
Happy Testing!