Giá trị của việc viết các bài kiểm tra đơn vị bổ sung khi bao thanh toán lại một hàm lớn hơn thành các hàm nhỏ hơn là gì?


8

Nếu tôi có một chức năng thử nghiệm đơn vị phức tạp :

def do_everything():
    # turn twizzles
    # push buttons
    # move mountain

Và tôi tính lại nó thành một số đơn vị nhỏ hơn:

def do_everything():
    turn_twizzles()
    push_buttons()
    move_mountain()

def turn_twizzles():
    # turn twizzles

def push_buttons():
    # push buttons

def move_mountain():
    # move mountain

Tôi có lãng phí thời gian của mình để viết bài kiểm tra đơn vị bổ sung cho các đơn vị nhỏ hơn không?

Câu trả lời:


15

Tôi giả sử bạn đã có bài kiểm tra đơn vị bao gồm hành vi của do_everything()? Nếu bạn đã phá vỡ turn_twizzles()các phương thức riêng tư, thì bạn đã không thay đổi bất kỳ hành vi bên ngoài nào, do đó bạn không cần thay đổi bất kỳ thử nghiệm nào.

Tuy nhiên, nếu turn_twizzles()được công khai, thì bạn đã giới thiệu một chức năng mới (như được quan sát từ bên ngoài lớp), vì vậy sẽ rất có giá trị khi kiểm tra điều này.


2
Không chắc chắn tại sao câu trả lời này đã bị hạ cấp. Nó là ngắn, đến điểm và 100% tại chỗ trong lời khuyên của nó.
David Arno

Đây là một câu trả lời rất rõ ràng, cảm ơn bạn. Tôi nghĩ rằng vấn đề (tín dụng cho @Samuel khi đề cập đến nó là nắm tay) là vấn đề thời tiết hay không giao diện công cộng đã thay đổi.
Adam Terrey

Downvote vì điều này không đầy đủ. Ngay cả khi các chức năng mới không phải là một phần của API công khai, các bài kiểm tra viết có thể rất hữu ích. Nói một bài kiểm tra cho do_everything () không thành công: lỗi ở đâu? Nếu bạn có các bài kiểm tra cho cả ba chức năng phụ, nó sẽ dễ dàng tìm thấy hơn. Đó là một lợi ích của việc viết các bài kiểm tra và nó nên được đề cập ở đây.
marstato

1
@marstato: Nó thường được coi là một ý tưởng tồi đối với các phương pháp riêng tư, vì nó kết hợp các thử nghiệm với các chi tiết thực hiện.
JacquesB

@JaxquesB Nói chung không phải là một điều xấu. Bạn có thể nói rằng bất cứ điều gì chính xác hơn một bài kiểm tra tích hợp thông thường đều gắn liền với chi tiết thực hiện. Nhưng dù sao bạn cũng viết những bài kiểm tra đó vì chúng giúp bạn theo dõi lỗi chứ không phải vì chúng giúp bạn chứng minh đúng chức năng. Công cụ sửa đổi truy cập luôn chủ quan. Một privatetừ khóa trong ngôn ngữ lập trình chỉ là một trong nhiều cách để hạn chế quyền truy cập vào một đoạn mã.
marstato

12

Nó phụ thuộc. Nói chính xác hơn, nó phụ thuộc vào

  • độ phức tạp của hàm ban đầu (nếu nó rất phức tạp, tự mình kiểm tra từng bộ phận sẽ được đền đáp)
  • sự phức tạp của các chức năng nhỏ hơn (nếu chúng là các bộ phận phức tạp, việc kiểm tra chúng riêng lẻ sẽ dẫn đến các thử nghiệm chi tiết hơn và phát hiện nguyên nhân gốc chính xác hơn trong trường hợp có lỗi)
  • các bài kiểm tra đơn vị hiện có (nếu chúng đã tạo ra phạm vi bảo hiểm đủ cho tất cả các "bộ phận" đó, thì có lẽ ít đáng để viết các bài kiểm tra riêng lẻ)
  • nếu bạn muốn giữ cho các chức năng nhỏ hơn đó "chi tiết triển khai" của các chức năng ban đầu, hoặc không (đối với trước đây, việc kiểm tra đơn vị viết cho các chức năng nhỏ hơn sẽ trở thành phản tác dụng cho mục tiêu này).

Đặc biệt là khi các "hàm nhỏ hơn" đó không tầm thường như trong ví dụ của bạn, nhưng sẽ có một danh sách các tham số đầu vào phức tạp hơn hoặc ít hơn, có thể rất khó để tạo ra các thử nghiệm đơn vị đủ cho chức năng ban đầu của bạn để đảm bảo các chức năng nhỏ hơn được kiểm tra với tất cả các kết hợp đầu vào "thú vị". Đó sẽ là một dấu hiệu rõ ràng để viết các bài kiểm tra đơn vị cụ thể cho các chức năng nhỏ hơn.

Vì vậy, không có câu trả lời rõ ràng "có" hoặc "không" cho câu hỏi này, đó là một sự đánh đổi mà bạn phải quyết định cho mỗi trường hợp.


6

Nếu turn_twizzles, push_buttonsmove_mountainđược công khai và được gọi bởi mã khác, thì tôi nghĩ điều quan trọng là phải cấu trúc lại các thử nghiệm của bạn để kiểm tra các chức năng này một cách riêng lẻ.

Đáng tiếc là sau khi cấu trúc lại của bạn, bạn có một vấn đề: để kiểm tra đơn vị do_everythingbạn cần để có thể chế nhạo turn_twizzles, push_buttonsmove_mountain. Viết bài kiểm tra do_everythingmà không chế nhạo các phụ thuộc sẽ là một bài kiểm tra tích hợp - không nhất thiết là điều xấu tùy thuộc vào kế hoạch kiểm tra của bạn, nhưng sẽ không có nhiều lợi ích vì bạn đã kiểm tra riêng ba chức năng nhỏ hơn. Đây có thể là thời điểm thích hợp để bạn thiết kế lại thành phần này và cộng tác với các đối tượng khác để thực hiện tất cả công việc do_everything.

Nếu turn_twizzles, push_buttonsmove_mountainkhông được gọi ra bên ngoài, chúng nên được đánh dấu là riêng tư và tôi không khuyên bạn nên thử nghiệm chúng riêng biệt do_everything. Điều này là do từ góc nhìn bên ngoài, do_everythingsẽ là đơn vị nhỏ nhất (vì những cái khác không thể truy cập được). Cũng xem câu trả lời này về việc chia nhỏ các phương thức bằng các phương thức riêng tư.


4
Tôi đã downvoted này như, " để kiểm tra đơn vị do_everythingbạn cần để có thể chế nhạo turn_twizzles, push_buttonsmove_mountain... " phụ thuộc vào một định nghĩa vô nghĩa của "đơn vị thử nghiệm".
David Arno

1
@David để công bằng, Samuel thừa nhận rằng trong câu trả lời. Sắp xếp
GnP

4

Không. Các bài kiểm tra đơn vị thêm là chính xác hơn. Nếu move_mountainthất bại, thì một bài kiểm tra sẽ thất bại trong đó nói rất cụ thể những gì đã sai.

Độ chính xác đó cắt giảm thời gian gỡ lỗi, đó là giá trị. Ngoài ra, do thử nghiệm tập trung hơn, nên chạy nhanh hơn thử nghiệm cùng chức năng thông qua chức năng đầy đủ, cung cấp phản hồi nhanh hơn, rất có giá trị.

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.