2010-07-18 33 views
11

Tôi vừa mua The Art of Unit Testing từ Amazon. Tôi khá nghiêm túc về việc hiểu TDD, vì vậy hãy yên tâm rằng đây là một câu hỏi thực sự.Cố gắng tự tin vào những lợi ích của TDD

Nhưng tôi cảm thấy mình liên tục tìm kiếm sự biện minh để từ bỏ nó.

Tôi sẽ đóng vai người bảo vệ ma quỷ ở đây và cố gắng hạ thấp lợi ích của TDD với hy vọng ai đó có thể chứng minh tôi sai và giúp tôi tự tin hơn về đức tính của mình. Tôi nghĩ rằng tôi đang thiếu một cái gì đó, nhưng tôi không thể tìm ra những gì.

1. TDD để giảm lỗi

này often-cited blog post nói rằng các xét nghiệm đơn vị là các công cụ thiết kế và không cho lỗi đánh bắt:

Theo kinh nghiệm của tôi, kiểm tra đơn vị không phải là một cách hiệu quả để tìm lỗi hoặc phát hiện hồi quy.

...

TDD là một cách mạnh mẽ của thiết kế thành phần phần mềm (“đơn vị”) tương tác để hành vi của họ được xác định thông qua kiểm tra đơn vị. Đó là tất cả!

Làm cho tinh thần. Các trường hợp cạnh vẫn luôn ở đó, và bạn sẽ chỉ tìm thấy các lỗi bề ngoài - đó là những lỗi mà bạn sẽ tìm thấy ngay sau khi bạn chạy ứng dụng của mình. Bạn vẫn cần phải làm thử nghiệm tích hợp thích hợp sau khi bạn đã hoàn thành việc xây dựng một phần mềm tốt cho phần mềm của mình.

Đủ công bằng, giảm lỗi không phải là điều duy nhất TDD có nghĩa vụ trợ giúp.

2. TDD như một mô hình thiết kế

Đây có lẽ là một lớn. TDD là một mô hình thiết kế giúp bạn (hoặc buộc bạn) làm cho mã của bạn nhiều hơn composable.

Nhưng khả năng tương thích là chất lượng có thể thực hiện được nhiều lần; ví dụ, kiểu lập trình chức năng, làm cho mã hoàn toàn tương thích. Tất nhiên, rất khó để viết một ứng dụng quy mô lớn hoàn toàn theo phong cách chức năng, nhưng có một số mẫu thỏa hiệp mà bạn có thể làm theo để duy trì khả năng tổng hợp.

Nếu bạn bắt đầu với một thiết kế chức năng cao mô-đun, và sau đó cẩn thận thêm trạng thái và IO vào mã của bạn khi cần thiết, bạn sẽ kết thúc với các mẫu tương tự mà TDD khuyến khích. Ví dụ, để thực thi logic nghiệp vụ trên cơ sở dữ liệu, mã IO có thể bị cô lập trong một hàm thực hiện các tác vụ "monadic" truy cập cơ sở dữ liệu và chuyển nó làm đối số cho hàm chịu trách nhiệm về logic nghiệp vụ . Đó sẽ là cách chức năng để làm điều đó.

Tất nhiên, đây là một chút khó khăn, vì vậy thay vào đó, chúng ta có thể ném một tập hợp con của mã IO cơ sở dữ liệu vào một lớp và cung cấp cho đối tượng chứa logic nghiệp vụ liên quan. Đó là điều tương tự, một sự thích nghi của cách thức hoạt động của việc làm, và nó được gọi là mô hình kho lưu trữ.

Tôi biết điều này có thể sẽ khiến tôi trở nên khá tệ, nhưng thường thì tôi không thể không cảm thấy TDD chỉ bù đắp cho một số thói quen xấu mà OOP có thể khuyến khích - những thứ có thể tránh với một chút cảm hứng từ phong cách chức năng.

3. TDD như tài liệu

TDD được cho là đóng vai trò như tài liệu hướng dẫn, nhưng nó chỉ đóng vai trò như tài liệu hướng dẫn cho đồng nghiệp; người tiêu dùng vẫn yêu cầu tài liệu văn bản. Tất nhiên, một phương pháp TDD có thể phục vụ như là cơ sở cho mã mẫu, nhưng xét nghiệm thường chứa một số mức độ mocks mà không nên có trong mã mẫu, và thường khá giả tạo để chúng có thể được đánh giá cho sự bình đẳng so với kết quả mong đợi.

Một bài kiểm tra đơn vị tốt sẽ mô tả trong chữ ký phương pháp của nó hành vi chính xác đang được xác minh, và kiểm tra sẽ xác minh không nhiều hơn và không ít hơn hành vi đó.

Vì vậy, tôi muốn nói, thời gian của bạn có thể tốt hơn là chi tiêu cho việc đánh bóng tài liệu của bạn. Heck, tại sao không chỉ làm tài liệu đầu tiên kỹ lưỡng, và gọi nó là tài liệu hướng thiết kế?

4. TDD để thử nghiệm hồi quy

Nó đề cập trong đó bài trên TDD đó không phải là quá hữu ích cho việc phát hiện hồi quy. Đó là, tất nhiên, bởi vì các trường hợp cạnh không rõ ràng là những người luôn luôn lộn xộn khi bạn thay đổi một số mã.

Điều gì cũng có thể lưu ý về chủ đề đó là cơ hội tốt là hầu hết mã của bạn sẽ vẫn giữ nguyên trong một thời gian khá dài. Vì vậy, nó sẽ không có ý nghĩa hơn để viết bài kiểm tra đơn vị trên cơ sở khi cần thiết, bất cứ khi nào mã được thay đổi, giữ mã cũ và so sánh kết quả của nó với chức năng mới?

+1

"những người có thể tránh được với một chút cảm hứng từ phong cách chức năng." Hầu như đồng ý ... TDD khuyến khích một phong cách mã hóa gần hơn với mô hình diễn viên, đó là loại nghịch đảo của phong cách chức năng (nó là một mô hình đẩy so với kéo mã hóa chức năng) – kyoryu

+0

Thú vị ... Tôi nên nhìn vào mô hình diễn viên . Điều đó có thể giữ câu trả lời tôi đang tìm kiếm! –

+0

Cần lưu ý rằng Alan Kay đã được trích dẫn khi nói rằng anh ta hối hận khi sử dụng thuật ngữ "hướng đối tượng" và mong muốn anh ta sẽ sử dụng "định hướng thông điệp". TDD đẩy bạn hướng tới một phong cách hướng thông điệp (đó là trái tim của mô hình diễn viên, hoặc giao tiếp các quy trình tuần tự, hoặc ...) – kyoryu

Trả lời

3

Tôi tin rằng lợi ích của TDD là bạn thực sự viết các bài kiểm tra vì chúng thú vị hơn khi chúng là mục tiêu bạn phải đạt được, (tạo mã để vượt qua bài kiểm tra), chứ không phải là việc vặt mà bạn phải làm sau đó .

Ngoài ra, nó đặt bạn vào tâm trí của người dùng. Bạn phải suy nghĩ "vì vậy người dùng cần phương pháp của tôi để làm gì" hoặc bất cứ điều gì, thay vì, "Tôi hy vọng phương pháp của tôi đã đạt được những gì nó được cho là phải làm". Bằng cách này, nó cũng có thể giúp giảm lỗi.

+0

Không chắc tôi tin rằng TDD không quá mức cho mục đích này, nhưng điều này dường như là động lực hợp lý nhất cho TDD. –

+0

Tôi cũng có thể có một danh sách việc cần làm cho ... –

+0

Vâng, đó là điều, đó là lý do tại sao sau gần một năm tôi vẫn chưa được thuyết phục. –

0

TDD cũng cung cấp cho bạn mã được kiểm tra kỹ lưỡng bằng các thử nghiệm đơn vị tự động. Điều này đơn giản là vì không có mã nào được viết cho đến khi nó cần thiết để thực hiện một phép thử kiểm tra đơn vị bị lỗi.

1

Tôi chỉ muốn nhấn mạnh:
Các xét nghiệm TDD không Unit Tests

"Mục đích của một đơn vị kiểm tra là kiểm tra một đơn vị mã trong sự cô lập."
"Thử nghiệm TDD, không giống như kiểm tra đơn vị, có thể thử nghiệm nhiều hơn một đơn vị mã tại một thời điểm." Các xét nghiệm TDD có nhiều bài kiểm tra tương tác ....

từ bài viết trên blog rất tốt Stephen Walter TDD Tests are not Unit Tests

5

Về mặt thiết kế, một benifit chính của TDD bạn không nhìn thấy là nó thúc đẩy thiết kế là vừa đủ.Bạn biết những gì họ nói rằng các kỹ sư nhìn thấy kính như là lớn gấp đôi như nó phải được. Overdesign trong phần mềm có thể là một vấn đề lớn. Tôi thấy rằng 90 +% thời gian TDD đã buộc phải sử dụng đúng mức độ trừu tượng để hỗ trợ phần mở rộng sau này của mã. TDD không phải là ma thuật, nó cũng khiến người lập trình phía sau nó làm điều đó, nhưng nó là một phần quan trọng của bộ công cụ.

Tôi nghĩ rằng có quá nhiều TDD trong sự cô lập trong danh sách của bạn. Điều gì về tái cấu trúc? Tôi nghĩ một trong những lợi ích chính của bài kiểm tra là nó khóa hành vi, để khi bạn cấu trúc lại, bạn có thể tự tin rằng bạn không thay đổi gì, điều này có thể khiến bạn tự tin về việc tái cấu trúc. Và không có gì giống như một thiết kế được sinh ra từ kinh nghiệm hơn là một tấm bảng (mặc dù thiết kế bảng trắng cao cấp vẫn còn rất quan trọng). Ngoài ra, bạn viết: "Vì vậy, nó sẽ không có ý nghĩa hơn để viết bài kiểm tra đơn vị trên cơ sở khi cần thiết, bất cứ khi nào mã được thay đổi, giữ mã cũ và so sánh kết quả của nó với chức năng mới?" Mã được viết mà không cần kiểm thử đơn vị trong tâm trí thường là không thể thực hiện được, đặc biệt nếu nó tương tác với các dịch vụ bên ngoài như cơ sở dữ liệu, trình quản lý giao dịch, bộ công cụ GUI hoặc dịch vụ web. Thêm chúng sau này sẽ không xảy ra.

Tôi nghĩ Bob Martin đã nói tốt nhất, TDD là lập trình mục Double Entry là gì. Nó ngăn cản một lớp sai lầm nhất định. Nó không ngăn chặn tất cả các vấn đề, nhưng chắc chắn rằng nếu chương trình của bạn dự định thêm hai cộng hai, nó sẽ không trừ chúng đi. Hành vi cơ bản là quan trọng, và khi nó đi sai, bạn có thể dành rất nhiều thời gian để biết trình gỡ rối của bạn.

+0

Hmm ... buộc bạn viết "vừa đủ" mã thực sự là một hiệu ứng của composability buộc quá. Hiểu những thứ như minh bạch tham chiếu và tác dụng phụ sẽ buộc mã của bạn phải làm "vừa đủ". Khúc xạ là những gì tôi đề cập đến ở điểm thứ hai của tôi, rằng nó làm cho mã có thể tổng hợp hơn. Composable phần mềm là theo định nghĩa dễ dàng để refractor. Trong hầu hết các trường hợp, với một số quy tắc nhất định, tôi có thể lấy được các mẫu OOP từ kiểu hàm mang lại mã mô-đun có xu hướng trông và cảm nhận rất nhiều như mã TDD. –

+0

@Rei, nếu lập luận của bạn là về mặt lý thuyết có thể nhận được TDD như mã mà không có TDD, không ai tranh luận với bạn (ngay cả những người ủng hộ lõi cứng của TDD). Tuy nhiên, điều đó không làm cho nó có khả năng hoặc dễ dàng. – Yishai

+2

Về việc tái cấu trúc, việc bạn tạo phần mềm của mình không thành vấn đề như thế nào, nếu bạn muốn cấu trúc lại cấu trúc bên trong mã của mình, bạn sẽ sợ làm như vậy mà không có mạng an toàn. Trừ khi bạn bất thường tốt hay bất thường ngu xuẩn. – Yishai

2

TDD không phải là phương pháp luận, nó là một suy nghĩ.

TDD để giảm lỗi: Khi cơ sở mã của bạn bắt đầu phát triển, điều quan trọng là bạn chạy tất cả các kiểm tra trên mỗi lần kiểm tra để kiểm soát nguồn. Lợi ích của việc này trở nên rõ ràng khi bạn có một thành viên mới trong nhóm.

TDD làm mẫu thiết kế: Kiểm tra là người dùng đầu tiên của mã. Ban đầu, rất khó để lái xe thiết kế của bạn bằng cách sử dụng các bài kiểm tra. Nhưng, một khi bạn cảm thấy thoải mái với nó, bạn sẽ nhận ra rằng mã thử nghiệm thực sự giúp bạn quyết định thiết kế của bạn. Điều này đến một cách tự nhiên với một số kinh nghiệm TDD. Ví dụ, với TDD bạn muốn bọc quyền truy cập vào dịch vụ của bạn trong một giao diện. Điều này cho phép bạn giả lập. Nhưng, điều quan trọng nhất ở đây là nó là cách chính xác để thiết kế.

TDD làm tài liệu Tài liệu dành cho tài liệu mã được sử dụng bởi các nhà phát triển mã của bạn. Các nhà phát triển tìm thấy nó dễ dàng để đọc các bài kiểm tra đơn vị viết tốt, chứ không phải là các trang và các trang tài liệu.

1

Trong Javascript hoặc bất kỳ ngôn ngữ nào phải chạy trong nhiều môi trường kỳ quặc như trình duyệt, kiểm tra đơn vị là cách tuyệt vời để nói nơi Internet Effing Explorer đã sửa đổi những gì cần sửa.

Ít nhất nó tốt hơn búa F5 và sử dụng console.log() hoặc thậm chí là cảnh báo.

Nhưng sau đó một lần nữa, tôi nghĩ rằng điều này nên được sử dụng chủ yếu cho phần mềm trung gian hoặc RIA phức tạp - vì hầu như không thể giao tiếp người dùng TDD với logic kinh doanh nhỏ.

Nếu bạn viết jQuery tiếp theo, kiểm tra đơn vị sẽ là bạn của bạn! :)

Oh và đừng quên những công cụ tuyệt vời cho js như JSTestDriver!

+0

Đúng, và đó là một trường hợp cực kỳ nghiêm trọng khi các bài kiểm tra đơn vị sẽ hữu ích: khi bản thân nền tảng thay đổi và bạn cần đảm bảo rằng mã của bạn hoạt động nhất quán trong tất cả chúng. Trong trường hợp đó bạn thực sự không có lựa chọn nào khác ngoài việc kiểm tra mọi thứ với sự tỉ mỉ đau đớn. Nói chung tôi hiểu các ưu đãi cho các bài kiểm tra đơn vị nhiều hơn tôi làm cho TDD. TDD vẫn thực sự gây ấn tượng với tôi. –

Các vấn đề liên quan