65.000.000.000 bài kiểm tra để chạy


50

Tôi đã được hỏi về cách chạy một bộ 65.000.000.000 bài kiểm tra và tôi tự hỏi liệu có bình thường khi có một dự án với số lượng thử nghiệm khổng lồ như vậy không.

Bạn đã làm việc trong các dự án với đặc điểm này?


32
65 tỷ (10e9) bài kiểm tra? Đây là một vấn đề thực tế hoặc một câu hỏi phỏng vấn?

40
Tôi rất muốn biết ai đã viết 65 tỷ bài kiểm tra và mất bao nhiêu năm.
Giàn khoan

46
Với 65 tỷ bài kiểm tra, nếu bạn có thể chạy 1000 bài kiểm tra / giây, sẽ mất khoảng 2 năm để chạy. 10.000 bài kiểm tra / giây là một chút trong hai tháng. 100.000 bài kiểm tra / giây sẽ mất khoảng một tuần. Đây là mô tả một số khả năng xử lý nghiêm túc để chạy thử nghiệm trong một khung thời gian hợp lý.

20
Tôi không muốn trở thành người viết ra ma trận truy xuất nguồn gốc ...
mouviciel

23
@DanPichelman - Rõ ràng, bạn cần viết thêm nửa tỷ bài kiểm tra để kiểm tra xem trình tạo kiểm tra có tạo ra các bài kiểm tra chính xác không.
Bobson

Câu trả lời:


103

Với 65 tỷ bài kiểm tra, có vẻ như bạn được yêu cầu kiểm tra tất cả các đầu vào có thể. Điều này không hữu ích - về cơ bản bạn đang kiểm tra xem bộ xử lý của bạn có hoạt động chính xác không, mã của bạn có đúng không.

Bạn nên kiểm tra các lớp tương đương thay thế. Điều này sẽ làm giảm đáng kể phạm vi đầu vào thử nghiệm của bạn.

Cũng xem xét liệu bạn có thể chia hệ thống của bạn thành các phần nhỏ hơn. Mỗi mảnh sẽ dễ dàng hơn để kiểm tra độc lập, và sau đó bạn có thể thực hiện một số thử nghiệm tích hợp mang tất cả các mảnh lại với nhau.

Nếu bạn vẫn muốn đảm bảo rằng một số kết hợp đầu vào đó hoạt động, có lẽ bạn có thể thử kiểm tra fuzz . Bạn sẽ nhận được một số lợi ích của việc thử nghiệm rất nhiều đầu vào khác nhau, nhưng không chạy tất cả 65 tỷ trong số chúng.


12
+1, đặc biệt là "về cơ bản bạn đang kiểm tra xem bộ xử lý của bạn có hoạt động chính xác không"
Doc Brown

4
Đối với chức năng đơn giản (bit fiddling vv) Tôi làm có xu hướng để kiểm tra tất cả các giá trị có thể. Đó là bằng chứng ngu ngốc và do đó mang lại cho tôi sự tự tin tốt hơn nhiều so với các lớp tương đương thử nghiệm (xuất phát và do đó có khả năng sai sót). Tất nhiên điều đó không còn hiệu quả nữa khi đầu vào khả thi của bạn lên tới hàng tỷ.
Konrad Rudolph

39

Nếu đây là một bộ thử nghiệm thực sự, thì bạn không muốn đến bất cứ nơi nào gần làm việc với nó.

Toàn bộ công việc của người kiểm tra là đạt được sự cân bằng giữa kiểm tra đủ kỹ lưỡng để tự tin rằng bạn đã có kết quả "đúng" và viết một vài bài kiểm tra đủ để họ có thể chạy trong một khoảng thời gian hợp lý.

Nhiều bài kiểm tra có thể được trừu tượng hóa thành "các lớp tương đương", có nghĩa là thay vì chạy 3 tỷ bài kiểm tra, bạn chạy 1 bài kiểm tra mang lại cho bạn mức độ tin cậy hợp lý rằng tất cả các bài kiểm tra khác trong lớp tương đương đó sẽ chạy thành công, nếu bạn quyết định lãng phí thời gian chạy chúng

Bạn nên nói với bất cứ ai đang nghĩ đến việc chạy 65 tỷ bài kiểm tra rằng họ cần thực hiện một bài kiểm tra trừu tượng hóa công việc tốt hơn thành các lớp tương đương.


+1 về kiểm tra kỹ lưỡng nhưng hiệu quả.
Marco

23

Nhiều khả năng, bạn đã đạt được con số 65 tỷ bài kiểm tra của mình bằng cách tính toán tất cả các kết hợp đầu vào có thể có trong hệ thống đang được kiểm tra hoặc bằng cách tính độ phức tạp theo chu kỳ và giả sử một bài kiểm tra phải được viết cho mỗi đường dẫn thực hiện duy nhất này.

Đây không phải là cách các bài kiểm tra thực sự được viết, bởi vì như các áp phích và bình luận khác đã chỉ ra, sức mạnh kỹ thuật cần thiết để thực hiện 65 tỷxét nghiệm là đáng kinh ngạc. Điều này sẽ giống như viết một bài kiểm tra thực hiện một phương pháp để thêm hai số nguyên bằng cách cắm vào mọi hoán vị có thể có của hai giá trị 32 bit và kiểm tra kết quả. Đó là sự điên rồ hoàn toàn. Bạn phải vẽ đường thẳng và xác định một tập hợp con của tất cả các trường hợp thử nghiệm có thể, giữa chúng sẽ đảm bảo rằng hệ thống sẽ hoạt động như mong đợi trong toàn bộ phạm vi đầu vào. Ví dụ. bạn kiểm tra thêm một vài số "thông thường", bạn kiểm tra một vài kịch bản số âm, bạn kiểm tra các giới hạn kỹ thuật như các kịch bản tràn và bạn kiểm tra bất kỳ kịch bản nào sẽ dẫn đến lỗi. Như đã đề cập, các loại bài kiểm tra khác nhau này thực hiện "các lớp tương đương"; chúng cho phép bạn lấy một mẫu đại diện của các đầu vào có thể, cùng với bất kỳ "ngoại lệ" đã biết nào,

Hãy xem xét một trong những katas mã cơ bản, Bộ tạo số La Mã. Nhiệm vụ, được thực hiện bằng các kỹ thuật TDD theo kiểu "dojo", là viết một hàm có thể chấp nhận bất kỳ số nào từ 1 đến 3000 và tạo ra số La Mã chính xác cho giá trị số đó.

Bạn không giải quyết vấn đề này bằng cách viết 3000 bài kiểm tra từng bài một, và lần lượt vượt qua chúng. Đó là sự mất trí; bài tập thường mất từ ​​một đến hai giờ và bạn sẽ có mặt trong nhiều ngày để kiểm tra từng giá trị riêng lẻ. Thay vào đó, bạn có được thông minh. Bạn bắt đầu với trường hợp cơ bản đơn giản nhất (1 == "I"), thực hiện bằng cách sử dụng chiến lược "ít mã nhất" ( return "I";) và sau đó tìm cách mã bạn có sẽ hành xử không chính xác trong một kịch bản dự kiến ​​khác (2 == " II "). Rửa sạch và lặp lại; nhiều khả năng, bạn đã thay thế triển khai ban đầu của mình bằng một cái gì đó lặp lại ký tự "Tôi" thường xuyên khi cần thiết (như return new String('I',number);). Điều đó rõ ràng sẽ vượt qua bài kiểm tra III, vì vậy bạn đừng bận tâm; thay vào đó, bạn viết bài kiểm tra cho 4 == "IV", mà bạn biết việc triển khai hiện tại đã thắng '

Hoặc, theo kiểu phân tích hơn, bạn kiểm tra từng quyết định có điều kiện được tạo bởi mã (hoặc cần phải có) và viết một bài kiểm tra được thiết kế để nhập mã cho từng kết quả có thể có của mỗi quyết định. Nếu bạn có 5 câu lệnh if (mỗi câu có một nhánh đúng và sai), mỗi câu lệnh hoàn toàn độc lập với nhau, bạn mã 10 bài kiểm tra, không phải 32. Mỗi bài kiểm tra sẽ được thiết kế để khẳng định hai điều về một quyết định cụ thể có thể; đầu tiên là quyết định chính xác được đưa ra, và sau đó mã được nhập với điều kiện đó là chính xác. Bạn không mã hóa một bài kiểm tra cho mỗi hoán vị có thể có của các quyết định độc lập. Nếu các quyết định phụ thuộc, thì bạn phải kiểm tra nhiều kết hợp trong số chúng, nhưng có ít kết hợp như vậy hơn vì một số quyết định chỉ được đưa ra khi một quyết định khác có kết quả cụ thể.


5

Đây có phải là "bình thường"?, Không. Trong đó "bình thường" được định nghĩa là trải nghiệm trung bình hoặc điển hình. Không thể nói rằng tôi đã từng phải làm việc trong một dự án như thế, nhưng tôi đã tham gia vào một dự án mà cứ sau vài triệu bitcoin sẽ bị lật. Kiểm tra cái đó là ... một thử thách.

Có khả năng cần thiết không? Vâng, điều đó phụ thuộc vào sự đảm bảo và chi tiết cụ thể của dự án. Lúc đầu hơi khó hiểu, nhưng câu hỏi của bạn rất nhẹ về chi tiết cụ thể.

Như những người khác (MichaelT) đã chỉ ra, thời gian để hoàn thành nhiệm vụ này với thử nghiệm nối tiếp làm cho điều này không thực tế. Vì vậy, song song trở thành xem xét đầu tiên của bạn. Có bao nhiêu hệ thống kiểm tra bạn có thể ném vào vấn đề này, và bạn có hỗ trợ gì để đối chiếu kết quả của nhiều hệ thống đó?

Điều gì đảm bảo cho bạn rằng thiết bị hoặc thuật toán mà bạn đang thử nghiệm đang được nhân rộng đáng tin cậy? Phần mềm khá đáng tin cậy trong việc nhân rộng, nhưng các thiết bị phần cứng (đặc biệt là thế hệ đầu tiên) có thể có vấn đề về sản xuất. Lỗi thử nghiệm sai trong trường hợp đó có thể chỉ ra thuật toán xấu hoặc thiết bị không lắp ráp chính xác. Bạn có cần phân biệt giữa hai trường hợp đó?

Bạn cũng cần xem xét cách bạn sẽ xác nhận các hệ thống kiểm tra. Giả sử một lý do chính đáng cho nhiều trường hợp thử nghiệm, bạn sẽ cần rất nhiều tự động hóa. Việc tự động hóa đó cần được kiểm tra để đảm bảo nó không bị lỗi trong việc tạo các trường hợp thử nghiệm của bạn. Kiểm tra tại chỗ cho các lỗi thực sự sẽ tương đương với việc tìm kim trong đống cỏ khô.

Liên kết arstechnica này có thể hoặc không thể làm sáng tỏ một số cái nhìn sâu sắc về các cân nhắc thử nghiệm của bạn. Các cụm GPU thường được sử dụng cho các mật khẩu bẻ khóa mạnh mẽ. Một trong những trích dẫn trong bài viết có thể can cycle through as many as 350 billion guesses per second, do đó loại đặt các bài kiểm tra 65B của bạn trong quan điểm. Đây có thể là một miền khác nhau, nhưng nó cho thấy cách tiếp cận nhiệm vụ từ các góc độ khác nhau có thể mang lại một giải pháp khả thi.


3

Tôi không nghĩ rằng việc duy trì thử nghiệm 6,5e + 10 ở nơi đầu tiên là khả thi , do đó, việc chạy chúng có thể là điều cần thiết. Ngay cả các dự án lớn nhất, như Debian với tất cả các gói của nó, chỉ có tổng số vài trăm triệu SLOC.

Nhưng nếu bạn phải chạy một số lượng lớn các bài kiểm tra, có một vài chiến lược.

  • Đừng chạy tất cả. Hầu hết có lẽ không phải mọi thử nghiệm đều phụ thuộc vào mọi đường dẫn mã. Xác định sự phụ thuộc giữa các hệ thống con và các thử nghiệm của chúng và giữa các bộ thử nghiệm và bạn sẽ chỉ có thể chạy thử nghiệm đơn vị có liên quan đến một thay đổi cụ thể, chỉ các thử nghiệm tích hợp tùy thuộc vào các thử nghiệm đơn vị này, v.v.

  • Chạy chúng song song. Với cơ sở mã khổng lồ, có lẽ bạn có một trang trại xây dựng khổng lồ (trở lại tại JetBrains, một hoạt động tương đối nhỏ, chúng tôi đã từng có 40-50 đại lý xây dựng chạy trên trang trại tích hợp / xây dựng liên tục IDEA). Vì các thử nghiệm đơn vị là độc lập và các thử nghiệm tích hợp có thể sử dụng lại mã đã được xây dựng, các thử nghiệm tương đối dễ dàng để song song hóa.

  • Dừng chạy sớm. Nếu bạn biết rằng một bộ kiểm tra cụ thể phụ thuộc vào chức năng hợp lý của nó về tính chính xác của một bộ kiểm tra khác, bạn có thể cắt toàn bộ chuỗi khi bạn thấy một liên kết bị lỗi.

Tuyên bố miễn trừ trách nhiệm: Tôi không phải là kỹ sư kiểm tra chuyên nghiệp. Lấy phần trên với một hạt muối.


5
... Tất nhiên, tại JetBrains, những đại lý xây dựng đó là miễn phí vì họ phát triển TeamCity và sở hữu nó hoàn toàn. Các "hoạt động tương đối nhỏ" khác có thể sẽ bị đau tim khi nghĩ đến chi phí ban đầu khoảng 15.000 đô la (chỉ dành cho phần mềm; thêm 40-50 đơn vị blademount và phần cứng khác, và thậm chí sử dụng một bản phân phối Linux miễn phí để lưu trữ tất cả các bạn ' dễ dàng nói về mức lương hàng năm của một nhà phát triển cao cấp) và 6500 đô la phí bảo trì hàng năm, cộng với thời gian và kỹ năng của nhân viên CNTT cần thiết để giữ cho trang trại xây dựng hoạt động tốt.
KeithS

0

Mặc dù đã có một số gợi ý tốt ở đây về cách cố gắng lén lút với ít bài kiểm tra hơn, tôi thực sự nghi ngờ hệ thống của bạn chỉ có 65 tỷ kết hợp đầu vào. Đó là ít hơn 36 bit đầu vào. Giả sử bạn đã thực hiện tất cả các lời khuyên đưa ra ở trên.

Nếu mỗi thử nghiệm mất khoảng một phần nghìn giây để chạy và bạn phân phối các thử nghiệm trên chỉ 10 bộ xử lý (một PC bình thường), thử nghiệm sẽ chạy trong hơn 69 ngày. Đó là một thời gian, nhưng không hoàn toàn vô lý. Phân phối trên 100 bộ xử lý (một tá PC bình thường hoặc một PC máy chủ hợp lý) và các thử nghiệm sẽ hoàn thành trong vòng dưới 7 ngày. Bạn có thể chạy chúng mỗi tuần để kiểm tra hồi quy.

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.