Mỗi bài kiểm tra đơn vị có thể được chạy độc lập với các bài kiểm tra khác không?


24

Giả sử bạn có các bài kiểm tra cho hai phương thức của một lớp. Phương thức đầu tiên thu thập dữ liệu từ một tầng khác và đưa nó vào một loại lưu trữ độc lập với thời gian chạy (như bảng SQL), vì vậy tất cả dữ liệu được xử lý bởi thử nghiệm này được mã hóa cứng vào thử nghiệm. Phương thức thứ hai chịu trách nhiệm lấy dữ liệu từ nơi phương thức đầu tiên rời khỏi nó và biến đổi nó theo một cách nào đó (tính toán, di chuyển một số phần nhất định ở nơi khác, v.v.).

Bây giờ phương thức thứ hai này có thể có các đầu vào được mã hóa cứng như đầu vào đầu tiên, hoặc có thể giả định rằng hai thử nghiệm sẽ được chạy tuần tự và nó có thể chọn nơi thử nghiệm đầu tiên dừng lại, lấy dữ liệu thực sự được lưu trữ bởi thử nghiệm đầu tiên.

Nếu bạn đã chọn tùy chọn thứ hai, bạn thực sự sẽ biết rằng hai phương pháp này kết hợp tốt với nhau, tuy nhiên, nếu thử nghiệm đầu tiên thất bại, tất cả các thử nghiệm sau đó sẽ thất bại, lấy đi lợi ích thử nghiệm giúp cách ly lỗi nhanh hơn.

Nếu bạn đã chọn tùy chọn đầu tiên, mỗi phương thức sẽ được cách ly và kiểm tra độc lập, nhưng bạn sẽ không bao giờ thực sự biết rằng chúng có thể thực sự hoạt động đúng với nhau.

Đó là lựa chọn tốt hơn ở đây? Có một số cách thay thế như có một thử nghiệm duy nhất cho mỗi phương thức bị cô lập với mã hóa cứng, và sau đó các thử nghiệm lớn hơn chứa cả hai phương thức trong một?


2
Tôi thực sự muốn tôi có thể dễ dàng ngẫu nhiên hóa thứ tự các bài kiểm tra đơn vị mỗi khi họ chạy. Ngay bây giờ họ chạy trong một số chưa biết, mặc dù thứ tự tương đối cố định.
Công việc

Câu trả lời:


11

Nếu bạn đã chọn tùy chọn đầu tiên, mỗi phương thức sẽ được cách ly và kiểm tra độc lập, nhưng bạn sẽ không bao giờ thực sự biết rằng chúng có thể thực sự hoạt động đúng với nhau.

Nếu phương pháp của bạn thực sự độc lập thì điều này không thành vấn đề. Phương pháp thứ hai của bạn nên:

a) Hoạt động chính xác khi được trình bày với dữ liệu hợp lệ.

b) Thất bại hợp lý và nhất quán khi được trình bày với dữ liệu không hợp lệ.

Tương tự phương pháp đầu tiên của bạn nên làm như vậy. Vì vậy, miễn là bạn xử lý các trường hợp lỗi, chúng sẽ hoạt động đúng.

Nếu bạn muốn kiểm tra rằng các phương thức hoạt động chính xác với nhau thì đó là kiểm thử tích hợp, không phải kiểm thử đơn vị.


27

Nếu các bài kiểm tra không thể chạy độc lập thì chúng không phải là bài kiểm tra đơn vị.

Một bài kiểm tra đơn vị không nên dựa vào bất kỳ trạng thái bên ngoài nào, chẳng hạn như nội dung của bảng cơ sở dữ liệu. Nó nên hoàn toàn kiểm tra một đơn vị mã trong sự cô lập.

Các thử nghiệm thay đổi hoặc yêu cầu một trạng thái nhất định là hợp lệ, chẳng hạn, chúng có thể tạo thành một phần của thử nghiệm tích hợp, và trong những trường hợp như vậy, điều quan trọng là phải đảm bảo rằng thiết lập phù hợp được thực hiện, nhưng đây không phải là thử nghiệm đơn vị. Trong trường hợp này tôi vẫn không khuyên rằng một bài kiểm tra yêu cầu một bài kiểm tra khác phải được chạy. Nếu bạn ở trong trường hợp này, có lẽ bạn nên đưa ra mã được yêu cầu vào một phương thức thiết lập riêng biệt. Bạn cũng có thể có một thử nghiệm mà sau đó chỉ cần gọi mã thiết lập và xác minh không có ngoại lệ nào được đưa ra, ví dụ, và sau đó một thử nghiệm khác sử dụng một cách chủ động dữ liệu được thiết lập trong phương thức thiết lập.


@Steve, vì vậy trong ví dụ này, bạn có thể nói: một thử nghiệm cho phương pháp 1, một thử nghiệm cho phương pháp 2 và một thử nghiệm chạy 1 và 2 trong cùng một thử nghiệm không?
Morgan Herlocker

2
Vâng. hai cái đầu tiên sẽ là các bài kiểm tra đơn vị, âm thứ ba giống như một bài kiểm tra tích hợp.
Steve

nếu bạn có mô-đun khách hàng và mô-đun đặt hàng và đơn đặt hàng không thể được tạo mà không liên quan đến khách hàng. Làm thế nào bạn sẽ kiểm tra nó độc lập với mô-đun khách hàng: tạo hồ sơ khách hàng trong cơ sở dữ liệu với sql (chèn vào khách hàng) hoặc sử dụng Customer.createCustomer (). Và IMHO sử dụng cái thứ hai thì tốt hơn, vì bạn không cần phải đưa ra bất kỳ logic nào trong thử nghiệm, nhưng nó chỉ hoạt động nếu thử nghiệm của bạn về việc tạo ra khách hàng vượt qua.
Dainius

@Dainius. Trong kịch bản thử nghiệm đơn vị, bạn thường sử dụng các đối tượng giả, vì vậy bạn sẽ chuyển một khách hàng giả cho mô-đun đặt hàng của mình. Bạn đúng ở chỗ bạn sẽ không muốn sử dụng sql trong trường hợp này.
Steve

Dường như trong bất kỳ kịch bản nào mà phương thức B phụ thuộc vào phương pháp A, hầu như sẽ luôn có một phương thức C gọi A rồi gọi B. Vì đây là trường hợp, bạn có thể kiểm tra A, B và C một cách độc lập.
Morgan Herlocker

9

Tôi chắc chắn rằng có vẻ ổn ngay bây giờ khi có bài kiểm tra đơn vị B phụ thuộc vào trạng thái còn lại của bài kiểm tra đơn vị B. Nhưng hãy xem xét một năm kể từ bây giờ khi bạn có một nghìn bài kiểm tra đơn vị. Bạn có thực sự muốn đợi mười phút để toàn bộ bộ thử nghiệm của bạn hoàn thành mỗi khi bạn cần thực hiện thay đổi không?

Tất nhiên nó phụ thuộc vào phong cách phát triển của bạn, nhưng nếu bạn muốn có bất kỳ hy vọng nào về phát triển dựa trên thử nghiệm đàng hoàng, trong đó bạn có thể chạy thử nghiệm riêng lẻ nhiều lần khi phát triển một tính năng, tôi khuyên bạn nên cho mỗi thử nghiệm khả năng độc lập.


1
+1 Raskolnikov, tôi đã không cân nhắc thực tế rằng đây sẽ là khoảng thời gian rất lớn sau này khi tôi đã "chạy tất cả các bài kiểm tra" sau này trên đường xuống.
Morgan Herlocker

3

Âm thanh như bạn đang nói về thiết lập thử nghiệm, có thể được thực hiện theo nhiều cách. Bạn muốn có một bản sao sạch của dữ liệu thử nghiệm (được gọi là vật cố định) cho mỗi thử nghiệm, vì vậy mỗi loại không nên phụ thuộc vào nhau.

Có một số khung cho phép loại thử nghiệm này và các công cụ như DBUnit cho phép bạn xây dựng và phá bỏ cấu trúc dữ liệu một cách nhanh chóng khi bắt đầu và kết thúc các thử nghiệm và bộ thử nghiệm.

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.