ควรมีการทดสอบหน่วยสำหรับนิพจน์ปกติที่ซับซ้อนหรือไม่


34

ฉันควรเขียนการทดสอบหน่วยสำหรับนิพจน์ปกติที่ซับซ้อนในใบสมัครของฉันหรือไม่

  • ในอีกด้านหนึ่งพวกเขาทดสอบได้ง่ายเพราะรูปแบบอินพุตและเอาต์พุตมักจะง่ายและกำหนดไว้อย่างดีและพวกเขามักจะกลายเป็นความซับซ้อนดังนั้นการทดสอบของพวกเขาโดยเฉพาะมีค่า
  • ในทางกลับกัน: พวกมันเองไม่ค่อยเป็นส่วนหนึ่งของส่วนต่อประสานของบางหน่วย อาจเป็นการดีกว่าที่จะทดสอบเฉพาะส่วนต่อประสานและดำเนินการทดสอบ regexes โดยปริยาย

แก้ไข:

ผมเห็นด้วยกับหมอสีน้ำตาลที่ของเขาในการแสดงความคิดเห็นหมายเหตุที่เป็นกรณีพิเศษนี้หน่วยทดสอบของชิ้นส่วนภายใน

แต่เนื่องจากส่วนประกอบภายใน regexes มีคุณสมบัติพิเศษบางอย่าง:

  1. regex บรรทัดเดียวนั้นซับซ้อนจริงๆโดยไม่ต้องเป็นโมดูลแยกต่างหาก
  2. Regexes แม็พอินพุตกับเอาต์พุตโดยไม่มีผลข้างเคียงใด ๆ และง่ายต่อการทดสอบแยกต่างหาก

12
"พวกมันเองไม่ค่อยเป็นส่วนหนึ่งของส่วนต่อประสานของบางหน่วย" - หากคลาสของคุณมีรหัสที่น่าสนใจฝังอยู่ใต้ส่วนต่อประสานให้แบ่งคลาสของคุณ นี่คือตัวอย่างของการคิดเกี่ยวกับ tess ที่สามารถปรับปรุงการออกแบบ
นาธานคูเปอร์

3
คำถามเดียวกันในลักษณะโดยทั่วไปที่มากกว่า: ส่วนประกอบภายในใดที่ควรทดสอบหน่วย ดูprogrammers.stackexchange.com/questions/16732/…
Doc Brown

เกี่ยวข้องกับ Sorta ดู Regex101 พวกเขามีส่วนที่จะเขียนการทดสอบหน่วยสำหรับ regex ของคุณตัวอย่างเช่น: regex101.com/r/tR3mJ2/2
Reinstate Monica

3
ข้อสงวนสิทธิ์ - ความคิดเห็นนี้เป็นความเห็นที่ต่ำต้อยของฉัน: 1ก่อนอื่นฉันเชื่อว่า regexps ที่ซับซ้อนเป็นความชั่วร้ายที่บริสุทธิ์ - โปรดดูblog.codinghorror.com/… 2 คุณค่าที่แท้จริงของการทดสอบนิพจน์ดังกล่าวเกิดขึ้นเมื่อคุณทดสอบฐานข้อมูลขนาดใหญ่ของจริง data blog.codinghorror.com/testing-with-the-force 3ฉันมีความรู้สึกแปลก ๆ ว่าการทดสอบเหล่านี้ไม่ใช่การทดสอบหน่วยแน่นอน
Boris Treukhov

คำตอบ:


101

การทดสอบความเชื่อในเรื่องที่แตกต่างกันคำถามที่แท้จริงคือว่ามันให้คุณค่ากับการทดสอบหน่วยการแสดงออกปกติที่ซับซ้อน ดูเหมือนจะค่อนข้างชัดเจนว่ามันให้คุณค่า (ไม่ว่า regex จะเป็นส่วนหนึ่งของส่วนต่อประสานสาธารณะหรือไม่) ถ้า regex นั้นซับซ้อนพอเพราะมันช่วยให้คุณค้นหาและทำซ้ำข้อผิดพลาดและป้องกันการถดถอย


25
+1 แต่ถ้าการแสดงออกปกติก็เพียงพอที่ซับซ้อนที่ว่านี้เป็นปัญหาแล้วมันอาจจะทำให้ความรู้สึกที่จะย้ายไปกลายเป็น "เสื้อคลุม" หน่วยด้วยวิธีการที่เหมาะสม ( isValid, parse, tryParseหรือ whatnot ขึ้นอยู่ว่าวิธีการที่มันถูกใช้) ดังนั้น ว่ารหัสลูกค้าไม่จำเป็นต้องรู้ว่ามันมีการใช้งานในปัจจุบันโดยใช้ regex หน่วยห่อหุ้มนั้นจะมีการทดสอบอย่างละเอียดซึ่ง - อีกครั้ง - ไม่จำเป็นต้องรู้การใช้งานในปัจจุบัน การทดสอบเหล่านี้แน่นอนมีพฤตินัยทดสอบ regex แต่ในวิธีการดำเนินงานที่ไม่เชื่อเรื่องพระเจ้า
ruakh

1
reg ex เป็นโปรแกรม แต่เป็นภาษาที่มีความเชี่ยวชาญและสั้นมาก ด้วยเหตุนี้การทดสอบจึงเหมาะสมสำหรับนิพจน์ที่ไม่น่าสนใจ ... และแน่นอนรหัสที่เรียกใช้นิพจน์ควรได้รับการทดสอบซึ่งอาจทดสอบโดยปริยาย
keshlam

6
@ruakh Well พูด ประโยชน์ของคลาส wrapper สำหรับ regex คือคุณสามารถแทนที่มันด้วยโค้ดธรรมดาได้หากจำเป็น รหัสที่มีอินพุต / เอาต์พุตที่ซับซ้อนควรมีการทดสอบหน่วยเสมอเนื่องจากเป็นการยากที่จะทำการดีบักอย่างน่าทึ่ง หากคุณจำเป็นต้องอ้างถึงเอกสารประกอบเพื่อให้เข้าใจถึงผลกระทบของรหัสควรมีการทดสอบหน่วย หากเป็นเพียงการแมป 1: 1 อย่างรวดเร็วเช่นการแปลงประเภทแสดงว่าไม่มีปัญหา Regexes ผ่านจุดที่ต้องการเอกสารอย่างรวดเร็ว
Aaron3468

4
@Lii: Regexes ไม่สมควรได้รับการดูแลเป็นพิเศษ regex เป็นหน่วยในกรณีนี้ดังนั้นเราจึงทดสอบหน่วย
JacquesB

1
@ruakh ฉันกำลังจะเขียนคำตอบสำหรับผลกระทบนั้น ฉันยอมรับว่าการใช้ regex เป็นรายละเอียดการใช้งาน สิ่งที่สำคัญคือสิ่งที่ตรวจสอบเมื่อพวกเขาควรจะและไม่สามารถตรวจสอบเมื่อพวกเขาควรจะ ทดสอบFooValidatorอินพุทและเอาท์พุทของมันจากนั้นคุณไม่ต้องกังวลเกี่ยวกับวิธีการทำงานของมัน ++
RubberDuck

21

Regex อาจเป็นเครื่องมือที่ทรงพลัง แต่ก็ไม่ใช่เครื่องมือที่คุณสามารถไว้วางใจให้ใช้งานได้หากคุณทำการเปลี่ยนแปลงเล็กน้อยกับ regexes ที่ซับซ้อน

ดังนั้นสร้างการทดสอบจำนวนมากที่บันทึกกรณีที่ควรครอบคลุม และสร้างการทดสอบจำนวนมากที่บันทึกกรณีที่มันควรจะล้มเหลวถ้ามันถูกใช้สำหรับการตรวจสอบ

เมื่อใดก็ตามที่คุณต้องการเปลี่ยน regexes ของคุณคุณเพิ่มกรณีใหม่เป็นแบบทดสอบแก้ไข regex ของคุณและหวังว่าจะดีที่สุด

ถ้าฉันอยู่ในองค์กรที่โดยทั่วไปไม่ได้ใช้การทดสอบหน่วยฉันจะยังคงเขียนโปรแกรมทดสอบที่จะทดสอบ regex ใด ๆ ที่เราต้องการใช้ ฉันจะทำด้วยตัวเองตามเวลาของฉันถ้าฉันมีผมของฉันไม่จำเป็นต้องเสียสีอีกต่อไป


3

นิพจน์ทั่วไปคือรหัสพร้อมกับแอปพลิเคชั่นที่เหลือของคุณ คุณควรทดสอบว่ารหัสโดยรวมทำในสิ่งที่คุณคาดหวังว่าจะทำ สิ่งนี้มีวัตถุประสงค์หลายประการ:

  • การทดสอบเป็นเอกสารที่ทำงานได้ มันแสดงให้เห็นอย่างชัดเจนถึงสิ่งที่คุณต้องใช้รหัสในการทำ หากมีการทดสอบเป็นสิ่งสำคัญ
  • ผู้ดูแลในอนาคตสามารถมั่นใจได้ว่าหากพวกเขาปรับเปลี่ยนการทดสอบจะให้แน่ใจว่าพฤติกรรมไม่เปลี่ยนแปลง

เนื่องจากมีอุปสรรค์พิเศษที่จะเอาชนะได้โดยมีรหัสในภาษาอื่นฝังกับส่วนที่เหลือคุณน่าจะให้ความสนใจเป็นพิเศษนี้เพื่อประโยชน์ของการบำรุงรักษา


1

ในระยะสั้นคุณควรทดสอบใบสมัครของคุณระยะเวลา ไม่ว่าคุณจะทดสอบ regex ของคุณด้วยการทดสอบอัตโนมัติที่แยกออกมาเป็นส่วนหนึ่งของกล่องดำที่มีขนาดใหญ่ขึ้นหรือหากคุณคลุกคลีไปกับมันด้วยมือนั้นเป็นเรื่องรองไปยังจุดที่คุณต้องการเพื่อให้แน่ใจว่ามันทำงานได้

ประโยชน์หลักของการทดสอบหน่วยคือพวกเขาประหยัดเวลา พวกเขาให้คุณทดสอบสิ่งต่าง ๆ ได้บ่อยเท่าที่คุณต้องการในตอนนี้หรือ ณ เวลาใด ๆ ในอนาคต หากมีเหตุผลใด ๆ ที่จะเชื่อว่า regex ของคุณจะได้รับการปรับเปลี่ยน, tweaked, รับข้อ จำกัด มากขึ้น ฯลฯ แล้วใช่คุณอาจต้องการทดสอบการถดถอยสำหรับมันหรือเมื่อคุณเปลี่ยนคุณจะต้องไป ผ่านการคิดชั่วโมงผ่านทุกกรณีที่เป็นขอบดังนั้นคุณจึงไม่ทำให้แตก หรือคุณเรียนรู้ที่จะอยู่กับการกลัวรหัสของคุณและไม่เคยเปลี่ยนเลย


3
กฎง่ายๆที่ฉันเข้าใจ ถ้าฉันต้องการเอกสารเพื่อเขียนและตรวจสอบรหัสฉันจะต้องทำการทดสอบหน่วย พวกเขาได้ช่วยให้ฉันปวดหัวจำนวนมากจับตัวชี้โมฆะไม่มีประเภทและเอาต์พุตไม่ถูกต้อง พวกเขายังให้ความสามารถแก่ผู้ใช้ในการซ่อมรหัสของคุณเพื่อสเป็คด้วยความพยายามน้อยที่สุดเมื่อมันแตกอย่างหลีกเลี่ยงไม่ได้
Aaron3468

-1

ในทางกลับกัน: พวกมันเองไม่ค่อยเป็นส่วนหนึ่งของส่วนต่อประสานของบางหน่วย อาจเป็นการดีกว่าที่จะทดสอบเฉพาะส่วนต่อประสานและดำเนินการทดสอบ regexes โดยปริยาย

ฉันคิดว่าสิ่งนี้คุณตอบด้วยตัวคุณเอง Regexes ในหน่วยส่วนใหญ่มีรายละเอียดการใช้งาน

สิ่งที่เกิดขึ้นสำหรับการทดสอบ SQL ของคุณก็อาจเป็นไปได้สำหรับ regexes เมื่อคุณเปลี่ยนชิ้นส่วนของ SQL คุณอาจเรียกใช้ผ่านทางไคลเอนต์ SQL ด้วยมือเพื่อดูว่ามันให้ผลตามที่คุณคาดหวังหรือไม่ สิ่งเดียวกันนี้เกิดขึ้นเมื่อฉันเปลี่ยน regex ฉันใช้เครื่องมือ regex ที่มีอินพุตตัวอย่างบางส่วนเพื่อดูว่าเป็นไปตามที่ฉันคาดไว้หรือไม่

สิ่งที่ฉันพบว่ามีประโยชน์คือความคิดเห็นใกล้กับ regex พร้อมตัวอย่างข้อความที่ควรตรงกัน


" เมื่อคุณเปลี่ยนชิ้นส่วนของ SQL คุณอาจเรียกใช้งาน SQL ไคลเอ็นต์ด้วยมือเพื่อดูว่ามันให้ผลลัพธ์ตามที่คุณคาดหวังหรือไม่ " แต่คำตอบประเภทนี้จะตอบคำถามในทางอื่น ... ถ้าฉันต้องการหรือคิดว่ามันมีประโยชน์ ทดสอบ regexes ด้วยมือจากนั้นฉันควรทำการทดสอบหน่วยแทน ตรงนี้เป็นสิ่งที่ทำให้มันเป็นเรื่องยากที่จะตัดสินใจ!
Lii

มันขึ้นอยู่กับ สิ่งที่คุณต้องการทดสอบหน่วยของคุณคือความสามารถในการเปลี่ยนแปลง คุณเปลี่ยน regex ที่เฉพาะเจาะจงบ่อยแค่ไหน? หากคำตอบคือบ่อยครั้งโดยทั้งหมดหมายความว่าสร้างการทดสอบสำหรับมัน
Christiaan

8
ทุกสิ่งเท่าเทียมกันดีกว่าที่จะมีการทดสอบอัตโนมัติมากกว่า "การทดสอบด้วยมือ"
Robert Harvey

1
ทำไมคุณไม่ทดสอบ regex โดยใช้ระบบอัตโนมัติ?
Tony Ennis

1
มันเป็นส่วนหนึ่งของวิธีการและสิ่งที่ฉันพยายามบอกก็คือไม่จำเป็นต้องทดสอบ regex โดยเฉพาะถ้าคุณทดสอบวิธีนั้นแล้ว แต่ถ้าคุณทำคุณอาจจะดีกว่าการแยก regex ลงในฟังก์ชั่นแยกต่างหากที่คุณทดสอบในการแยก
Christiaan

-5

หากคุณต้องถามคำตอบคือใช่

สมมติว่ามี FNG เข้ามาบ้างและคิดว่าเขาสามารถ "ปรับปรุง" regex ของคุณได้ ตอนนี้เขาเป็น FNG ดังนั้นคนงี่เง่าโดยอัตโนมัติ ประเภทของบุคคลที่ไม่ควรสัมผัสรหัสอันมีค่าของคุณไม่ว่าในกรณีใด ๆ ! แต่บางทีเขาอาจเกี่ยวข้องกับPHBหรือบางสิ่งบางอย่างดังนั้นจึงไม่มีอะไรที่คุณสามารถทำได้

ยกเว้นว่าคุณรู้ว่า PHB กำลังจะลากคุณเตะและส่งเสียงกรี๊ดกลับไปที่โปรเจ็กต์นี้ "อาจจะให้พอยน์เตอร์เกี่ยวกับวิธีที่คุณทำสิ่งนี้กับผู้ชาย" เมื่อทุกอย่างไม่ดี ดังนั้นคุณต้องเขียนทุกกรณีที่คุณได้พิจารณาอย่างรอบคอบเมื่อสร้างผลงานชิ้นเอกที่สวยงามของคุณ

และเมื่อคุณเขียนลงไปหมดคุณมีสองในสามของวิธีที่จะมีกรณีทดสอบหลายชุดตั้งแต่ - ลองดูกัน - กรณีทดสอบของ regex นั้นตายง่ายต่อการทำงานเมื่อคุณสร้างเฟรมเวิร์กแล้ว

ตอนนี้คุณมีชุดของเงื่อนไขขอบทางเลือกและผลลัพธ์ที่คาดหวัง และทันใดนั้นกรณีทดสอบก็เป็นเอกสารตามที่สัญญาไว้ในโพสต์บล็อกของฉันด้วยเช่นกัน คุณเพิ่งชี้ไปที่ FNG ว่าถ้า "การปรับปรุง" ของเขาไม่ผ่านกรณีทดสอบที่มีอยู่มันไม่ได้ปรับปรุงเลยใช่มั้ย และกรณีทดสอบใหม่ของเขาที่เสนอซึ่งแสดงให้เห็นปัญหาบางอย่างกับรหัสต้นฉบับซึ่งมันใช้งานได้เขาไม่จำเป็นต้องปรับเปลี่ยนเลย !!!


3
FNG คืออะไร นี่ดูเหมือนจะไม่ใช่คำตอบที่ไม่ดีสำหรับฉัน แต่คำจำกัดความที่ขาดหายไปของ FNG (googlin เพราะมันให้ผลลัพธ์ที่ไม่เกี่ยวข้องดังนั้นบางทีคำตอบนี้อาจถูกลดระดับลงเพราะ FNG?)
GameDeveloper

1
ฉันสงสัยว่า Google พาคุณไปถูกที่แล้ว ;-) ( en.wikipedia.org/wiki/FNG_syndrome )
Austin Hastings

นอกจากคุณจะเป็นอัจฉริยะแห่งการเขียนโปรแกรมอย่างแท้จริงแล้วก็จะมีโปรแกรมเมอร์ที่มีประสบการณ์มากกว่าพิจารณาสิ่งที่คุณทำเหมือนดูผู้ชายคนใหม่ คุณอาจต้องการพิจารณาความอ่อนน้อมถ่อมตนมากขึ้น
Thorbjørn Ravn Andersen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.