Có phải các bài kiểm tra để phát triển theo hướng kiểm tra (TDD) luôn là bài kiểm tra đơn vị không?


41

Tôi hiểu sự phát triển dựa trên thử nghiệm cho đến nay bạn chỉ được phép viết mã sản xuất khi bạn có một bài kiểm tra đơn vị (màu đỏ) không thành công. Dựa trên điều này tôi có câu hỏi nếu cách tiếp cận dựa trên thử nghiệm cũng có thể được áp dụng cho các hình thức thử nghiệm khác.


6
Không có gì lạ khi sử dụng nhiều hơn một cấp độ đỏ / xanh / tái cấu trúc khác nhau được lồng vào nhau. Ví dụ: bạn có thể theo dõi màu đỏ / xanh / tái cấu trúc trong khi viết các bài kiểm tra chấp nhận / hành vi, trong đó giai đoạn 'xanh' của bài kiểm tra chấp nhận chứa nhiều lần lặp lại màu đỏ / xanh / tái cấu trúc của các bài kiểm tra đơn vị.
Sean Burton

1
Tiêu đề không phù hợp với nội dung của câu hỏi. Tiêu đề "là các bài kiểm tra luôn là bài kiểm tra đơn vị " (câu trả lời: không, có thể có các loại bài kiểm tra khác ngoài bài kiểm tra đơn vị), nội dung hỏi "bạn có phải viết bài kiểm tra trước không?".
AnoE

@AnoE Câu đầu tiên của nội dung chỉ là một câu giới thiệu. Câu giây không hỏi liệu bài kiểm tra có phải được viết trước không, nhưng nếu phương pháp TDD có thể được sử dụng cho các phương pháp kiểm tra khác với TDD.
dùng1364368

@ user1364368, vui lòng cải cách câu hỏi một chút, ít nhất tôi đã bối rối về ý định của bạn khi đọc lần đầu tiên và câu hỏi được bình chọn hàng đầu, trong khi giải quyết cả hai câu của bạn cũng bắt đầu nổi bật với câu đầu tiên.
AnoE

@AnoE Tôi đã thay đổi đầu câu thứ hai để làm rõ câu hỏi thực sự là gì.
dùng1364368

Câu trả lời:


27

Tất cả TDD yêu cầu của bạn là bạn viết một bài kiểm tra thất bại, sau đó sửa đổi mã của bạn để làm cho nó vượt qua.

Thông thường "kiểm tra đơn vị" là nhỏ và nhanh và kiểm tra một phần mã của bạn một cách riêng lẻ. Bởi vì chúng nhanh, nó làm cho vòng lặp red / green / refactor cũng nhanh. Tuy nhiên, họ chỉ chịu đựng các phần thử nghiệm trong sự cô lập. Vì vậy, bạn cần các bài kiểm tra khác quá (tích hợp, chấp nhận, vv). Vẫn là một thực hành tốt để tuân theo các nguyên tắc tương tự: viết một bài kiểm tra thất bại, sau đó sửa đổi mã để làm cho nó hoạt động. Chỉ cần lưu ý rằng chúng thường chậm hơn, do đó có thể ảnh hưởng đến thời gian chu kỳ đỏ / xanh / tái cấu trúc.


59

Chu trình tái cấu trúc màu xanh lá cây màu đỏ được xây dựng trên một nguyên tắc rất hợp lý:

Chỉ có các bài kiểm tra tin cậy mà bạn đã thấy cả vượt qua và thất bại.

Có mà làm việc với các bài kiểm tra tích hợp tự động là tốt. Cũng kiểm tra thủ công. Heck, nó hoạt động trên thử nghiệm pin xe hơi. Đây là cách bạn kiểm tra bài kiểm tra.

Một số người nghĩ về các bài kiểm tra đơn vị như bao gồm những điều nhỏ nhất có thể được kiểm tra. Một số người nghĩ về bất cứ điều gì nhanh chóng để kiểm tra. TDD không chỉ là chu trình tái cấu trúc màu xanh lục đỏ mà phần đó còn có một bộ thử nghiệm rất cụ thể: Đây không phải là thử nghiệm mà bạn sẽ chạy lý tưởng một lần trước khi gửi bộ sưu tập các thay đổi. Đó là các bài kiểm tra mà bạn sẽ chạy mỗi khi bạn thực hiện bất kỳ thay đổi nào. Đối với tôi, đó là những bài kiểm tra đơn vị của bạn.


1
Đó cũng là một lý do tại sao kiểm tra tiêu cực rất quan trọng khi kiểm tra xảy ra lỗi: bạn muốn đảm bảo rằng mọi thứ khác sẽ hoạt động, do đó, có hai thử nghiệm (một thử nghiệm tạo ra lỗi dự kiến ​​chính xác, bên kia không tạo ra lỗi) lẫn nhau giúp nâng cao niềm tin rằng trong tương lai trạng thái đỏ / xanh này sẽ tiếp tục.
Matthieu M.

12

Tuy nhiên, tôi tự hỏi nếu cách tiếp cận dựa trên thử nghiệm cũng có thể được áp dụng cho các hình thức thử nghiệm khác.

Vâng, và một cách tiếp cận nổi tiếng thực hiện điều này là phát triển theo định hướng Hành vi . Các thử nghiệm được tạo từ thông số kỹ thuật chính thức trong BDD có thể được gọi là "thử nghiệm đơn vị", nhưng chúng thường sẽ không ở mức độ thấp như trong TDD thực, chúng có thể sẽ phù hợp hơn với thuật ngữ "thử nghiệm chấp nhận".


8

Tôi hiểu sự phát triển dựa trên thử nghiệm cho đến nay bạn chỉ được phép viết mã sản xuất khi bạn có một bài kiểm tra đơn vị (màu đỏ) không thành công.

Không. Bạn chỉ được phép viết mã đơn giản nhất có thể để thay đổi thông báo của bài kiểm tra. Nó không nói bất cứ điều gì về loại thử nghiệm.

Trên thực tế, bạn có thể sẽ bắt đầu bằng cách viết một bài kiểm tra chấp nhận thất bại (màu đỏ) cho một tiêu chí chấp nhận, chính xác hơn, bạn viết bài kiểm tra chấp nhận đơn giản nhất có thể thất bại; Sau đó, bạn chạy thử nghiệm, xem nó thất bại và xác minh rằng nó thất bại vì lý do đúng đắn. Sau đó, bạn viết một bài kiểm tra chức năng thất bại cho một lát chức năng của tiêu chí chấp nhận đó, một lần nữa, bạn viết bài kiểm tra chức năng đơn giản nhất có thể thất bại, chạy nó, xem nó thất bại và xác minh rằng nó không đúng lý do. Sau đó, bạn viết một bài kiểm tra đơn vị thất bại, bài kiểm tra đơn vị đơn giản nhất có thể thất bại, chạy nó xem nó thất bại, xác minh rằng nó thất bại vì lý do đúng.

Bây giờ , bạn viết mã sản xuất đơn giản nhất có thể thay đổi thông báo lỗi. Chạy thử nghiệm một lần nữa, xác minh rằng thông báo lỗi đã thay đổi, rằng nó đã thay đổi theo đúng hướng và mã đã thay đổi thông báo cho đúng lý do. (Lý tưởng nhất là thông báo lỗi sẽ biến mất ngay bây giờ và bài kiểm tra sẽ vượt qua, nhưng thường xuyên hơn là không, tốt hơn là thực hiện các bước nhỏ thay đổi thông báo thay vì cố gắng vượt qua bài kiểm tra trong một lần - đó là lý do tại sao các nhà phát triển khung kiểm tra dành quá nhiều nỗ lực cho các thông báo lỗi của họ!)

Khi bạn vượt qua bài kiểm tra đơn vị, bạn sẽ cấu trúc lại mã sản xuất của mình dưới sự bảo vệ của các bài kiểm tra. (Lưu ý rằng tại thời điểm này, thử nghiệm chấp nhận và thử nghiệm chức năng vẫn không thành công, nhưng không sao, vì bạn chỉ tái cấu trúc các đơn vị riêng lẻ được bao phủ bởi các thử nghiệm đơn vị.)

Bây giờ bạn tạo thử nghiệm đơn vị tiếp theo và lặp lại ở trên, cho đến khi thử nghiệm chức năng cũng vượt qua. Dưới sự bảo vệ của kiểm tra chức năng, bây giờ bạn có thể thực hiện tái cấu trúc trên nhiều đơn vị.

Chu kỳ giữa này bây giờ lặp lại cho đến khi thử nghiệm chấp nhận vượt qua, tại thời điểm đó bạn có thể thực hiện tái cấu trúc trên toàn bộ hệ thống.

Bây giờ, bạn chọn tiêu chí chấp nhận tiếp theo và chu trình bên ngoài bắt đầu lại.

Kent Beck, "người phát hiện" TDD (anh ấy không thích thuật ngữ "nhà phát minh", anh ấy nói rằng mọi người đã làm điều này suốt, anh ấy chỉ đặt tên cho nó và viết một cuốn sách về nó) sử dụng một sự tương tự từ nhiếp ảnh và gọi đây là "phóng to và thu nhỏ".

Lưu ý: bạn không phải lúc nào cũng cần ba cấp độ kiểm tra. Có lẽ, đôi khi bạn cần nhiều hơn. Thường xuyên hơn, bạn cần ít hơn. Nếu các phần chức năng của bạn nhỏ và các bài kiểm tra chức năng của bạn nhanh, thì bạn có thể nhận được mà không cần (hoặc với các bài kiểm tra đơn vị ít hơn). Thông thường, bạn chỉ cần kiểm tra chấp nhận và kiểm tra đơn vị. Hoặc, tiêu chí chấp nhận của bạn rất tốt đến nỗi các bài kiểm tra chấp nhận của bạn các bài kiểm tra chức năng.

Kent Beck nói rằng nếu anh ta có một bài kiểm tra chức năng nhanh, nhỏ và tập trung, trước tiên anh ta sẽ viết các bài kiểm tra đơn vị, để cho các bài kiểm tra đơn vị lái mã, sau đó xóa (một số) đơn vị kiểm tra lại bao gồm mã cũng được bao phủ bởi các bài kiểm tra chức năng nhanh. Hãy nhớ rằng: mã kiểm tra cũng là mã cần được duy trì và tái cấu trúc, càng ít có thì càng tốt!

Tuy nhiên, tôi tự hỏi nếu cách tiếp cận dựa trên thử nghiệm cũng có thể được áp dụng cho các hình thức thử nghiệm khác.

Bạn không thực sự áp dụng TDD cho các bài kiểm tra. Bạn áp dụng nó cho toàn bộ quá trình phát triển của bạn. Đó là những gì phần "thúc đẩy" của Test- Driven -Development có nghĩa là: tất cả sự phát triển của bạn được điều khiển bởi các bài kiểm tra. Các thử nghiệm không chỉ lái xe mã bạn viết, họ cũng lái xe mã để viết, mà mã để viết tiếp theo. Họ lái thiết kế của bạn. Họ nói với bạn khi bạn hoàn thành. Họ nói với bạn những gì để làm việc tiếp theo. Họ cho bạn biết về các lỗi thiết kế trong mã của bạn (khi các bài kiểm tra khó viết).

Keith Braithwaite đã tạo ra một bài tập mà anh gọi là TDD As If You Mete It . Nó bao gồm một bộ quy tắc (dựa trên Ba quy tắc TDD của chú Bob Martin , nhưng chặt chẽ hơn nhiều) mà bạn phải tuân thủ nghiêm ngặt và được thiết kế để hướng bạn áp dụng TDD chặt chẽ hơn. Nó hoạt động tốt nhất với lập trình cặp (để cặp của bạn có thể đảm bảo bạn không vi phạm các quy tắc) và một người hướng dẫn.

Các quy tắc là:

  1. Viết chính xác một bài kiểm tra mới, bài kiểm tra nhỏ nhất mà bạn có thể chỉ ra theo hướng của một giải pháp
  2. Thấy nó thất bại; thất bại biên dịch được tính là thất bại
  3. Làm cho bài kiểm tra từ (1) vượt qua bằng cách viết mã thực hiện ít nhất bạn có thể trong phương thức kiểm tra .
  4. Tái cấu trúc để loại bỏ trùng lặp, và nếu không theo yêu cầu để cải thiện thiết kế. Hãy nghiêm ngặt về việc sử dụng các động thái này:
    1. bạn muốn có một phương thức mới, hãy đợi cho đến khi tái cấu trúc thời gian, sau đó, bạn tạo ra các phương thức mới (không thử nghiệm) bằng cách thực hiện một trong những phương thức này và không có cách nào khác:
      • ưa thích: thực hiện Phương thức trích xuất trên mã thực hiện được tạo theo (3) để tạo một phương thức mới trong lớp thử nghiệm, hoặc
      • nếu bạn phải: di chuyển mã triển khai theo (3) sang một phương thức triển khai hiện có
    2. bạn muốn có một lớp mới chờ đợi cho đến khi tái cấu trúc thời gian, sau đó, bạn tạo các lớp không thử nghiệm để cung cấp đích cho Phương thức di chuyển và không vì lý do nào khác
    3. Tạo các lớp triển khai với các phương thức bằng cách thực hiện Phương thức di chuyển và không có cách nào khác

Những quy tắc này có nghĩa là để thực hiện TDD. Chúng không có nghĩa là thực sự làm TDD trong sản xuất (mặc dù không có gì ngăn bạn thử nó). Họ có thể cảm thấy bực bội vì đôi khi dường như bạn sẽ thực hiện hàng ngàn bước nhỏ xíu mà không có tiến bộ thực sự.


2

TDD hoàn toàn không giới hạn ở những gì cộng đồng Kiểm thử phần mềm truyền thống gọi là "kiểm thử đơn vị". Sự hiểu lầm rất phổ biến này là kết quả của sự quá tải đáng tiếc của Kent Beck về thuật ngữ "đơn vị" khi mô tả thực hành TDD của anh ấy. Ý anh là "kiểm tra đơn vị" là một bài kiểm tra chạy cách ly. Nó không phụ thuộc vào các xét nghiệm khác. Mỗi bài kiểm tra phải thiết lập trạng thái cần thiết và thực hiện bất kỳ việc dọn dẹp nào khi hoàn thành. Theo nghĩa này, một bài kiểm tra đơn vị theo nghĩa TDD là một đơn vị. Nó là khép kín. Nó có thể tự chạy hoặc có thể chạy cùng với bất kỳ bài kiểm tra đơn vị nào khác theo bất kỳ thứ tự nào.

Tham khảo : "Thử nghiệm phát triển theo ví dụ", bởi Kent Beck

Kent Beck mô tả những gì anh ta có nghĩa là bằng cách kiểm tra đơn vị của Cameron trong Chương 32 - Làm chủ TDD


1

Tôi đã không đọc sách về nó, tôi cũng không hoàn toàn tuân theo các thực hành TDD "tiêu chuẩn" mọi lúc, nhưng trong tâm trí tôi, điểm chính của triết lý TDD, mà tôi hoàn toàn đồng ý, là bạn phải xác định thành công trước tiên . Điều này rất quan trọng ở mọi cấp độ thiết kế, từ "Mục tiêu của dự án này là gì?" thành "Đầu vào và đầu ra của phương pháp nhỏ này phải là gì?"

Có rất nhiều cách để thực hiện định nghĩa thành công này. Một phương pháp hữu ích, đặc biệt đối với các phương thức cấp thấp có khả năng có nhiều trường hợp cạnh, là viết các bài kiểm tra trong mã. Đối với một số mức độ trừu tượng, có thể hữu ích chỉ cần viết ra một ghi chú nhanh về mục tiêu của mô-đun hoặc bất cứ điều gì, hoặc thậm chí chỉ cần kiểm tra chính mình (hoặc hỏi đồng nghiệp) để đảm bảo mọi thứ có ý nghĩa và trong một nơi logic. Đôi khi thật hữu ích khi mô tả một thử nghiệm tích hợp trong mã (và tất nhiên giúp một người tự động hóa nó), và đôi khi thật hữu ích khi xác định một kế hoạch kiểm tra nhanh hợp lý mà bạn có thể sử dụng để đảm bảo tất cả các hệ thống hoạt động cùng nhau theo cách bạn đang mong đợi

Nhưng bất kể các kỹ thuật hoặc công cụ cụ thể mà bạn đang sử dụng, trong suy nghĩ của tôi, điều quan trọng cần rút ra khỏi triết lý TDD là việc xác định thành công xảy ra trước tiên. Mặt khác, bạn đang ném phi tiêu và sau đó vẽ hình mắt bò xung quanh bất cứ nơi nào nó xảy ra.


1

Trong buổi nói chuyện Phát triển dựa trên thử nghiệm: Đây không phải là ý nghĩa của chúng tôi, Steve Freeman cho thấy slide sau đây của bức tranh lớn TDD (xem hình ảnh dưới đây trả lời). Điều này bao gồm một bước "Viết một bài kiểm tra đầu cuối thất bại" được theo sau bởi "Viết một bài kiểm tra đơn vị thất bại". (Bấm để phóng to, nó ở trên cùng bên phải)

Vì vậy, không có trong TDD, các bài kiểm tra không phải lúc nào cũng là bài kiểm tra đơn vị.

Và vâng, bạn có thể (và có thể nên) bắt đầu với bài kiểm tra đầu cuối cấp cao hơn thất bại trước khi bạn viết bài kiểm tra đơn vị đầu tiên. Bài kiểm tra này mô tả hành vi bạn muốn đạt được. Điều này tạo ra phạm vi bảo hiểm trên nhiều cấp độ của kim tự tháp thử nghiệm . Adrian Sutton giải thích kinh nghiệm của LMAX cho thấy các bài kiểm tra đầu cuối có thể đóng một vai trò lớn và có giá trị .

nhập mô tả hình ảnh ở đây


-1

Không, nó không thể được áp dụng cho các loại thử nghiệm khác, vì một lý do thực tế đơn giản: các loại thử nghiệm khác đang mất quá nhiều thời gian để thực hiện.

Chu trình TDD điển hình là: viết lỗi kiểm tra, thực hiện, mã tái cấu trúc. Các bước ở giữa là xây dựng và thực hiện các bài kiểm tra, và những điều này cần phải nhanh như chớp. Nếu họ không, thì mọi người sẽ bắt đầu bỏ qua các bước, và sau đó bạn không làm TDD nữa.


1
Điều này không chính xác: tùy thuộc vào chương trình và bài kiểm tra (và ngôn ngữ), các bài kiểm tra tích hợp đầu cuối có thể dễ dàng chạy trong vòng chưa đầy 3 giây. Hoàn toàn có thể chạy một bộ thử nghiệm hoàn chỉnh từ đầu đến cuối trong thời gian ngắn, thậm chí, nếu nó được thiết kế tốt. Vì vậy, "không thể" là khá mạnh.
Jonathan Cast

@jcast Mình chưa bao giờ thấy cái gì khác nhanh đến thế. Các thử nghiệm chức năng của tôi trong dự án trước đây của tôi mất 30 giây và nhanh chóng. Tích hợp thậm chí lâu hơn. Trong trường hợp của tôi, không có gì khác có ý nghĩa. Ngoài ra, các bài kiểm tra đơn vị là cách nhanh nhất trong tất cả các loại bài kiểm tra - do đó, việc sử dụng chúng là hợp lý.
BЈовић
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.