Làm thế nào để kiểm tra các bài kiểm tra?


53

Chúng tôi kiểm tra mã của chúng tôi để làm cho nó chính xác hơn (thực tế, ít có khả năng là không chính xác ). Tuy nhiên, các bài kiểm tra cũng là mã - chúng cũng có thể chứa lỗi. Và nếu các bài kiểm tra của bạn có lỗi, chúng hầu như không làm cho mã của bạn tốt hơn.

Tôi có thể nghĩ về ba loại lỗi có thể xảy ra trong các bài kiểm tra:

  1. Lỗi logic, khi lập trình viên hiểu sai nhiệm vụ trong tay, và các bài kiểm tra làm những gì anh ta nghĩ họ nên làm, đó là sai;

  2. Lỗi trong khung kiểm tra cơ bản (ví dụ: trừu tượng chế nhạo bị rò rỉ);

  3. Lỗi trong các bài kiểm tra: bài kiểm tra đang làm hơi khác so với những gì lập trình viên nghĩ.

Lỗi loại (1) dường như là không thể ngăn chặn (trừ khi lập trình viên chỉ ... trở nên thông minh hơn). Tuy nhiên, (2) và (3) có thể dễ điều khiển. Làm thế nào để bạn đối phó với các loại lỗi? Bạn có chiến lược đặc biệt nào để tránh chúng không? Ví dụ: bạn có viết một số bài kiểm tra "trống" đặc biệt, chỉ kiểm tra các giả định của tác giả bài kiểm tra không? Ngoài ra, làm thế nào để bạn tiếp cận gỡ lỗi một trường hợp thử nghiệm bị hỏng?


3
Mỗi phần giới thiệu tôi đã đọc về chế giễu dường như đều gặp phải vấn đề này. Khi bạn bắt đầu chế giễu mọi thứ, các bài kiểm tra dường như luôn phức tạp hơn mã mà chúng đang kiểm tra. Rõ ràng điều này ít có khả năng xảy ra khi thử nghiệm mã trong thế giới thực, nhưng nó khá không thành công khi bạn đang cố gắng học.
Carson63000

@ Carson63000 Nếu đó là một thử nghiệm đơn giản thử nghiệm một cái gì đó với một giả thử nghiệm , thì độ phức tạp được phân chia và trong tầm kiểm soát (, tôi nghĩ vậy).
mlvljr

13
Nhưng sau đó, làm thế nào để bạn kiểm tra các bài kiểm tra thử nghiệm?
ocodo

+1. Mục 1 có thể là một lỗi yêu cầu. Chỉ có thể được ngăn chặn bằng cách xem xét các yêu cầu. Có lẽ nằm ngoài tầm tay của lập trình viên trừ khi họ cũng là nhà phân tích yêu cầu
MarkJ

@ocodo: Giống như cách bạn xem Người theo dõi. :)
Greg Burghardt

Câu trả lời:


18

Các xét nghiệm đã được thử nghiệm. Các thử nghiệm được thiết kế bảo vệ khỏi các lỗi, bởi vì thử nghiệm chỉ phát hiện sự khác biệt giữa mã và kỳ vọng của chúng tôi. Nếu có vấn đề chúng tôi có một lỗi. Lỗi có thể nằm trong mã hoặc có cùng xác suất trong các thử nghiệm.

  1. Có một số kỹ thuật ngăn bạn thêm cùng một lỗi trong cả mã và kiểm tra của bạn:

    1. Khách hàng nên là người khác với người thực hiện.
    2. Đầu tiên viết các bài kiểm tra và sau đó là mã (như trong Test Driven Development).
  2. Bạn không cần phải kiểm tra nền tảng cơ bản. Các bài kiểm tra không chỉ thực hiện mã do bạn viết, mà chúng còn chạy mã từ nền tảng. Mặc dù bạn không cần phải bắt lỗi trong nền tảng thử nghiệm, nhưng rất khó để viết mã và kiểm tra luôn ẩn lỗi trong nền tảng, nói cách khác là rất khó để có lỗi hệ thống trong cả thử nghiệm / mã của bạn và trong nền tảng và xác suất được hạ xuống với mỗi thử nghiệm mà bạn tạo. Ngay cả khi bạn sẽ cố gắng làm điều này, bạn sẽ có một nhiệm vụ rất khó khăn.

  3. Bạn có thể có lỗi trong các bài kiểm tra nhưng thường thì chúng dễ dàng bị bắt vì các bài kiểm tra được kiểm tra bởi mã được phát triển. Giữa mã và các bài kiểm tra bạn có một phản hồi tự thực thi. Cả hai đều đưa ra dự đoán về cách một cuộc gọi cụ thể của một giao diện nên hoạt động. Nếu phản hồi khác nhau, bạn không cần phải có lỗi trong mã. Bạn có thể có một lỗi trong bài kiểm tra là tốt.


Câu trả lời rất hay. Tôi thích ý tưởng về một vòng lặp tự củng cố giữa các bài kiểm tra và mã và quan sát rằng sẽ rất khó để viết các bài kiểm tra liên tục che giấu các lỗi trong nền tảng cơ bản.
Ryszard Szopa

không ngăn các thử nghiệm được tạo dựa trên các giả định thiếu sót về những gì mã thực tế nên làm. Điều này có thể dẫn đến các lỗi rất khó chịu còn lại không bị phát hiện trong quá trình thử nghiệm. Cách duy nhất để ngăn chặn điều đó là các bài kiểm tra được viết bởi bên thứ ba hoàn toàn không liên quan đến tổ chức viết mã thực tế, vì vậy họ không thể "làm ô nhiễm" suy nghĩ của nhau khi giải thích các tài liệu yêu cầu.
jwenting

24

Hãy thử làm các bài kiểm tra riêng lẻ càng nhỏ (ngắn) càng tốt.

Điều này sẽ làm giảm cơ hội tạo ra lỗi ở nơi đầu tiên. Ngay cả khi bạn quản lý để tạo một cái, nó vẫn dễ tìm thấy hơn. Các bài kiểm tra đơn vị được cho là nhỏ và cụ thể, với sai số thấp cho sự thất bại và sai lệch.

Cuối cùng, đó có lẽ chỉ là vấn đề kinh nghiệm. Bạn viết càng nhiều bài kiểm tra, bạn càng trở nên giỏi hơn, bạn càng ít có cơ hội thực hiện các bài kiểm tra tào lao.


3
Điều gì xảy ra nếu các bài kiểm tra cần một số thiết lập khá phức tạp? Đôi khi những thứ này không thuộc quyền kiểm soát của bạn.
Ryszard Szopa

Chà, tôi đoán thiết lập phức tạp là "điều kiện ban đầu" của các bài kiểm tra. Nếu thất bại, tất cả các bài kiểm tra của bạn sẽ thất bại. Trên thực tế, tôi đang làm việc với một dự án như vậy ngay bây giờ và những người không bao giờ sử dụng các bài kiểm tra đơn vị liên tục hỏi điều tương tự..cho đến khi chúng tôi giải thích các bài kiểm tra đơn vị thực sự là gì :) Sau đó, họ nhận ra rằng nó có thể được thực hiện, mặc dù rất lớn độ phức tạp của dự án.
dr Hannibal Lecter

Cách tốt nhất để kiểm tra xem "điều kiện ban đầu" này có được đáp ứng chính xác là câu hỏi của tôi không. Bạn có viết một bài kiểm tra riêng cho điều đó? Hoặc chỉ cho rằng các xét nghiệm sẽ phá vỡ nếu điều kiện này không đúng? Thế còn tình huống khi thiết lập không "tệ", chỉ hơi tắt thì sao?
Ryszard Szopa

2
Các xét nghiệm của bạn sẽ thất bại nếu các điều kiện ban đầu không đúng, đó là toàn bộ vấn đề. Khi ở trạng thái A, bạn mong đợi kết quả B. Nếu bạn không có trạng thái A, một bài kiểm tra sẽ thất bại. Tại thời điểm đó, bạn có thể điều tra lý do tại sao nó thất bại, điều kiện ban đầu tồi tệ hoặc thử nghiệm tồi, nhưng nó sẽ thất bại trong cả hai trường hợp. Thậm chí nếu nó là, như bạn nói, "hơi off" (ví dụ "A" => "B", "a" => "b"nhưng không bao giờ "a" => "B"hoặc thử nghiệm của bạn là xấu).
dr Hannibal Lecter

19

Một chiến thuật là viết thử nghiệm trước khi mã nó kiểm tra và đảm bảo thử nghiệm thất bại trước vì lý do đúng. Nếu bạn sử dụng TDD, bạn sẽ nhận được ít nhất mức kiểm tra thử nghiệm này.

Một cách toàn diện hơn để kiểm tra chất lượng của bộ kiểm tra là sử dụng kiểm tra đột biến .


2
Và bài kiểm tra của bạn thất bại vì lý do đúng đắn .
Frank Shearar

@Frank - Vâng. Tôi sẽ thêm nó vào câu trả lời.
Don Roby

Và bạn đang thêm một thử nghiệm mới cho hành vi mới sẽ được thử nghiệm. Đừng thêm vào các bài kiểm tra hiện có.
Huperniketes

@DonRoby, Bạn đã thấy thử nghiệm đột biến hữu ích trong thực tế chưa? Những thiếu sót bạn đã tìm thấy trong các trường hợp thử nghiệm của bạn với điều đó?
dzieciou

4

Đối với # 1 và # 3: Các bài kiểm tra đơn vị không được chứa bất kỳ logic nào, nếu bạn làm như vậy thì có lẽ bạn đang kiểm tra nhiều hơn một điều trong bài kiểm tra đơn vị của mình. Một cách thực hành tốt nhất để kiểm tra đơn vị là chỉ có một bài kiểm tra cho mỗi bài kiểm tra đơn vị.

Xem video này của Roy Osherove để tìm hiểu thêm về cách viết bài kiểm tra đơn vị tốt.


quảng cáo số 3 - Tôi đồng ý rằng các bài kiểm tra nên đơn giản nhất có thể và không chứa bất kỳ logic nào. Tuy nhiên, hãy nghĩ về giai đoạn thiết lập thử nghiệm, khi bạn tạo các đối tượng mà nó sẽ cần. Bạn có thể tạo ra các đối tượng hơi sai. Đây là loại vấn đề tôi đang suy nghĩ.
Ryszard Szopa

Khi bạn nói 'đối tượng hơi sai', bạn có nghĩa là trạng thái đối tượng không đúng hoặc thiết kế thực tế của đối tượng không đúng? Đối với trạng thái đối tượng, bạn có thể có thể viết các bài kiểm tra để kiểm tra tính hợp lệ của nó. Nếu thiết kế sai thì thử nghiệm sẽ thất bại.
Piers Myers

3

Về mặt số 1 - Tôi nghĩ rằng nên kết hợp đánh giá / mã cho mặt này của vấn đề. Thật dễ dàng để đưa ra các giả định hoặc chỉ hiểu sai nhưng nếu bạn phải giải thích bài kiểm tra của bạn đang làm gì, vấn đề là gì, bạn có nhiều khả năng sẽ nhận nếu bạn nhắm sai mục tiêu.


2

Phải có một điểm khi người ta nên ngừng cố gắng kiểm tra đơn vị. Nên biết khi nào nên vẽ đường thẳng. Chúng ta có nên viết trường hợp kiểm tra để kiểm tra trường hợp kiểm tra? Điều gì về các trường hợp thử nghiệm mới được viết để kiểm tra các trường hợp thử nghiệm? Làm thế nào chúng ta sẽ kiểm tra chúng?

if (0 > printf("Hello, world\n")) {
  printf("Printing \"Hello, world\" failed\n");
}

Chỉnh sửa: Cập nhật với lời giải thích theo đề nghị của bình luận.


-1 cái gì? Điều này dường như không có liên quan.
thay thế

2
Phải có một điểm khi người ta nên ngừng cố gắng kiểm tra đơn vị. Nên biết khi nào nên vẽ đường thẳng. Chúng ta có nên viết trường hợp kiểm tra để kiểm tra trường hợp kiểm tra? Điều gì về các trường hợp thử nghiệm mới được viết để kiểm tra các trường hợp thử nghiệm? Làm thế nào chúng ta sẽ kiểm tra chúng?
aufather

2
Process Brain đưa ra EInfiniteRecursion trong khi cố gắng ngoại suy câu nói của bạn ...
Mason Wheeler

Thay thế câu trả lời của bạn bằng nhận xét của bạn và bạn sẽ nhận được +1
Lưu ý để tự nghĩ về một cái tên

3
Trong tất cả các công bằng, ví dụ của bạn là một người rơm. Bạn đang kiểm tra hệ thống con printf () trong thư viện C, không phải chương trình thực tế gọi printf (). Tôi đồng ý, tuy nhiên, tại một số điểm, người ta phải phá vỡ các bài kiểm tra đệ quy.
Tim Post

2

Chào.
Bạn phải nộp đơn:

  • Sản phẩm của bạn
  • Thử nghiệm của bạn cho sản phẩm đó.

Khi bạn đang chạy thử nghiệm đối với sản phẩm của mình, bạn thực sự không bị giới hạn trong thử nghiệm mà là tương tác giữa sản phẩm và thử nghiệm của bạn. Nếu kiểm tra thất bại, nó không nói rằng ứng dụng có lỗi. Nó nói rằng sự tương tác giữa sản phẩm và thử nghiệm đã không thành công . Bây giờ công việc của bạn là xác định những gì đã sai. Nó có thể là:

  • ứng dụng không hoạt động như bạn mong đợi (kỳ vọng này được thể hiện trong bài kiểm tra của bạn)
  • ứng dụng đang hoạt động chính xác, bạn chưa ghi lại hành vi này một cách chính xác (trong các thử nghiệm của bạn)

Đối với tôi các bài kiểm tra thất bại không phải là phản hồi đơn giản, rằng điều này và điều đó là sai . Đó là chỉ báo rằng có sự không nhất quán, và tôi cần kiểm tra cả hai để kiểm tra muốn đi sai. Cuối cùng, tôi chịu trách nhiệm xác minh rằng ứng dụng là chính xác, các bài kiểm tra chỉ là một công cụ để làm nổi bật các khu vực có thể đáng kiểm tra.

Các thử nghiệm chỉ kiểm tra một số phần của ứng dụng. Tôi kiểm tra ứng dụng, tôi kiểm tra các bài kiểm tra.


2

Các thử nghiệm không nên "thông minh" đủ để chứa lỗi.

Mã bạn đang viết thực hiện một bộ thông số kỹ thuật. (Nếu X thì Y, trừ khi Z trong trường hợp Q, v.v.). Tất cả các thử nghiệm nên cố gắng thực hiện là xác định rằng X thực sự là Y trừ khi Z trong trường hợp này Q. Điều này có nghĩa là tất cả các thử nghiệm nên làm là đặt X và xác minh Y.

Nhưng điều đó không bao gồm tất cả các trường hợp, có lẽ bạn đang nói, và bạn đã đúng. Nhưng nếu bạn thực hiện bài kiểm tra "thông minh" đủ để biết rằng X chỉ nên bằng Y nếu không phải Z thì về cơ bản bạn đang thực hiện lại logic nghiệp vụ trong bài kiểm tra. Đây là vấn đề vì lý do chúng tôi sẽ đi sâu hơn một chút bên dưới. Bạn không nên cải thiện phạm vi bảo hiểm mã bằng cách làm cho thử nghiệm đầu tiên của mình "thông minh hơn", thay vào đó, bạn nên thêm thử nghiệm câm thứ hai, đặt X và Z và xác minh Q. Bằng cách đó, bạn sẽ có hai thử nghiệm, một thử nghiệm bao gồm trường hợp chung ( đôi khi còn được gọi là đường dẫn hạnh phúc) và một trường hợp bao gồm trường hợp cạnh như một thử nghiệm riêng biệt.

Có một số lý do cho việc này, trước tiên và quan trọng nhất là làm thế nào để bạn xác định xem một bài kiểm tra thất bại có phải là do lỗi trong logic nghiệp vụ hay lỗi trong các bài kiểm tra không? Rõ ràng câu trả lời là nếu các bài kiểm tra càng đơn giản càng tốt thì chúng rất khó có khả năng chứa lỗi. Nếu bạn nghĩ rằng các bài kiểm tra của bạn cần kiểm tra thì bạn đã kiểm tra sai .

Các lý do khác bao gồm bạn chỉ cần nhân rộng nỗ lực (như tôi đã đề cập, viết một bài kiểm tra đủ thông minh để thực hiện tất cả các khả năng trong một bài kiểm tra về cơ bản là sao chép logic nghiệp vụ mà bạn đang thử nghiệm ở nơi đầu tiên), nếu yêu cầu thay đổi sau đó các bài kiểm tra phải dễ dàng thay đổi để phản ánh các yêu cầu mới, các bài kiểm tra đóng vai trò là một loại tài liệu (chúng là một cách chính thức để nói đặc điểm kỹ thuật của đơn vị được kiểm tra là gì), v.v.

TL: DR: Nếu các bài kiểm tra của bạn cần kiểm tra thì bạn đã làm sai. Viết bài kiểm tra câm .


0

Không phải là một câu trả lời (tôi không có đặc quyền để bình luận), nhưng tự hỏi liệu bạn có quên các lý do khác để phát triển các trường hợp thử nghiệm không ...
Một khi bạn tìm ra tất cả các lỗi trong các bài kiểm tra, bạn có thể hồi quy kiểm tra ứng dụng của mình một cách dễ dàng. Bộ kiểm tra tự động sẽ giúp bạn tìm ra vấn đề sớm hơn, trước khi tích hợp. Các thay đổi đối với các yêu cầu tương đối dễ kiểm tra hơn, vì các thay đổi có thể trở thành phiên bản mới hơn, đã thay đổi của các trường hợp thử nghiệm cũ vượt qua và các trường hợp cũ hơn ở lại để nhận lỗi.


0

Câu trả lời ngắn: Mã sản xuất kiểm tra các bài kiểm tra .

So sánh điều này với mô hình tín dụng / ghi nợ được sử dụng trong kinh tế. Các cơ chế rất đơn giản - Nếu tín dụng khác với ghi nợ thì có gì đó không đúng.

anh ta cũng đi kiểm tra đơn vị - Nếu một bài kiểm tra thất bại, nó chỉ ra có gì đó không đúng. Nó có thể là mã sản xuất, nhưng nó cũng có thể là mã thử nghiệm! Phần cuối cùng này nếu quan trọng.

Lưu ý rằng lỗi loại (1) của bạn không thể được tìm thấy bằng các bài kiểm tra đơn vị. Để tránh các loại lỗi này, bạn cần các công cụ khác.

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.