Kiểm tra: xác định hay không xác định?


17

Có tốt hơn để có một

  • Bộ kiểm tra xác định, kết quả trong các thử nghiệm tương tự thành công
  • Bộ kiểm tra không xác định, có khả năng bao gồm nhiều trường hợp hơn

?

Ví dụ: Bạn viết một bộ kiểm tra để kiểm tra chức năng của bộ điều khiển trong một ứng dụng MVC. Bộ điều khiển yêu cầu dữ liệu ứng dụng từ cơ sở dữ liệu làm đầu vào trong quá trình thử nghiệm. Có hai lựa chọn để làm điều này:

  • Bạn mã hóa hàng nào từ cơ sở dữ liệu kiểm tra được chọn làm đầu vào (ví dụ: hàng thứ 10 và 412)
  • Bạn sử dụng trình tạo số ngẫu nhiên để giả ngẫu nhiên chọn dữ liệu từ cơ sở dữ liệu (hai hàng được chọn bởi trình tạo số ngẫu nhiên)

Đầu tiên là xác định: mỗi lần chạy thử nghiệm cho cùng một lần sửa đổi mã sẽ mang lại kết quả như nhau. Thứ hai là không xác định: mỗi lần chạy bộ thử nghiệm có khả năng mang lại một kết quả khác nhau. Tuy nhiên, dữ liệu được chọn ngẫu nhiên có thể là đại diện tốt hơn cho các trường hợp cạnh dữ liệu. Nó có thể mô phỏng người dùng cung cấp cho bộ điều khiển của chúng tôi dữ liệu không thể đoán trước tốt hơn?

Lý do để chọn cái này hơn cái kia là gì?


5
Thử nghiệm đó chỉ thất bại, đôi khi. martinfowler.com/articles/nonDeterminism.html

Cảm ơn liên kết đó. Với bài viết đó trong tâm trí, tôi cảm thấy tôi cần phải làm rõ rằng tính không xác định có nghĩa là trong bối cảnh của bộ thử nghiệm này. Bởi vì dữ liệu được chọn ngẫu nhiên từ cơ sở dữ liệu, tất cả dữ liệu được cung cấp cho bộ điều khiển là dữ liệu hợp lệ theo mặc định. Điều này có nghĩa là các phủ định sai không tồn tại trong bộ thử nghiệm khi nói đến tính không xác định. Theo một cách nào đó, tính ngẫu nhiên này mô phỏng người dùng chọn dữ liệu 'ngẫu nhiên' để sử dụng trong bộ điều khiển. Đây không nhất thiết là cùng một chủ nghĩa không xác định mà bài báo thảo luận, phải không?
DCKing


10
@DCKing: Xem xét những gì xảy ra nếu thử nghiệm của bạn thất bại. Được rồi, bạn có một lỗi. Uh, bây giờ thì sao? Chạy lại nó trong chế độ gỡ lỗi! Nơi nó thành công! Giống như nó thực hiện hàng trăm lần tiếp theo bạn chạy nó, và sau đó bạn viết ra vấn đề như một cuộc tấn công bằng tia vũ trụ. Không xác định trong các thử nghiệm âm thanh hoàn toàn không thể thực hiện được. Nếu bạn cảm thấy cần phải bao quát nhiều mặt đất hơn trong các trường hợp thử nghiệm của mình, hãy bao quát nhiều mặt đất hơn. Khởi tạo RNG của bạn với một hạt giống được thiết lập và chạy "thử nghiệm" vài trăm lần với các giá trị ngẫu nhiên nhất quán.
Phoshi

1
(cuối cùng đã tìm được một máy mà tôi có thể tìm kiếm twitter một cách chính xác - " Bài kiểm tra đó đôi khi thất bại " là từ #FiveWordTechHorrors trên Twitter - muốn ghi có đúng cách)

Câu trả lời:


31

Khi mỗi lần chạy bộ kiểm tra cung cấp cho bạn khả năng mang lại một kết quả khác nhau, thử nghiệm gần như hoàn toàn vô giá trị - khi bộ công cụ cho bạn thấy một lỗi, bạn có khả năng cao là bạn không thể sao chép nó và khi bạn cố gắng khắc phục lỗi, bạn không thể xác minh nếu sửa chữa của bạn hoạt động.

Vì vậy, khi bạn nghĩ rằng bạn cần sử dụng một số loại trình tạo số ngẫu nhiên để tạo dữ liệu thử nghiệm của mình, hãy đảm bảo bạn luôn khởi tạo trình tạo với cùng một hạt giống hoặc duy trì dữ liệu thử nghiệm ngẫu nhiên của bạn trong một tệp trước khi đưa vào thử nghiệm của bạn, để bạn có thể chạy lại bài kiểm tra một lần nữa với chính xác cùng một dữ liệu từ lần chạy trước. Bằng cách này, bạn có thể chuyển đổi bất kỳ bài kiểm tra không xác định nào thành bài kiểm tra xác định.

EDIT: Sử dụng trình tạo số ngẫu nhiên để chọn một số dữ liệu kiểm tra là IMHO đôi khi là dấu hiệu cho thấy quá lười biếng trong việc chọn dữ liệu kiểm tra tốt . Thay vì ném 100.000 giá trị kiểm tra được chọn ngẫu nhiên và hy vọng rằng điều này sẽ đủ để phát hiện ra tất cả các lỗi nghiêm trọng, hãy sử dụng bộ não của bạn tốt hơn, chọn 10 đến 20 trường hợp "thú vị" và sử dụng chúng cho bộ kiểm tra. Điều này sẽ không chỉ dẫn đến chất lượng tốt hơn các bài kiểm tra của bạn, mà còn cho hiệu suất cao hơn của bộ phần mềm.


Cảm ơn câu trả lời của bạn. Ý kiến ​​của bạn về nhận xét tôi đưa ra cho câu hỏi của tôi là gì?
DCKing

1
@DCKing: nếu bạn thực sự nghĩ rằng một trình tạo ngẫu nhiên sẽ tốt hơn trong việc chọn các trường hợp kiểm thử tốt hơn bạn (điều tôi nghi ngờ), hãy sử dụng nó một lần để tìm các kết hợp dữ liệu kiểm tra khi chương trình của bạn thất bại và đưa các kết hợp đó vào phần "mã hóa cứng" của bộ thử nghiệm của bạn.
Doc Brown

Cảm ơn một lần nữa. Đã cập nhật câu trả lời của tôi để nó dường như không áp dụng cho chỉ các ứng dụng MVC.
DCKing

1
Trong một số bối cảnh UI (ví dụ: các trò chơi lấy đầu vào bộ điều khiển) có các chương trình thử nghiệm tạo mục nhập khóa ngẫu nhiên có thể hữu ích cho kiểm tra căng thẳng. Họ có thể phát hiện ra những khiếm khuyết khó tìm thấy với đầu vào có chủ ý.
Gort Robot

@StevenBurnap: tốt, theo cách tôi hiểu câu hỏi, tôi nghĩ rằng OP đã có thử nghiệm hồi quy thông thường hơn trong tâm trí. Tất nhiên, tôi đồng ý, kiểm tra căng thẳng là một trường hợp đặc biệt cũng có thể phụ thuộc vào phần cứng và dẫn đến hành vi không xác định ngay cả khi bạn không sử dụng trình tạo ngẫu nhiên. Đó là điều được mô tả trong bài viết được liên kết bởi MichaelT trong bình luận đầu tiên bên dưới câu hỏi. Và ngay cả trong thử nghiệm căng thẳng với đầu vào ngẫu nhiên, ít nhất người ta có thể cố gắng làm cho hành vi mang tính quyết định hơn bằng cách sử dụng một hạt giống ngẫu nhiên xác định.
Doc Brown

4

Cả xác định và không xác định đều có một vị trí

Tôi sẽ chia chúng như sau:

Bài kiểm tra đơn vị.

Chúng nên có các xét nghiệm xác định, lặp lại với cùng một dữ liệu chính xác mỗi lần. Các thử nghiệm đơn vị đi kèm với các phần mã cụ thể, riêng biệt và nên kiểm tra chúng theo kiểu xác định.

Kiểm tra căng thẳng chức năng và đầu vào.

Chúng có thể sử dụng cách tiếp cận không xác định với các cảnh báo sau:

  • thực tế đó được phân định rõ ràng và được gọi ra
  • các giá trị ngẫu nhiên được chọn được ghi lại và có thể thử lại bằng tay

3

Cả hai.

Các xét nghiệm xác định và không xác định có các trường hợp sử dụng khác nhau và các giá trị khác nhau cho bộ của bạn. Nói chung không xác định không thể cung cấp chính xác tương tự như kiểm tra xác định, mà đã dần dần phát triển thành "kiểm tra không xác định cung cấp không có giá trị." Điều này là sai. Chúng có thể ít chính xác hơn, nhưng chúng cũng có thể rộng hơn nhiều, có lợi ích riêng của nó.

Hãy lấy một ví dụ: bạn viết một hàm sắp xếp danh sách các số nguyên. Điều gì sẽ là một số bài kiểm tra đơn vị xác định mà bạn thấy hữu ích?

  • Một danh sách trống
  • Một danh sách chỉ có một yếu tố
  • Một danh sách với tất cả các yếu tố giống nhau
  • Một danh sách có nhiều yếu tố độc đáo
  • Một danh sách có nhiều yếu tố, một số trong đó là trùng lặp
  • Một danh sách với NaN, INT_MININT_MAX
  • Một danh sách đã được sắp xếp một phần
  • Một danh sách với 10.000.000 phần tử

Và đó chỉ là một chức năng sắp xếp! Chắc chắn, bạn có thể lập luận rằng một số trong số này là không cần thiết, hoặc một số trong số này có thể được loại trừ với lý do không chính thức. Nhưng chúng tôi là các kỹ sư và chúng tôi đã thấy lý do không chính thức nổ tung trong khuôn mặt của chúng tôi. Chúng tôi biết rằng chúng tôi không đủ thông minh để hiểu hoàn toàn các hệ thống chúng tôi đã xây dựng hoặc hoàn toàn giữ được sự phức tạp trong đầu. Đó là lý do tại sao chúng tôi viết bài kiểm tra ở nơi đầu tiên. Thêm kiểm tra không xác định chỉ nói rằng chúng ta có thể không nhất thiết phải đủ thông minh để biết tất cả các bài kiểm tra tốt một tiên nghiệm. Bằng cách ném dữ liệu bán ngẫu nhiên vào chức năng của bạn, nhiều khả năng bạn sẽ tìm thấy một trường hợp cạnh bạn đã bỏ lỡ.

Tất nhiên, điều đó cũng không loại trừ kiểm tra xác định. Thử nghiệm không phá hủy giúp tìm ra lỗi trong các khu vực lớn của chương trình. Tuy nhiên, khi bạn đã tìm thấy các lỗi, bạn cần một cách có thể lặp lại để cho thấy rằng bạn đã sửa nó. Vì thế:

  • Sử dụng các thử nghiệm không xác định để tìm lỗi trong mã của bạn.
  • Sử dụng các bài kiểm tra xác định để xác minh các bản sửa lỗi trong mã của bạn.

Lưu ý rằng điều này có nghĩa là rất nhiều lời khuyên chắc chắn về các bài kiểm tra đơn vị không nhất thiết phải áp dụng cho các bài kiểm tra không xác định. Ví dụ, họ phải nhanh. Các thử nghiệm thuộc tính cấp thấp phải nhanh, nhưng thử nghiệm không xác định như "mô phỏng người dùng nhấp ngẫu nhiên vào nút trên trang web của bạn và đảm bảo bạn không bao giờ gặp lỗi 500" nên ưu tiên tính toàn diện hơn tốc độ. Chỉ cần có một thử nghiệm như thế chạy độc lập với quá trình xây dựng của bạn để nó không làm chậm quá trình phát triển. Ví dụ, chạy nó trên hộp dàn riêng của nó.


-1

Bạn không thực sự muốn xác định so với không xác định.

Những gì bạn có thể muốn là "luôn luôn giống nhau" so với "không phải luôn luôn giống nhau".

Ví dụ: bạn có thể có số bản dựng tăng theo mỗi bản dựng và khi bạn muốn một số số ngẫu nhiên, bạn khởi tạo trình tạo số ngẫu nhiên với số bản dựng làm hạt giống. Vì vậy, mỗi bản dựng, bạn thực hiện các thử nghiệm của mình với các giá trị khác nhau, cho bạn nhiều cơ hội hơn để tìm lỗi.

Nhưng một khi lỗi được tìm thấy, tất cả những gì bạn cần làm là chạy thử nghiệm với cùng số bản dựng và nó có thể được lặp lại.


1
Hoặc nếu bạn không có số bản dựng để sử dụng, hãy đặt giá trị ban đầu của hạt giống vào đầu ra của lần chạy thử, để bạn có thể chạy lại các thử nghiệm với cùng một hạt giống.
RemcoGerlich
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.