Những gì được hiểu theo đơn vịvvv


9

Theo tôi hiểu trong lý thuyết theo phương pháp "đơn vị", con người có nghĩa là (trong OOP). Nhưng trong các thử nghiệm thực tế xác minh một số phương pháp trong sự cô lập là các thử nghiệm hành vi rất mong manh (xác minh không phải là kết quả mà thực tế là một số phương pháp phụ thuộc đã được gọi). Vì vậy, tôi thấy rất nhiều người theo đơn vị hiểu một nhóm nhỏ các lớp liên quan chặt chẽ. Trong trường hợp này, chỉ có các phụ thuộc bên ngoài bị chế giễu / sơ khai và đối với các phụ thuộc bên trong đơn vị thực hiện thực tế được sử dụng. Trong trường hợp này có nhiều trạng thái, có ý nghĩa (theo đặc điểm kỹ thuật) và không phải là thử nghiệm mong manh. Vì vậy, câu hỏi là bạn cảm thấy thế nào về các phương pháp này và có hợp lệ để gọi thử nghiệm đơn vị tiếp cận thứ hai hay có thể là một loại thử nghiệm tích hợp cấp thấp?

Nếu bạn thấy một số cân nhắc cụ thể về việc áp dụng TDD bằng một trong những cách thử nghiệm này, tôi sẽ biết ơn những suy nghĩ của bạn.

Câu trả lời:


11

Ban đầu TDD xuất phát từ phong trào nhanh nhẹn, trong đó kiểm tra được viết lên phía trước như một cách để đảm bảo những gì bạn đã mã hóa vẫn đúng với các đặc điểm kỹ thuật hiện được xác định rõ trong mã kiểm tra. Nó cũng xuất hiện như một khía cạnh rất quan trọng của tái cấu trúc, khi bạn sửa đổi mã của mình, bạn có thể dựa vào các thử nghiệm để chứng minh rằng bạn đã thay đổi hành vi của mã.

Sau đó, các công cụ mọi người xuất hiện và nghĩ rằng họ biết thông tin về mã của bạn và sau đó có thể tạo ra các cuống thử nghiệm để hỗ trợ bạn viết bài kiểm tra đơn vị của bạn và tôi nghĩ rằng đây là nơi tất cả đã sai.

Các cuống thử nghiệm được tạo ra bởi một máy tính không biết bạn đang làm gì, nó chỉ vô tình tạo ra một sơ khai cho mọi phương thức bởi vì đó là những gì nó được bảo phải làm. Điều này có nghĩa là bạn có một trường hợp thử nghiệm cho từng phương thức bất kể độ phức tạp của phương pháp đó hay liệu nó có phù hợp để thử nghiệm trong sự cô lập hay không.

Điều này đang đến lúc thử nghiệm từ kết thúc sai của phương pháp TDD. Trong TDD, bạn phải tìm ra mã phải làm gì và sau đó tạo mã để đạt được điều này. Điều này là tự hoàn thành ở chỗ bạn kết thúc việc viết các bài kiểm tra chứng minh mã thực hiện những gì mã đó làm, chứ không phải những gì nó phải làm. Kết hợp với việc tạo các cuống thử nghiệm dựa trên phương thức tự động, bạn sẽ lãng phí khá nhiều thời gian để chứng minh từng khía cạnh nhỏ của mã có thể dễ dàng chứng minh là sai khi tất cả các phần nhỏ được ghép lại với nhau.

Khi Fowler mô tả thử nghiệm trong cuốn sách của mình, ông đã đề cập đến việc thử nghiệm từng lớp với phương thức chính của nó. Anh ấy đã cải thiện điều này, nhưng khái niệm vẫn giống nhau - bạn kiểm tra toàn bộ lớp để nó hoạt động một cách tổng thể, tất cả các bài kiểm tra của bạn được kết hợp với nhau để chứng minh sự tương tác của tất cả các phương thức đó để lớp có thể được sử dụng lại với các kỳ vọng đã xác định.

Tôi nghĩ rằng các bộ công cụ kiểm tra đã làm cho chúng tôi không hài lòng, dẫn chúng tôi xuống lối suy nghĩ rằng bộ công cụ là cách duy nhất để làm mọi thứ khi thực sự, bạn cần phải suy nghĩ nhiều hơn để có được kết quả tốt nhất từ ​​mã của mình. Đặt mã kiểm tra một cách mù quáng vào các mẩu kiểm tra cho các mẩu nhỏ chỉ có nghĩa là bạn phải lặp lại công việc của mình trong kiểm tra tích hợp (và nếu bạn sẽ làm điều đó, tại sao không bỏ qua hoàn toàn giai đoạn kiểm tra đơn vị dự phòng). Điều đó cũng có nghĩa là mọi người lãng phí rất nhiều thời gian để cố gắng đạt được phạm vi kiểm tra 100% và rất nhiều thời gian để tạo ra một lượng lớn mã giả và dữ liệu sẽ được sử dụng tốt hơn để làm cho mã dễ dàng hơn để kiểm tra tích hợp (ví dụ: nếu bạn có nhiều như vậy phụ thuộc dữ liệu, kiểm tra đơn vị có thể không phải là lựa chọn tốt nhất)

Cuối cùng, sự mong manh của các bài kiểm tra đơn vị dựa trên phương pháp chỉ cho thấy vấn đề. Tái cấu trúc được thiết kế để được sử dụng với các bài kiểm tra đơn vị, nếu các bài kiểm tra của bạn bị hỏng mọi lúc vì bạn đang tái cấu trúc thì có gì đó đã sai nghiêm trọng với toàn bộ cách tiếp cận. Tái cấu trúc thích tạo và xóa các phương thức, vì vậy rõ ràng phương pháp kiểm tra dựa trên phương pháp mù không phải là mục đích ban đầu.

Tôi không nghi ngờ rằng nhiều phương thức sẽ có các bài kiểm tra được viết cho chúng, tất cả các phương thức công khai của một lớp nên được kiểm tra, nhưng bạn không thể thoát khỏi khái niệm kiểm tra chúng cùng nhau như là một phần của một trường hợp kiểm thử. Ví dụ: nếu tôi có một tập hợp và một phương thức get, tôi có thể viết các bài kiểm tra đưa dữ liệu vào và kiểm tra các thành viên nội bộ được đặt ổn hay tôi có thể sử dụng từng phương thức để đặt một số dữ liệu và sau đó lấy lại để xem liệu nó có được không vẫn như cũ và không bị cắt xén. Đây là kiểm tra lớp, không phải mỗi phương thức trong sự cô lập. Nếu setter dựa vào phương thức riêng của người trợ giúp, thì tốt thôi - bạn không cần phải chế giễu phương thức riêng để đảm bảo setter hoạt động, chứ không phải nếu bạn kiểm tra toàn bộ lớp.

Tôi nghĩ rằng tôn giáo đang đi sâu vào chủ đề này, do đó bạn thấy sự phân ly vào cái mà ngày nay được gọi là phát triển 'hướng theo hành vi' và 'điều khiển thử nghiệm' - khái niệm ban đầu về thử nghiệm đơn vị là dành cho phát triển theo hành vi.


10

Một đơn vị thường được định nghĩa là " phần có thể kiểm tra nhỏ nhất của ứng dụng ". Thường xuyên hơn không, có, điều này có nghĩa là một phương pháp. Và vâng, điều này có nghĩa là bạn không nên kiểm tra kết quả của một phương thức phụ thuộc, nhưng chỉ là phương thức đó được gọi (và sau đó chỉ một lần, nếu có thể, không phải trong mọi thử nghiệm cho phương thức đó).

Bạn gọi đây là mong manh. Tôi nghĩ đó là không chính xác. Các thử nghiệm dễ vỡ là những thử nghiệm phá vỡ dưới sự thay đổi nhỏ nhất đối với mã không liên quan. Đó là, những người dựa vào mã không liên quan đến chức năng đang được thử nghiệm.

Tuy nhiên, điều tôi nghĩ bạn thực sự muốn nói là việc thử nghiệm một phương pháp không có sự phụ thuộc nào của nó là không kỹ lưỡng. Về điểm đó tôi sẽ đồng ý. Bạn cũng cần kiểm tra tích hợp để đảm bảo rằng các đơn vị mã được nối chính xác với nhau để tạo ra một ứng dụng.

Đây chính xác là vấn đề mà sự phát triển dựa trên hành vi và sự phát triển dựa trên thử nghiệm chấp nhận cụ thể , đặt ra để giải quyết. Nhưng điều đó không loại bỏ sự cần thiết phải phát triển thử nghiệm đơn vị / phát triển dựa trên thử nghiệm; nó chỉ bổ sung cho nó


Tôi thực sự muốn nói kiểm tra hành vi là mong manh. Chúng thường trở thành âm tính giả trong quá trình thay đổi codebase. Nó xảy ra ít hơn với các bài kiểm tra trạng thái (nhưng các bài kiểm tra trạng thái rất hiếm khi kiểm tra đơn vị)
SiberianGuy

@Idsa: Tôi hơi lạc lõng với định nghĩa của bạn. Kiểm tra hành vi là kiểm tra tích hợp, kiểm tra một phần hành vi theo quy định. Đọc câu hỏi ban đầu của bạn, có vẻ như khi bạn nói các bài kiểm tra trạng thái, bạn có nghĩa là điều tương tự.
pdr

theo trạng thái Tôi có nghĩa là kiểm tra xác minh trạng thái, kết quả của một số chức năng; bằng hành vi, ý tôi là kiểm tra xác minh không phải kết quả, nhưng thực tế là một số chức năng đã được gọi
SiberianGuy

@Idsa: Trong trường hợp đó, tôi hoàn toàn không đồng ý. Những gì bạn đang gọi kiểm tra nhà nước, tôi gọi tích hợp. Những gì bạn đang gọi hành vi, tôi gọi đơn vị. Kiểm tra tích hợp theo định nghĩa của họ là mong manh hơn. Google "đơn vị kiểm tra tích hợp dễ vỡ" và bạn sẽ thấy rằng tôi không đơn độc.
pdr

có một nhật ký các bài viết về thử nghiệm nhưng chúng trong số chúng chia sẻ ý kiến ​​của bạn?
SiberianGuy

2

Như tên cho thấy bạn đang thử nghiệm một chủ đề nguyên tử trong mỗi thử nghiệm. Một chủ đề như vậy thường là một phương pháp duy nhất. Nhiều thử nghiệm có thể kiểm tra cùng một phương pháp, để bao quát đường dẫn hạnh phúc, các lỗi có thể xảy ra, v.v. Bạn đang kiểm tra hành vi, không phải cơ học bên trong. Vì vậy, kiểm thử đơn vị thực sự là kiểm tra giao diện chung của một lớp, tức là một phương thức cụ thể.

Trong thử nghiệm đơn vị, một phương pháp cần phải được kiểm tra một cách cô lập, nghĩa là bằng cách khai thác / chế nhạo / giả mạo bất kỳ sự phụ thuộc nào. Mặt khác, kiểm tra một đơn vị với các phụ thuộc 'thực' làm cho nó trở thành một thử nghiệm tích hợp. Có một thời gian và địa điểm cho cả hai loại thử nghiệm. Kiểm tra đơn vị đảm bảo một chủ đề duy nhất hoạt động như mong đợi, độc lập. Kiểm tra tích hợp đảm bảo rằng các đối tượng 'thực' hoạt động chính xác với nhau.


1
không hẳn, một đơn vị là bất kỳ đối tượng biệt lập nào, chỉ vì công cụ tự động thích xử lý một phương thức vì điều này không làm cho nó trở nên như vậy, cũng không làm cho nó trở nên tốt nhất. "Cô lập" là chìa khóa ở đây. Ngay cả khi bạn kiểm tra các phương pháp, bạn cũng nên kiểm tra các phương thức riêng tư.
gbjbaanb

1

Quy tắc ngón tay cái của tôi: Đơn vị mã nhỏ nhất vẫn đủ phức tạp để chứa lỗi.

Cho dù đây là một phương thức hay lớp hoặc hệ thống con phụ thuộc vào mã cụ thể, không có quy tắc chung nào có thể được đưa ra.

Ví dụ, nó không cung cấp bất kỳ giá trị nào để kiểm tra các phương thức getter / setter đơn giản hoặc các phương thức trình bao bọc mà chỉ gọi phương thức khác. Ngay cả một lớp có thể quá đơn giản để kiểm tra, nếu lớp chỉ là một trình bao bọc hoặc bộ điều hợp mỏng. Nếu điều duy nhất để kiểm tra là nếu một phương thức trên giả được gọi, thì mã được kiểm tra là mỏng.

Trong các trường hợp khác, một phương thức duy nhất có thể thực hiện một số phép tính phức tạp có giá trị để kiểm tra cách ly.

Trong nhiều trường hợp, các phần phức tạp không phải là các lớp riêng lẻ mà là sự tích hợp giữa các lớp. Vì vậy, bạn kiểm tra hai hoặc nhiều lớp cùng một lúc. Một số người sẽ nói rằng đây không phải là kiểm tra đơn vị mà là kiểm tra tích hợp, nhưng đừng bận tâm đến thuật ngữ: Bạn nên kiểm tra mức độ phức tạp và các kiểm tra này phải là một phần của bộ kiểm tra.

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.