Nếu bạn chỉ nên có một khẳng định cho mỗi bài kiểm tra; Làm thế nào để kiểm tra nhiều đầu vào?


15

Tôi đang cố gắng xây dựng một số trường hợp thử nghiệm và đã đọc rằng bạn nên thử và giới hạn số lượng xác nhận cho mỗi trường hợp thử nghiệm.

Vì vậy, câu hỏi của tôi là, cách tốt nhất để kiểm tra một chức năng với nhiều đầu vào là gì. Ví dụ, tôi có một hàm phân tích một chuỗi từ người dùng và trả về số phút. Chuỗi có thể ở dạng "5w6h2d1m", trong đó w, h, d, mtương ứng với số tuần, giờ, ngày và phút.

Nếu tôi muốn làm theo '1 xác nhận cho mỗi quy tắc kiểm tra', tôi có phải thực hiện nhiều thử nghiệm cho mỗi biến thể của đầu vào không? Điều đó có vẻ ngớ ngẩn vì vậy thay vào đó tôi chỉ có một cái gì đó như:

self.assertEqual(parse_date('5m'), 5)
self.assertEqual(parse_date('5h'), 300)
self.assertEqual(parse_date('5d') ,7200)
self.assertEqual(parse_date('1d4h20m'), 1700)

Trong một trường hợp thử nghiệm. Có cách nào tốt hơn?


Cách tốt nhất để làm như vậy là sử dụng các tham số (một số khung hỗ trợ tính năng này, tất cả các khung nên). Bằng cách này, bạn đang kiểm tra một hành vi duy nhất nhưng có tính đến nhiều trường hợp kiểm tra và vẫn có thể thấy giá trị tham số nào gây ra lỗi nếu xảy ra lỗi
Kemoda

Câu trả lời:


23

Một cách thực tế hơn để xem một "quy tắc" khẳng định cho mỗi bài kiểm tra, là để các xác nhận của bạn trong một bài kiểm tra bao gồm một khái niệm duy nhất.

Bằng cách này, bạn vẫn đang thử nghiệm một khái niệm trong một thử nghiệm duy nhất. Trong trường hợp của bạn, liệu chuỗi đầu vào của bạn có được phân tích cú pháp chính xác trong một ngày không.

Bạn nên thực hiện phán đoán của mình trong từng trường hợp cụ thể để kiểm tra xem bạn có nên thử nghiệm một khái niệm duy nhất với nhiều khẳng định hoặc có một khẳng định duy nhất trong nhiều thử nghiệm hay không.

Chọn tùy chọn giúp kiểm tra rõ ràng hơn, ít lặp lại hơn trong khi vẫn có các bài kiểm tra của bạn có thể làm nổi bật các điểm thất bại khác nhau trong phương pháp của bạn. Bạn muốn nó rõ ràng khi một bài kiểm tra thất bại chính xác những gì đã xảy ra thay vì phải gỡ lỗi bài kiểm tra của bạn để tìm ra những gì đã sai.


17

Nó phụ thuộc rất nhiều vào thư viện thử nghiệm của bạn. Trong thư viện C # NUnit, bạn có thể làm một cái gì đó như:

[TestCase('5m', 5)]
[TestCase('5h', 300)]
[TestCase('5d', 7200)]
[TestCase('1d4h20m', 1700)]
public void ParseDateTest(inputString, expectedMinutes)
{
    Assert.That(parse_date(inputString), Is.EqualTo(expectedMinutes));
}

Trong java với testng, bạn có các phương thức
@DataProvider

Đó là giải pháp tốt nhất IMHO. trong hầu hết mọi ngôn ngữ bạn có thể tham số hóa các bài kiểm tra của mình. cho java: @Parameterized , JunitParams , Zohhak
piotrek

3

Vâng, thực hiện nhiều thử nghiệm cho mỗi biến thể của đầu vào.

Mục tiêu chính của một khẳng định cho mỗi hướng dẫn kiểm tra là để có một lỗi (lý tưởng) rằng một lỗi dẫn đến một lỗi kiểm tra và ngược lại để bạn biết chính xác những gì đã thất bại. Sau đó, bạn có thể làm việc với một thử nghiệm rất chính xác để gỡ lỗi nguyên nhân gốc và xác minh. Bạn có thể phá vỡ điều này với một khẳng định, và bạn có thể ổn với nhiều khẳng định. Trong kịch bản cụ thể này, tôi sẽ có một bài kiểm tra cho mỗi hậu tố và một vài kết hợp đặt hàng.

Hy vọng rằng rõ ràng tại sao cô lập các bài kiểm tra là một lợi ích: bạn lãng phí ít thời gian hơn để gỡ lỗi khi có sự cố xảy ra. Bây giờ, nếu bạn thực sự chắc chắn rằng bài kiểm tra khó có thể thất bại và chi phí cho việc tìm kiếm qua bài kiểm tra là rất nhỏ, thì có lẽ nên kiểm tra tất cả chúng cùng một lúc để tiết kiệm thời gian thực hiện.

Nhưng lịch sử đã chỉ ra rằng tiết kiệm một ít thời gian viết mã với chi phí đọc / sử dụng mã là không bao giờ có giá trị. Do đó hướng dẫn.


1

Những người theo chủ nghĩa thuần túy sẽ nói rằng các xác nhận cho các giá trị đầu vào khác nhau nên được đặt trong các phương thức thử nghiệm riêng biệt trong lớp thử nghiệm. Một lý do cho điều này là, tùy thuộc vào giao diện người dùng thử nghiệm của bạn, việc phân biệt giữa các lỗi thử nghiệm riêng lẻ thường dễ dàng hơn so với giữa các xác nhận riêng lẻ, điều này có thể khiến bạn xác định nguồn gốc của sự thất bại nhanh hơn.

Khi kiểm tra với JUnit, chúng ta có thể khắc phục điều này bằng cách sử dụng phiên bản của các phương thức khẳng định * với đối số Chuỗi ban đầu để phân biệt một xác nhận này với một xác nhận khác trong cùng một phương thức kiểm tra.

self.assertEqual("just minutes", parse_date('5m'), 5)
self.assertEqual("just hours", parse_date('5h'), 300)
self.assertEqual("just days", ('5d') ,7200)
self.assertEqual("days, hours, minutes", parse_date('1d4h20m'), 1700)
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.