Là phạm vi kiểm tra là một thước đo đầy đủ của chất lượng mã?


20

Nếu tôi có một số mã có phạm vi kiểm tra 80% (tất cả các bài kiểm tra vượt qua), có công bằng không khi nói rằng nó có chất lượng cao hơn mã không có phạm vi kiểm tra?

Hay công bằng hơn khi nói nó dễ bảo trì hơn?


2
Bảo hiểm 100% không có nghĩa là nó đã được thử nghiệm tốt. Nhưng 0% có nghĩa là nó chưa được thử nghiệm.
mouviciel

1
Về mặt kỹ thuật thì không. Thực tế, có. Kinh nghiệm đã dạy rất nhiều kỹ sư phần mềm và người kiểm thử rằng khi độ bao phủ mã đạt khoảng 80%, các loại lỗi mà kiểm thử đơn vị là đủ bắt đầu chững lại. Đó là nguyên tắc pareto. Về cơ bản một khi bạn đạt đến điểm mà bạn bao phủ 80% mã, bất kể chất lượng thử nghiệm của bạn là gì, có lẽ bạn đã kiểm tra 20% mã gây ra hầu hết các vấn đề tiềm ẩn khá kỹ lưỡng. Đây không phải là một sự tuyệt đối, mà là một sự khôn ngoan thông thường. Bạn phải kỹ lưỡng hơn nếu cuộc sống phụ thuộc vào thử nghiệm của bạn.
Calphool

@JoeRounceville Tôi không chắc ... Tôi có thể đạt được phạm vi kiểm tra cao trong khi kiểm tra không có gì thực sự hữu ích. Bảo hiểm chỉ cho bạn biết bao nhiêu mã đang được bộ kiểm thử chạm vào, chứ không phải liệu các thử nghiệm có ý nghĩa hay không.
Andres F.

1
@AresresF. Đó là lý do tại sao tôi nói "về mặt kỹ thuật là không, thực tế là có". Mọi người không ngốc (nói chung). Họ không (nói chung) chỉ kiểm tra các trường hợp không có trí tuệ. Vì vậy, dựa trên kinh nghiệm , nhiều cửa hàng dừng ở đâu đó khoảng 80%, đưa ra giả định (khá an toàn) rằng người dân của họ không phải là người đạo đức.
Calphool

Câu trả lời:


24

Theo một nghĩa nghiêm ngặt, thật không công bằng khi đưa ra bất kỳ khiếu nại nào cho đến khi chất lượng của bộ thử nghiệm được thiết lập. Vượt qua 100% các bài kiểm tra là không có ý nghĩa nếu hầu hết các bài kiểm tra là tầm thường hoặc lặp đi lặp lại với nhau.

Câu hỏi là: Trong lịch sử của dự án, có bất kỳ thử nghiệm nào phát hiện ra lỗi không? Mục tiêu của một bài kiểm tra là tìm lỗi. Và nếu họ không làm, họ đã thất bại khi thử nghiệm. Thay vì cải thiện chất lượng mã, họ chỉ có thể mang lại cho bạn cảm giác an toàn sai lầm.

Để cải thiện thiết kế thử nghiệm của bạn, bạn có thể sử dụng (1) kỹ thuật whitebox, (2) kỹ thuật hộp đen và (3) thử nghiệm đột biến.

(1) Dưới đây là một số kỹ thuật whitebox tốt để áp dụng cho các thiết kế thử nghiệm của bạn. Một thử nghiệm whitebox được xây dựng với mã nguồn cụ thể trong tâm trí. Một khía cạnh quan trọng của thử nghiệm whitebox là bảo hiểm mã:

  • Là mọi chức năng được gọi là? [Bảo hiểm chức năng]
  • Là mỗi tuyên bố thực hiện? [Bảo hiểm tuyên bố-- Cả bảo hiểm chức năng và bảo hiểm tuyên bố đều rất cơ bản, nhưng tốt hơn là không có gì]
  • Đối với mọi quyết định (như ifhoặc while), bạn có một bài kiểm tra buộc nó là đúng và khác có buộc nó là sai không? [Bảo hiểm quyết định]
  • Đối với mọi điều kiện là kết hợp (sử dụng &&) hoặc phân tách (sử dụng ||), mỗi biểu thức con có kiểm tra trong đó đúng / sai không? [Bảo hiểm điều kiện]
  • Phạm vi vòng lặp: Bạn có kiểm tra buộc 0 lần lặp, 1 lần lặp, 2 lần lặp không?
  • Là mỗi breaktừ một vòng lặp được bảo hiểm?

(2) Các kỹ thuật hộp đen được sử dụng khi có sẵn các yêu cầu, nhưng bản thân mã thì không. Những điều này có thể dẫn đến các bài kiểm tra chất lượng cao:

  • Các bài kiểm tra hộp đen của bạn có bao gồm nhiều mục tiêu kiểm tra không? Bạn sẽ muốn các bài kiểm tra của mình "mập": Họ không chỉ kiểm tra tính năng X mà còn kiểm tra Y và Z. Sự tương tác của các tính năng khác nhau là một cách tuyệt vời để tìm lỗi.
  • Trường hợp duy nhất bạn không muốn kiểm tra "chất béo" là khi bạn đang kiểm tra một tình trạng lỗi. Ví dụ: kiểm tra đầu vào người dùng không hợp lệ. Nếu bạn đã cố gắng đạt được nhiều mục tiêu kiểm tra đầu vào không hợp lệ (ví dụ: mã zip không hợp lệ và địa chỉ đường phố không hợp lệ) thì có khả năng một trường hợp đang che giấu trường hợp khác.
  • Xem xét các loại đầu vào và tạo thành một "lớp tương đương" cho các loại đầu vào. Ví dụ: nếu mã của bạn kiểm tra xem một tam giác có bằng nhau không, thì thử nghiệm sử dụng một tam giác có các cạnh (1, 1, 1) có thể sẽ tìm thấy các loại lỗi tương tự như dữ liệu thử nghiệm (2, 2, 2) và (3, 3, 3) sẽ tìm thấy. Tốt hơn là dành thời gian của bạn nghĩ về các lớp đầu vào khác. Ví dụ: nếu chương trình của bạn xử lý thuế, bạn sẽ muốn kiểm tra cho từng khung thuế. [Đây được gọi là phân vùng tương đương.]
  • Các trường hợp đặc biệt thường liên quan đến khuyết tật. Dữ liệu thử nghiệm của bạn cũng phải có các giá trị biên, chẳng hạn như các giá trị trên, trên hoặc dưới các cạnh của tác vụ tương đương. Ví dụ: khi kiểm tra thuật toán sắp xếp, bạn sẽ muốn kiểm tra với một mảng trống, một mảng phần tử đơn, một mảng có hai phần tử và sau đó là một mảng rất lớn. Bạn nên xem xét các trường hợp ranh giới không chỉ cho đầu vào, mà còn cho đầu ra. [Đây là cuộc gọi phân tích giá trị biên.]
  • Một kỹ thuật khác là "Lỗi đoán." Bạn có cảm giác nếu bạn thử một số kết hợp đặc biệt mà bạn có thể làm cho chương trình của bạn bị phá vỡ? Sau đó, hãy thử nó! Hãy nhớ rằng: Mục tiêu của bạn là tìm lỗi, không xác nhận rằng chương trình hợp lệ . Một số người có sở trường để đoán lỗi.

(3) Cuối cùng, giả sử bạn đã có rất nhiều bài kiểm tra hay về độ bao phủ của whitebox và các kỹ thuật hộp đen được áp dụng. Bạn còn có thể làm gì khác nữa không? Đã đến lúc kiểm tra bài kiểm tra của bạn . Một kỹ thuật bạn có thể sử dụng là Kiểm tra đột biến.

Theo thử nghiệm đột biến, bạn thực hiện sửa đổi (bản sao) chương trình của mình, với hy vọng tạo ra lỗi. Một đột biến có thể là:

Thay đổi một tham chiếu của một biến thành một biến khác; Chèn hàm abs (); Thay đổi ít hơn thành lớn hơn; Xóa một tuyên bố; Thay một biến bằng một hằng số; Xóa một phương thức ghi đè; Xóa một tham chiếu đến một siêu phương thức; Thay đổi thứ tự đối số

Tạo vài chục đột biến, ở nhiều nơi trong chương trình của bạn [chương trình sẽ vẫn cần phải biên dịch để kiểm tra]. Nếu các bài kiểm tra của bạn không tìm thấy các lỗi này, thì bây giờ bạn cần phải viết một bài kiểm tra có thể tìm thấy lỗi trong phiên bản đột biến của chương trình của bạn. Khi một bài kiểm tra tìm thấy lỗi, bạn đã giết chết dị nhân và có thể thử một lỗi khác.


Phụ lục : Tôi quên đề cập đến hiệu ứng này: Lỗi có xu hướng co cụm . Điều đó có nghĩa là bạn càng tìm thấy nhiều lỗi trong một mô-đun, xác suất bạn sẽ tìm thấy càng nhiều lỗi càng cao. Vì vậy, nếu bạn có một thử nghiệm thất bại (có nghĩa là thử nghiệm thành công, vì mục tiêu là tìm lỗi), bạn không chỉ nên sửa lỗi mà còn nên viết thêm các thử nghiệm cho mô-đun, sử dụng kỹ thuật trên.

Chừng nào bạn còn tìm thấy lỗi với tốc độ ổn định, các nỗ lực kiểm tra phải tiếp tục. Chỉ khi có sự suy giảm về tỷ lệ lỗi mới được tìm thấy, bạn mới có niềm tin rằng bạn đã nỗ lực thử nghiệm tốt cho giai đoạn phát triển đó.


7

Theo một định nghĩa, nó sẽ dễ bảo trì hơn, vì bất kỳ thay đổi vi phạm nào cũng dễ bị bắt bởi các thử nghiệm.

Tuy nhiên, thực tế là mã vượt qua các bài kiểm tra đơn vị không có nghĩa là về bản chất nó có chất lượng cao hơn. Mã vẫn có thể được định dạng xấu với các nhận xét không liên quan và cấu trúc dữ liệu không phù hợp, nhưng nó vẫn có thể vượt qua các bài kiểm tra.

Tôi biết mã nào tôi muốn duy trì và mở rộng.


7

Mã hoàn toàn không có bài kiểm tra nào có thể cực kỳ chất lượng, dễ đọc, đẹp và hiệu quả (hoặc tổng số rác), vì vậy không công bằng khi nói rằng mã có độ bao phủ thử nghiệm 80% có chất lượng cao hơn mã không có phạm vi kiểm tra.

Có thể công bằng khi nói rằng mã 80% được bao phủ bởi các bài kiểm tra tốt có lẽ có chất lượng chấp nhận được và có thể tương đối duy trì được. Nhưng nó đảm bảo ít, thực sự.


3

Tôi sẽ gọi nó là nhiều hơn - tái cấu trúc. Tái cấu trúc trở nên cực kỳ dễ dàng nếu mã được bao phủ bởi nhiều bài kiểm tra.

Nó sẽ là công bằng để gọi nó là duy trì nhiều hơn.


2

Tôi đồng ý về phần duy trì. Michael Feathers gần đây đã đăng một video về một cuộc nói chuyện xuất sắc về cái gọi là " Sự phối hợp sâu sắc giữa khả năng kiểm tra và thiết kế tốt " trong đó ông thảo luận về chủ đề này. Trong cuộc nói chuyện, ông nói rằng mối quan hệ là một cách, nghĩa là, mã được thiết kế tốt là có thể kiểm tra được, nhưng mã có thể kiểm tra không nhất thiết phải được thiết kế tốt.

Điều đáng chú ý là truyền phát video không tuyệt vời trong video, vì vậy có thể đáng để tải xuống nếu bạn muốn xem đầy đủ.


-2

Bây giờ tôi đã tự hỏi mình câu hỏi này liên quan đến "bảo hiểm điều kiện". Vậy làm thế nào về trang này từ atollic.com "Tại sao phân tích bảo hiểm mã?"

Về mặt kỹ thuật, phân tích độ bao phủ mã tìm thấy các khu vực trong chương trình của bạn không nằm trong các trường hợp thử nghiệm của bạn, cho phép bạn tạo các thử nghiệm bổ sung bao gồm các phần chưa được kiểm tra trong chương trình của bạn. Do đó, điều quan trọng là phải hiểu rằng bảo hiểm mã giúp bạn hiểu chất lượng của các quy trình kiểm tra của bạn, chứ không phải chất lượng của chính mã .

Điều này dường như khá liên quan ở đây. Nếu bạn có một bộ trường hợp thử nghiệm quản lý để đạt được một mức độ bao phủ (mã hoặc mặt khác) nhất định, thì bạn hoàn toàn có khả năng gọi mã được thử nghiệm với một bộ giá trị đầu vào khá đầy đủ! Điều này sẽ không cho bạn biết nhiều về mã đang được thử nghiệm (trừ khi mã bị nổ hoặc tạo ra các lỗi có thể phát hiện được) nhưng giúp bạn tự tin hơn trong trường hợp thử nghiệm của mình .

Trong một thay đổi quan điểm thú vị của Necker Cube , mã kiểm tra hiện đang được kiểm tra bởi mã đang được thử nghiệm!


-3

Có nhiều cách để đảm bảo rằng một chương trình thực hiện những gì bạn dự định và để đảm bảo rằng các sửa đổi sẽ không mang lại hiệu quả ngoài ý muốn.

Kiểm tra là một. Tránh đột biến dữ liệu là một vấn đề khác. Hệ thống kiểu cũng vậy. Hoặc xác minh chính thức.

Vì vậy, trong khi tôi đồng ý rằng thử nghiệm nói chung là một điều tốt, thì một tỷ lệ thử nghiệm nhất định có thể không có nhiều ý nghĩa. Tôi thà dựa vào một cái gì đó được viết bằng Haskell mà không có bài kiểm tra nào hơn là trên một thư viện PHP được kiểm tra tốt


Đây chỉ là ý kiến ​​của bạn hoặc bạn có thể sao lưu nó bằng cách nào đó?
gnat

2
Kiểm tra không phải là một cách để đảm bảo một chương trình thực hiện những gì bạn dự định.
Andres F.

1
Sau đó, tôi còn lại để tự hỏi thử nghiệm là gì
Andrea

@gnat đây là tất nhiên ý kiến ​​của tôi. Tuy nhiên, nó nói những gì được nói. Tôi lấy Haskell làm ví dụ về ngôn ngữ có trình biên dịch rất nghiêm ngặt và đưa ra nhiều đảm bảo về sự hình thành tốt của đầu vào, các loại, tác dụng phụ, đột biến dữ liệu. Tôi đã lấy PHP làm ví dụ về một ngôn ngữ có trình thông dịch rất khoan dung và thậm chí không có đặc tả. Ngay cả khi không có thử nghiệm, sự hiện diện của tất cả các đảm bảo từ các loại và hệ thống hiệu ứng thường mang lại một mức độ tin cậy khá. Để bù lại rằng với các bài kiểm tra, người ta sẽ cần phải có một bộ rất toàn diện
Andrea

Tôi có thể hơi vội vàng khi tôi viết - tôi đang nghe điện thoại - nhưng tôi vẫn nghĩ có một điểm. Tôi không muốn bash trên PHP, nhưng tôi nghĩ rằng nói rằng so sánh Haskell cho mức độ tin cậy cao hơn nhiều là một tuyên bố khách quan
Andrea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.