Có nên có các bài kiểm tra đơn vị cho các biểu thức chính quy phức tạp?


34

Tôi có nên viết bài kiểm tra đơn vị cho các biểu thức chính quy phức tạp trong ứng dụng của mình không?

  • Một mặt: chúng rất dễ kiểm tra vì định dạng đầu vào và đầu ra thường đơn giản và được xác định rõ ràng và chúng thường có thể trở nên phức tạp nên các thử nghiệm về chúng đặc biệt có giá trị.
  • Mặt khác: bản thân chúng hiếm khi là một phần của giao diện của một số đơn vị. Có thể tốt hơn nếu chỉ kiểm tra giao diện và thực hiện điều đó theo cách ngầm kiểm tra các biểu thức chính quy.

CHỈNH SỬA:

Tôi đồng ý với Doc Brown, người trong nhận xét của ông lưu ý rằng đây là trường hợp đặc biệt về kiểm tra đơn vị các thành phần bên trong .

Nhưng như regex thành phần nội bộ có một vài đặc điểm đặc biệt:

  1. Một regex dòng đơn có thể thực sự phức tạp mà không thực sự là một mô-đun riêng biệt.
  2. Regexes ánh xạ đầu vào thành đầu ra mà không có bất kỳ tác dụng phụ nào và do đó thực sự dễ dàng để kiểm tra riêng.

12
"bản thân chúng hiếm khi là một phần của giao diện của một số đơn vị." - nếu các lớp của bạn có mã thú vị được chôn sâu dưới giao diện, hãy chia nhỏ các lớp của bạn. Đây là một ví dụ về cách suy nghĩ về tess có thể cải thiện thiết kế.
Nathan Cooper

3
Câu hỏi tương tự theo cách tổng quát hơn: đơn vị nội bộ nào nên được kiểm tra đơn vị? Xem lập trình
Doc Brown

Sắp xếp liên quan, xem Regex101. Họ có một phần để viết bài kiểm tra đơn vị cho regex của bạn. Ví dụ: regex101.com/r/tR3mJ2/2
David nói Phục hồi lại

3
Disclaimer - nhận xét đây là thiển ý của tôi: 1 trước hết tôi tin rằng regexps phức tạp là ác tinh khiết - also see blog.codinghorror.com/... 2 giá trị thực của kiểm tra biểu thức như vậy đi kèm khi bạn kiểm tra chúng trên một cơ sở dữ liệu lớn của thực dữ liệu blog.codinghorror.com/testing-with-the-force 3 Tôi có một cảm giác kỳ lạ rằng các bài kiểm tra này không phải là bài kiểm tra đơn vị chính xác
Boris Treukhov

Câu trả lời:


101

Kiểm tra giáo điều sang một bên, câu hỏi thực sự là liệu nó có cung cấp giá trị cho đơn vị kiểm tra các biểu thức chính quy phức tạp hay không. Có vẻ như khá rõ ràng rằng nó cung cấp giá trị (bất kể regex có phải là một phần của giao diện công cộng hay không) nếu regex đủ phức tạp, vì nó cho phép bạn tìm và tái tạo lỗi và ngăn chặn hồi quy.


25
+1, mặc dù nếu một biểu thức chính quy là đủ phức tạp rằng đây là một vấn đề, sau đó nó có thể làm cho tinh thần để di chuyển nó thành một "wrapper" đơn vị với các phương pháp thích hợp ( isValid, parse, tryParse, hoặc có điều gì, tùy thuộc chính xác như nó đang được sử dụng), vì vậy rằng mã máy khách không cần phải biết rằng nó hiện được triển khai bằng regex. Đơn vị bao bọc sau đó sẽ có các thử nghiệm chi tiết, một lần nữa - sẽ không cần biết triển khai hiện tại. Các thử nghiệm này, tất nhiên, trên thực tế là thử nghiệm regex, nhưng theo một cách thức không thể thực hiện được.
ruakh

1
Một reg ex là một chương trình, mặc dù trong một ngôn ngữ chuyên ngành và rất ngắn gọn. Như vậy, kiểm thử là thích hợp cho các biểu thức không cần thiết ... Và chắc chắn mã đang gọi biểu thức nên được kiểm tra, có thể ngầm kiểm tra dự trữ.
keshlam

6
@ruakh Nói tốt. Lợi ích của lớp trình bao bọc cho biểu thức chính là bạn có thể thay thế nó gọn gàng bằng mã thông thường nếu điều đó trở nên cần thiết. Mã với đầu vào / đầu ra phức tạp phải luôn có kiểm thử đơn vị, bởi vì rất khó để gỡ lỗi mà không có. Nếu bạn cần tham khảo tài liệu để hiểu các hiệu ứng của mã, nó cần có các bài kiểm tra đơn vị. Nếu đó chỉ là một ánh xạ 1: 1 nhanh chóng như chuyển đổi loại, thì không có vấn đề gì. Regexes vượt qua điểm yêu cầu tài liệu rất nhanh.
Aaron3468

4
@Lii: Regexes không xứng đáng được đối xử đặc biệt. Regex là đơn vị trong trường hợp này, vì vậy chúng tôi kiểm tra đơn vị nó.
JacquesB

1
@ruakh Mình định viết câu trả lời cho hiệu ứng đó. Tôi đồng ý rằng sử dụng regex là một chi tiết thực hiện. Điều quan trọng là mọi thứ xác nhận khi chúng được yêu cầu và không xác nhận khi chúng được cho là đúng. Kiểm tra các FooValidatorđầu vào và đầu ra của nó, sau đó bạn không quan tâm đến việc nó được thực hiện như thế nào . ++
RubberDuck

21

Regex có thể là một công cụ mạnh mẽ, nhưng nó không phải là một công cụ mà bạn có thể tin tưởng để vẫn hoạt động nếu bạn thực hiện ngay cả những thay đổi nhỏ đối với các biểu thức phức tạp.

Vì vậy, tạo ra nhiều bài kiểm tra tài liệu các trường hợp mà nó nên bao gồm. Và tạo ra nhiều bài kiểm tra mà tài liệu trường hợp nó sẽ thất bại, nếu nó được sử dụng để xác nhận.

Bất cứ khi nào bạn cần thay đổi regex của mình, bạn thêm các trường hợp mới dưới dạng thử nghiệm, sửa đổi regex của bạn và hy vọng điều tốt nhất.

Nếu tôi ở trong một tổ chức nói chung không sử dụng các bài kiểm tra đơn vị, tôi vẫn sẽ viết một chương trình kiểm tra để kiểm tra bất kỳ regex nào chúng tôi sẽ sử dụng. Tôi thậm chí sẽ tự làm điều đó nếu tôi phải làm vậy, tóc tôi không cần phải mất thêm màu nào nữa.


3

Biểu thức chính quy là mã cùng với phần còn lại của ứng dụng của bạn. Bạn nên kiểm tra xem mã nói chung có làm những gì bạn mong đợi không. Điều này có một số mục đích:

  • Kiểm tra là tài liệu runnable. Nó thể hiện rõ ràng những gì bạn cần mã để làm. Nếu nó được thử nghiệm thì nó rất quan trọng.
  • Những người duy trì trong tương lai có thể chắc chắn rằng nếu họ sửa đổi nó, các thử nghiệm sẽ đảm bảo rằng hành vi không thay đổi.

Vì có một trở ngại thêm để khắc phục bằng cách có mã bằng một ngôn ngữ khác được nhúng với phần còn lại, rất có thể bạn nên chú ý thêm cho lợi ích của việc bảo trì.


1

Tóm lại, bạn nên kiểm tra ứng dụng của bạn, thời gian. Cho dù bạn kiểm tra regex của mình bằng các kiểm tra tự động chạy nó một cách cô lập, như là một phần của hộp đen lớn hơn hoặc nếu bạn chỉ xoay quanh nó bằng tay là thứ yếu để đảm bảo rằng nó hoạt động.

Ưu điểm chính của kiểm tra đơn vị là chúng tiết kiệm thời gian. Họ cho phép bạn kiểm tra mọi thứ nhiều lần như bạn muốn bây giờ hoặc tại bất kỳ thời điểm nào trong tương lai. Nếu có bất kỳ lý do nào để tin rằng regex của bạn tại bất kỳ thời điểm nào sẽ được tái cấu trúc, điều chỉnh, có nhiều ràng buộc hơn, vâng, bạn có thể muốn một số bài kiểm tra hồi quy cho nó hoặc khi bạn thay đổi nó, bạn sẽ phải đi thông qua một giờ suy nghĩ thông qua tất cả các trường hợp cạnh để bạn không phá vỡ nó. Điều đó, hoặc bạn học cách sống với việc sợ mã của mình và đơn giản là không bao giờ thay đổi nó.


3
Một quy tắc của ngón tay cái tôi đã nhận ra; nếu tôi cần tài liệu để viết và kiểm tra mã, thì tôi sẽ cần một bài kiểm tra đơn vị. Họ đã cứu tôi rất nhiều vấn đề đau đầu, bắt con trỏ null, không có loại nào và đầu ra không chính xác. Họ cũng cung cấp cho người dùng cuối khả năng sửa chữa mã của bạn thành thông số kỹ thuật với nỗ lực tối thiểu khi nó chắc chắn bị hỏng.
Aaron3468

-1

Mặt khác: bản thân chúng hiếm khi là một phần của giao diện của một số đơn vị. Có thể tốt hơn nếu chỉ kiểm tra giao diện và thực hiện điều đó theo cách ngầm kiểm tra các biểu thức chính quy.

Tôi nghĩ với điều này bạn đã tự trả lời nó. Các quy tắc trong một đơn vị rất có thể là một chi tiết thực hiện.

Những gì diễn ra để kiểm tra SQL của bạn có lẽ cũng dành cho regexes. Khi bạn thay đổi một đoạn SQL, bạn có thể chạy nó thông qua một số máy khách SQL bằng tay để xem liệu nó có mang lại những gì bạn mong đợi không. Điều tương tự cũng xảy ra khi tôi thay đổi regex Tôi sử dụng một số công cụ regex với một số đầu vào mẫu để xem nó có làm những gì tôi mong đợi không.

Những gì tôi thấy hữu ích là một nhận xét gần regex với một mẫu văn bản mà nó phải phù hợp.


" Khi bạn thay đổi một đoạn SQL, bạn có thể chạy nó qua một số máy khách SQL để xem liệu nó có mang lại những gì bạn mong đợi không. " Nhưng loại câu trả lời này theo cách khác ... Nếu tôi cần hoặc nghĩ rằng nó hữu ích với kiểm tra regexes bằng tay thì tôi nên làm một bài kiểm tra đơn vị cho điều đó thay vào đó. Chính xác thì đây là điều khiến nó trở thành một điều khó khăn để quyết định!
Lii

Nó thực sự phụ thuộc. Những gì bạn muốn kiểm tra đơn vị của bạn là khả năng thực hiện thay đổi. Làm thế nào thường xuyên bạn thay đổi một regex cụ thể? Nếu câu trả lời thường là vậy thì bằng mọi cách hãy tạo một bài kiểm tra cho nó.
Christiaan

8
Tất cả những thứ khác đều bằng nhau, tốt hơn là có một bài kiểm tra tự động hơn là "kiểm tra bằng tay".
Robert Harvey

1
Tại sao bạn không kiểm tra regex bằng tự động hóa?
Tony Enni

1
Nó là một phần của một phương thức và tất cả những gì tôi đã cố gắng nói là không cần phải kiểm tra cụ thể regex nếu bạn đã kiểm tra phương thức đó. Nhưng nếu bạn làm như vậy, có lẽ tốt hơn hết bạn nên trích xuất regex thành một hàm riêng biệt mà bạn kiểm tra riêng rẽ.
Christiaan

-5

Nếu bạn phải hỏi, câu trả lời là có.

Giả sử một số FNG xuất hiện và nghĩ rằng anh ta có thể "cải thiện" regex của bạn. Bây giờ, anh ta là một FNG, nên tự động là một thằng ngốc. Chính xác là loại người không nên chạm vào mã quý giá của bạn trong mọi trường hợp! Nhưng có lẽ anh ấy liên quan đến PHB hoặc một cái gì đó, vì vậy bạn không thể làm gì.

Ngoại trừ bạn biết PHB sẽ kéo bạn đá và hét trở lại dự án này để "có thể cung cấp cho anh chàng một số gợi ý về cách bạn thực hiện mớ hỗn độn này" khi mọi thứ trở nên tồi tệ. Vì vậy, bạn viết ra tất cả các trường hợp mà bạn đã xem xét cẩn thận khi xây dựng kiệt tác tuyệt đẹp của bạn.

Và vì bạn đã viết tất cả chúng xuống, bạn đã có hai phần ba để có một bộ các trường hợp thử nghiệm, vì - hãy đối mặt với nó - các trường hợp thử nghiệm regex rất dễ chạy khi bạn đã xây dựng khung.

Vì vậy, bây giờ, bạn có một tập hợp các điều kiện cạnh, các lựa chọn thay thế và kết quả mong đợi. Và đột nhiên các trường hợp thử nghiệm là tài liệu đúng như đã hứa trong tất cả các bài đăng trên blog của tôi. Bạn chỉ cần nói với FNG rằng nếu "cải tiến" của anh ấy không vượt qua các trường hợp thử nghiệm hiện tại, thì đó không phải là một sự cải tiến, phải không? Và ở đâu đề nghị trường hợp thử nghiệm mới của mình rằng chứng minh một số vấn đề với mã gốc, mà vì nó hoạt động, ông không cần phải được sửa đổi, bao giờ hết !!!


3
FNG là gì? Đây có vẻ không phải là một câu trả lời tồi đối với tôi, nhưng thiếu định nghĩa cho FNG (googlin cho nó chỉ đưa ra kết quả không liên quan, vì vậy có lẽ câu trả lời này đã bị hạ cấp vì FNG?)
GameDeveloper

1
Tôi nghi ngờ rằng Google đã đưa bạn đến đúng nơi. ;-) ( en.wikipedia.org/wiki/FNG_syathy )
Austin Hastings

Trừ khi bạn là một thiên tài lập trình tuyệt đối, sẽ có nhiều lập trình viên có kinh nghiệm hơn xem xét những gì bạn làm giống như bạn nhìn vào anh chàng mới. Bạn có thể muốn xem xét là khiêm tốn hơn.
Thorbjørn Ravn Andersen
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.