การทดสอบหน่วยจะช่วยให้ซิตี้กรุ๊ปหลีกเลี่ยงข้อผิดพลาดราคาแพงนี้หรือไม่


86

ฉันอ่านเกี่ยวกับ snafu นี้: ค่าใช้จ่ายข้อผิดพลาด Programming ซิตี้กรุ๊ป $ 7 หลังจากการทำธุรกรรมที่ legit เข้าใจผิดว่าเป็นข้อมูลการทดสอบเป็นเวลา 15 ปี

เมื่อระบบเปิดตัวในกลางปี ​​1990 รหัสโปรแกรมจะกรองธุรกรรมใด ๆ ที่ได้รับรหัสสาขาสามหลักจาก 089 ถึง 100 และใช้คำนำหน้าเหล่านั้นเพื่อวัตถุประสงค์ในการทดสอบ

แต่ในปี 1998 บริษัท เริ่มใช้รหัสสาขาตัวอักษรและตัวเลขเมื่อขยายธุรกิจ ในหมู่พวกเขาคือรหัส 10B, 10C และอื่น ๆ ซึ่งระบบถือว่าอยู่ในช่วงที่ยกเว้นและการทำธุรกรรมของพวกเขาจะถูกลบออกจากรายงานใด ๆ ที่ส่งไปยังสำนักงาน ก.ล.ต.

(ฉันคิดว่าสิ่งนี้แสดงให้เห็นว่าการใช้ตัวบ่งชี้ข้อมูลที่ไม่ชัดเจนคือ ... ย่อยที่ดีที่สุดมันจะดีกว่ามากที่จะเติมและใช้Branch.IsLiveคุณสมบัติที่ชัดเจนเชิงความหมาย)

นอกเหนือจากนั้นปฏิกิริยาแรกของฉันคือ "การทดสอบหน่วยจะช่วยให้ที่นี่" ... แต่พวกเขาจะ?

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



17
ดูเหมือนว่าพวกเขายังพลาดการทดสอบการรวมซึ่งตรวจสอบจำนวนธุรกรรมที่ส่งออกไปยัง SEC หากคุณสร้างคุณสมบัติการส่งออกที่จะเป็นการตรวจสอบที่เหมาะสม
Luc Franken

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

25
@gnat ฉันไม่ได้อ่านที่ลิงค์ภายนอกและฉันยังคงพบว่าคำถามนี้มีความหมาย
Jeutnarg

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

คำตอบ:


19

คุณกำลังถามว่า "การทดสอบหน่วยจะช่วยได้ที่นี่จริง ๆ " หรือคุณถามว่า "การทดสอบประเภทใดก็ได้ที่อาจช่วยได้ที่นี่"

รูปแบบที่ชัดเจนที่สุดของการทดสอบที่จะช่วยคือการยืนยันเงื่อนไขในโค้ดนั้นตัวระบุสาขาประกอบด้วยตัวเลขเท่านั้น (สมมติว่านี่เป็นข้อสันนิษฐานที่อาศัยโดย coder ในการเขียนรหัส)

สิ่งนี้อาจล้มเหลวในการทดสอบการรวมบางประเภทและทันทีที่มีการเปิดใช้รหัสรหัสสาขาใหม่ที่เป็นตัวเลขและตัวอักษรแล้วการยืนยันก็จะเกิดขึ้น แต่นั่นไม่ใช่การทดสอบหน่วย

หรืออาจมีการทดสอบการรวมกลุ่มของขั้นตอนที่สร้างรายงาน ก.ล.ต. การทดสอบนี้ช่วยให้มั่นใจว่าตัวระบุสาขาจริงทุกรายงานธุรกรรมของตน (และต้องใช้การป้อนข้อมูลจริงในโลกรายการของตัวระบุสาขาทั้งหมดที่ใช้งานอยู่) นั่นไม่ใช่การทดสอบหน่วยเช่นกัน

ฉันไม่สามารถดูความหมายหรือเอกสารใด ๆ ของอินเตอร์เฟซที่เกี่ยวข้อง แต่มันอาจเป็นไปได้ว่าการทดสอบหน่วยไม่อาจตรวจพบข้อผิดพลาดเพราะหน่วยไม่ได้เป็นความผิดพลาด หากหน่วยได้รับอนุญาตให้สมมติว่าตัวระบุสาขาประกอบด้วยตัวเลขเท่านั้นและนักพัฒนาไม่เคยตัดสินใจว่าควรใช้รหัสใดในกรณีที่ไม่มีเขียนการทดสอบหน่วยเพื่อบังคับใช้พฤติกรรมเฉพาะในกรณีของตัวระบุที่ไม่ใช่ตัวเลขเนื่องจากการทดสอบจะปฏิเสธการใช้งานที่ถูกต้องตามสมมุติฐานของหน่วยที่จัดการตัวระบุสาขาตัวอักษรและตัวเลขอย่างถูกต้องและคุณไม่ต้องการเขียนการทดสอบหน่วยที่ป้องกันการใช้งาน การใช้งานและส่วนขยายในอนาคต หรือบางทีหนึ่งเอกสารที่เขียนเมื่อ 40 ปีที่แล้วได้นิยามไว้โดยปริยาย (ผ่านบางช่วงของคำศัพท์ใน EBCDIC ดิบแทนที่จะเป็นกฎการเปรียบเทียบที่เป็นมิตรกับมนุษย์มากกว่า) ว่า 10B เป็นตัวระบุการทดสอบเพราะมันอยู่ระหว่าง 089 ถึง 100 15 ปีที่แล้วมีคนตัดสินใจที่จะใช้มันเป็นตัวระบุที่แท้จริงดังนั้น "ความผิดพลาด" ไม่ได้อยู่ในหน่วยที่ใช้นิยามดั้งเดิมอย่างถูกต้อง: มันอยู่ในกระบวนการที่ล้มเหลวที่จะสังเกตเห็นว่า 10B ถูกกำหนดให้เป็นตัวระบุการทดสอบและดังนั้นจึงไม่ควรกำหนดให้กับสาขา เช่นเดียวกันจะเกิดขึ้นใน ASCII หากคุณกำหนด 089 - 100 เป็นช่วงทดสอบแล้วแนะนำตัวระบุ 10 $ หรือ 1.0 มันเพิ่งเกิดขึ้นว่าใน EBCDIC ตัวเลขที่ตามหลังตัวอักษร

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

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

ฉันเห็นด้วยแน่นอนว่าถ้าหน่วยไม่ได้ถูกกำหนดในตอนแรกด้วยอินพุต "รูปทรงตลก" จากนั้นจะไม่มีอะไรที่จะทดสอบ การตั้งชื่อเนมสเปซเป็นเรื่องยากที่จะทดสอบได้อย่างถูกต้องเพราะความยากลำบากไม่ได้อยู่ที่การใช้คำจำกัดความตลกของคุณมันอยู่ในการทำให้แน่ใจว่าทุกคนเข้าใจและเคารพคำจำกัดความตลกของคุณ นั่นไม่ใช่คุณสมบัติโลคัลของหน่วยโค้ดหนึ่งหน่วย นอกจากนี้การเปลี่ยนประเภทข้อมูลบางส่วนจาก "สตริงของตัวเลข" เป็น "สตริงของตัวอักษรและตัวเลข" นั้นคล้ายกับการทำให้โปรแกรมที่ใช้ ASCII จัดการกับ Unicode: มันจะไม่ง่ายถ้ารหัสของคุณจะถูกรวมเข้ากับคำจำกัดความเดิมอย่างมาก ประเภทข้อมูลเป็นพื้นฐานของสิ่งที่โปรแกรมทำแล้วมันมักจะเป็นคู่อย่างมาก

มันค่อนข้างน่ารำคาญถ้าคิดว่ามันต้องใช้ความพยายามอย่างมาก

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


ยืนยันเป็นสิ่งที่ดี!

3
@nocomprende: ตามที่เรแกนมีไว้ "วางใจ แต่ยืนยัน"
Steve Jessop

1
ฉันยังจะพูดว่า "การทดสอบหน่วยไม่ดี!" แต่ฉันคิดว่าคนส่วนใหญ่จะพลาดการอ้างอิงไปที่Animal Farmและเริ่มวิจารณ์ฉันจริง ๆแทนที่จะคิดว่าสิ่งที่ฉันพูด (การกระตุกเข่าไม่ได้ผล) แต่ฉันไม่ได้พูดอย่างนั้น บางทีคนที่ฉลาดกว่าและมีความรู้ที่ดีสามารถทำให้ประเด็นนั้นเกิดขึ้นได้

2
"การทดสอบทั้งหมดผ่าน แต่การทดสอบบางอย่างผ่านไปได้มากกว่าการทดสอบอื่น ๆ !"
เกรแฮม

1
การทดสอบเป็นปลาเฮอริ่งแดง พวกเหล่านี้ไม่รู้ด้วยซ้ำว่า "รหัสสาขา" ถูกกำหนดไว้อย่างไร นี่จะเป็นเหมือนที่ทำการไปรษณีย์ของสหรัฐอเมริกาที่ไม่รู้ว่ามันกำลังเปลี่ยนนิยามของรหัสไปรษณีย์เมื่อมันเพิ่ม 4 หลัก
Radarbob

120

การทดสอบหน่วยสามารถจับได้ว่ารหัสสาขา 10B และ 10C ถูกจำแนกอย่างไม่ถูกต้องว่าเป็น "สาขาทดสอบ" แต่ฉันคิดว่ามันไม่น่าเป็นไปได้ที่การทดสอบสำหรับการจำแนกสาขานั้นจะกว้างขวางพอที่จะจับข้อผิดพลาดนั้นได้

ในทางกลับกันการตรวจสอบเฉพาะจุดของรายงานที่สร้างขึ้นสามารถเปิดเผยได้ว่า 10B และ 10C ที่แยกจากกันหายไปจากรายงานอย่างต่อเนื่องเร็วกว่า 15 ปีที่ข้อผิดพลาดนี้ได้รับอนุญาตให้คงอยู่

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


80
การทดสอบหน่วย +1 ไม่สามารถชดเชยการตัดสินใจในการออกแบบที่ไม่ดีได้ (เช่นการทดสอบแบบผสมและข้อมูลจริง)
Jeutnarg

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

4
@Voo ฉันคิดว่ามีข้อสันนิษฐานโดยปริยายว่ามีระดับของความซับซ้อนหรือความต้องการความน่าเชื่อถือที่การทดสอบจริงระบบการนำไปใช้งานจริงนั้นถือว่าคุ้มค่าหรือจำเป็น (พิจารณาว่าจะผิดพลาดมากเพียงใดเนื่องจากตัวแปรการกำหนดค่าที่ไม่ถูกต้อง) ฉันเห็นว่านี่เป็นกรณีของสถาบันการเงินขนาดใหญ่
jpmc26

4
@Voo ฉันไม่ได้พูดถึงการทดสอบ ฉันกำลังพูดถึงการตรวจสอบความถูกต้องของระบบ ในระบบการผลิตจริงมีหลายวิธีที่จะล้มเหลวที่ไม่เกี่ยวข้องกับรหัส หากคุณกำลังวางระบบธนาคารใหม่ในการผลิตคุณอาจมีปัญหาบางอย่างในฐานข้อมูลหรือเครือข่ายอื่น ๆ ที่ป้องกันไม่ให้ธุรกรรมถูกนำไปใช้กับบัญชี ฉันไม่เคยทำงานที่ธนาคาร แต่ฉันค่อนข้างแน่ใจว่ามันขมวดคิ้วเมื่อเริ่มปรับเปลี่ยนบัญชีจริงด้วยธุรกรรมปลอม เพื่อให้คุณตั้งค่าบัญชีปลอมหรือรอและอธิษฐาน
JimmyJames

12
@JimmyJames ในด้านการดูแลสุขภาพเป็นเรื่องปกติที่จะคัดลอกฐานข้อมูลการผลิตเป็นระยะในสภาพแวดล้อมการทดสอบเพื่อทำการทดสอบข้อมูลที่ใกล้เคียงกับของจริงมากที่สุด ฉันคิดว่าธนาคารสามารถทำเช่นเดียวกัน
dj18

75

ซอฟต์แวร์ต้องจัดการกับกฎเกณฑ์ทางธุรกิจบางอย่าง หากมีการทดสอบหน่วยการทดสอบหน่วยจะตรวจสอบว่าซอฟต์แวร์จัดการกฎธุรกิจอย่างถูกต้อง

กฎธุรกิจเปลี่ยนไป

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

ดังนั้นไม่การทดสอบหน่วยจะไม่เข้าใจ

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

แน่นอนในกรณีเดียวกันหากมีการเปลี่ยนแปลงซอฟต์แวร์เท่านั้นไม่ใช่การทดสอบหน่วยดังนั้นการทดสอบหน่วยก็จะล้มเหลวเช่นกัน เมื่อใดก็ตามที่การทดสอบหน่วยล้มเหลวก็ไม่ได้หมายความว่าซอฟต์แวร์ผิดก็หมายความว่าซอฟต์แวร์หรือการทดสอบหน่วย (บางครั้งทั้งคู่) ผิด


2
เป็นไปได้หรือไม่ที่จะมีทีมต่าง ๆ ที่หนึ่งทำงานกับรหัสและอื่น ๆ ในการทดสอบ "หน่วย" มันเป็นไปได้ยังไง ... ข้าทำการปรับรหัสของข้าใหม่ตลอดเวลา
Sergio

2
@Sergio จากมุมมองหนึ่ง refactoring การเปลี่ยนแปลงภายในขณะที่รักษาพฤติกรรม - ดังนั้นหากการทดสอบจะเขียนในลักษณะที่ทดสอบพฤติกรรมโดยไม่ต้องอาศัย internals แล้วมันไม่จำเป็นต้องปรับปรุง
Daenyth

1
ฉันเคยเห็นสิ่งนี้เกิดขึ้นหลายครั้ง ซอฟต์แวร์กำลังทำการผลิตโดยไม่มีการร้องเรียนจากนั้นผู้ใช้ทั้งหมดในทันทีที่มีการร้องเรียนว่ามันไม่ทำงานอีกต่อไปและค่อยๆล้มเหลวในช่วงหลายปีที่ผ่านมา นั่นคือสิ่งที่เกิดขึ้นเมื่อคุณตัดสินใจที่จะไปและเปลี่ยนขั้นตอนภายในของคุณโดยไม่ต้องทำตามขั้นตอนการแจ้งเตือนมาตรฐาน ...
Brian Knoblauch

42
"การเปลี่ยนแปลงกฎธุรกิจ" เป็นการสังเกตที่สำคัญ การทดสอบหน่วยตรวจสอบว่าคุณดำเนินการตรรกะคุณคิดว่าคุณดำเนินการไม่ว่าตรรกะของคุณเป็นที่ถูกต้อง
Ryan Cavanaugh

5
หากฉันถูกต้องเกี่ยวกับสิ่งที่เกิดขึ้นเป็นไปได้ยากที่หน่วยทดสอบจะตรวจจับสิ่งนี้จะถูกเขียนขึ้น หลักการพื้นฐานสำหรับการเลือกการทดสอบคือการทดสอบบางกรณี "ดี" บางกรณี "ไม่ดี" และกรณีถ่ายคร่อมขอบเขตใด ๆ ในกรณีนี้คุณจะทดสอบ "099", "100" และ "101" เนื่องจาก "10B" ถูกครอบคลุมโดยการทดสอบ "ปฏิเสธที่ไม่ใช่ตัวเลข" ภายใต้ระบบเก่าและมากกว่า 101 (และถูกครอบคลุมโดยการทดสอบนั้น) ภายใต้ระบบใหม่จึงไม่มีเหตุผลที่จะทดสอบ - ยกเว้นใน EBCDIC, "10B" จัดเรียงระหว่าง "099" และ "100"
ทำเครื่องหมาย

29

ไม่นี่เป็นปัญหาใหญ่อย่างหนึ่งของการทดสอบหน่วย: พวกเขาจะขับกล่อมให้คุณรู้สึกถึงความปลอดภัย

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


17
พ่อของฉันเคยถามฉันว่า: ทำไมคุณไม่คิดในสิ่งที่คุณไม่ได้คิด (มีเพียงเขาเคยทำให้สับสนโดยการพูดว่า "ถ้าคุณไม่รู้จงถาม !") แต่ฉันจะรู้ได้อย่างไรว่าฉันไม่รู้

7
"หมายความว่าชิ้นส่วนของการออกแบบของคุณที่คุณคิดอย่างมีสติและเขียนแบบทดสอบทำงานอย่างที่คุณคิด ถูกต้อง ข้อมูลนี้มีค่ามากหากคุณทำการปรับโครงสร้างใหม่หรือหากมีการเปลี่ยนแปลงบางอย่างในระบบที่ทำให้สมมติฐานของคุณแตก นักพัฒนาซอฟต์แวร์ที่ถูกกล่อมให้รู้สึกถึงความปลอดภัยไม่เข้าใจข้อ จำกัด ของการทดสอบหน่วย แต่นั่นไม่ได้ทำให้การทดสอบหน่วยเป็นเครื่องมือที่ไร้ประโยชน์
Robert Harvey

12
@MasonWheeler: เช่นเดียวกับคุณผู้เขียนคิดว่าการทดสอบหน่วยควรจะพิสูจน์ว่าโปรแกรมของคุณทำงานได้ มันไม่ได้ ฉันขอย้ำว่า: การทดสอบหน่วยไม่ได้พิสูจน์ว่าโปรแกรมของคุณทำงาน การทดสอบหน่วยพิสูจน์ว่าวิธีการของคุณเป็นไปตามสัญญาทดสอบและนั่นคือทั้งหมดที่ทำได้ ส่วนที่เหลือของกระดาษล้มลงเพราะมันวางอยู่บนสมมติฐานที่ไม่ถูกต้องเพียงครั้งเดียวนั้น
Robert Harvey

5
โดยปกติแล้วนักพัฒนาที่มีความเชื่อที่ผิดจะต้องผิดหวังเมื่อการทดสอบหน่วยล้มเหลวอย่างสิ้นเชิง แต่นั่นเป็นความผิดพลาดของผู้พัฒนาไม่ใช่การทดสอบหน่วยและไม่ทำให้มูลค่าของแท้ที่ใช้ทดสอบนั้นเป็นโมฆะ
Robert Harvey

5
o_O @ ประโยคแรกของคุณ การทดสอบแบบหน่วยจะให้ความรู้สึกที่ผิด ๆ กับการรักษาความปลอดภัยในขณะที่เขียนโค้ดเช่นมีมืออยู่บนพวงมาลัยช่วยให้คุณรู้สึกถึงความปลอดภัยในขณะขับรถ
djechlin

10

ไม่ไม่จำเป็น

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

จากนั้นข้อกำหนดจะมีการเปลี่ยนแปลงและอัปเดตรหัสแล้ว แต่นี่อาจหมายถึงรหัสทดสอบหน่วยที่ให้ข้อมูลที่ไม่ดี (นั่นคือข้อมูลที่ดี) จะต้องมีการแก้ไข

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

การทดสอบหน่วยเป็นสิ่งที่ดีสำหรับการพัฒนาดั้งเดิม แต่ไม่ใช่สำหรับการทดสอบระบบโดยเฉพาะอย่างยิ่งไม่เกิน 15 ปีหลังจากข้อกำหนดถูกลืมไปนาน

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


จับได้เห็นชัดตรงเผง. และปัญหาหลัก (เท่านั้น) กับการทดสอบหน่วย บันทึกฉันด้วยคำตอบของฉันเองตามที่ฉันได้กล่าวไว้อย่างแม่นยำในสิ่งเดียวกัน (แต่อาจแย่กว่านี้!) :)
Lightness Races ใน Orbit

8

การทดสอบประเภท (กระบวนการทดสอบค่าคงที่โดยใช้ข้อมูลที่สร้างขึ้นแบบสุ่มตามตัวอย่างจาก Haskell ห้องสมุดทดสอบQuickCheckและพอร์ต / ทางเลือกต่าง ๆ ที่ได้รับแรงบันดาลใจจากภาษาอื่น) อาจตรวจจับปัญหานี้ได้ .

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

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

แน่นอน QuickCheck ได้รับการพัฒนาเป็นครั้งแรกในปี 1999 ดังนั้นจึงสายเกินไปที่จะตรวจสอบปัญหานี้


1
ฉันคิดว่าเป็นเรื่องปกติมากขึ้นที่จะเรียกการทดสอบตามคุณสมบัตินี้และแน่นอนว่ามันเป็นไปได้ที่จะเขียนการทดสอบตามคุณสมบัติที่จะผ่านการเปลี่ยนแปลงนี้ (แม้ว่าฉันคิดว่าคุณมีแนวโน้มที่จะเขียนการทดสอบที่หาได้)
jk

5

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

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

คุณสามารถตรวจพบปัญหานี้ได้อย่างสมเหตุสมผลผ่าน:

  • การทดสอบการผสาน - แต่คุณจะต้องเพิ่มรูปแบบรหัสใหม่เพื่อป้อนผ่านหลาย ๆ หน่วยในระบบ (เช่นพวกเขาจะแสดงปัญหาให้คุณเฉพาะในกรณีที่การทดสอบเริ่มต้นรวมสาขาที่ถูกต้องแล้วในตอนนี้)
  • การทดสอบแบบครบวงจร - ธุรกิจควรดำเนินการทดสอบแบบ end-to-end ที่รวมรูปแบบรหัสสาขาเก่าและใหม่

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


2

การยืนยันในตัวในเวลาทำงานอาจช่วยได้ ตัวอย่างเช่น:

  1. สร้างฟังก์ชั่นเช่น bool isTestOnly(string branchCode) { ... }
  2. ใช้ฟังก์ชันนี้เพื่อตัดสินใจว่าจะกรองรายงานใด
  3. ใช้ฟังก์ชันนั้นอีกครั้งในการยืนยันในรหัสการสร้างสาขาเพื่อตรวจสอบหรือยืนยันว่าสาขานั้นไม่ได้สร้าง (ไม่สามารถ) ได้โดยใช้รหัสสาขาประเภทนี้‼
  4. เปิดใช้งานการยืนยันนี้ในเวลาทำงานจริง (และไม่ "ปรับให้เหมาะสมยกเว้นในรหัสนักพัฒนารุ่นเฉพาะการดีบัก")‼

ดูสิ่งนี้ด้วย:


2

Takeaway ที่จากนี้คือการล้มเหลวอย่างรวดเร็ว

เราไม่มีรหัสและไม่มีตัวอย่างคำนำหน้าหลายคำที่ไม่ใช่คำนำหน้าของสาขาทดสอบตามรหัส สิ่งที่เรามีคือ:

  • 089 - 100 => สาขาทดสอบ
  • 10B, 10C => สาขาทดสอบ
  • <088 => กิ่งจริงอาจ
  • > 100 => กิ่งจริงอาจ

ความจริงที่ว่ารหัสช่วยให้ตัวเลขและสตริงเป็นมากกว่าแปลกเล็กน้อย แน่นอนว่า 10B และ 10C สามารถพิจารณาได้ว่าเป็นเลขฐานสิบหก แต่หากคำนำหน้าทั้งหมดถือว่าเป็นเลขฐานสิบ 10B และ 10C จะอยู่นอกช่วงทดสอบและจะถือว่าเป็นสาขาจริง

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

bool IsTest(string strPrefix) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix))
        return iPrefix >= 89 && iPrefix <= 100;
    return true; //here is the problem
}

ในภาษาอังกฤษถ้าสตริงเป็นตัวเลขและอยู่ระหว่าง 89 และ 100 ก็คือการทดสอบ หากไม่ใช่ตัวเลขก็เป็นการทดสอบ มิฉะนั้นจะไม่ได้ทดสอบ

หากรหัสเป็นไปตามรูปแบบนี้จะไม่มีการทดสอบหน่วยใด ๆ ในตอนนี้ที่มีการนำรหัสไปใช้ นี่คือตัวอย่างการทดสอบหน่วย:

assert.isFalse(IsTest("088"))
assert.isTrue(IsTest("089"))
assert.isTrue(IsTest("095"))
assert.isTrue(IsTest("100"))
assert.isFalse(IsTest("101"))
assert.isTrue(IsTest("10B")) // <--- business rule change

การทดสอบหน่วยแสดงว่า "10B" ควรถือว่าเป็นสาขาทดสอบ User @ gnasher729 ด้านบนบอกว่ากฎทางธุรกิจเปลี่ยนไปและนั่นคือสิ่งที่การยืนยันครั้งสุดท้ายข้างต้นแสดงให้เห็น ในบางจุดที่ยืนยันควรเปลี่ยนเป็นisFalseแต่ไม่ได้เกิดขึ้น การทดสอบหน่วยเริ่มต้นที่การพัฒนา - และเวลาสร้าง แต่หลังจากนั้นไม่นาน


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

// Alternative A
bool TryGetIsTest(string strPrefix, out bool isTest) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix)) {
        isTest = iPrefix >= 89 && iPrefix <= 100;
        return true;
    }
    isTest = true; //this is just some value that won't be read
    return false;
}

สำหรับผู้ที่ไม่ทราบ C # ค่าส่งคืนจะระบุว่ารหัสนั้นสามารถแยกคำนำหน้าจากสตริงที่กำหนดหรือไม่ หากค่าส่งคืนเป็นจริงรหัสการโทรสามารถใช้ตัวแปร isTest out เพื่อตรวจสอบว่าคำนำหน้าสาขาเป็นคำนำหน้าทดสอบหรือไม่ หากค่าส่งคืนเป็นเท็จรหัสการโทรควรรายงานว่าไม่คาดว่าจะมีส่วนนำหน้าที่กำหนดไว้และตัวแปร isTest out ไม่มีความหมายและควรละเว้น

หากคุณมีข้อยกเว้นคุณสามารถทำได้ดังนี้:

// Alternative B
bool IsTest(string strPrefix) {
    int iPrefix = int.Parse(strPrefix);
    return iPrefix >= 89 && iPrefix <= 100;
}

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


1

คำตอบมากมายและไม่ใช่คำพูดของ Dijkstra แม้แต่คนเดียว:

การทดสอบแสดงให้เห็นว่าไม่มีแมลงอยู่หรือไม่

ดังนั้นมันขึ้นอยู่กับ หากรหัสได้รับการทดสอบอย่างถูกต้องมีโอกาสมากที่ข้อผิดพลาดนี้จะไม่มี


-1

ฉันคิดว่าการทดสอบหน่วยที่นี่จะทำให้มั่นใจได้ว่าปัญหาจะไม่เกิดขึ้นตั้งแต่แรก

พิจารณาคุณเขียนbool IsTestData(string branchCode)ฟังก์ชั่น

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

เพื่อให้การทดสอบทั้งหมดผ่านคุณจะต้องเพิ่มการตรวจสอบพารามิเตอร์ในฟังก์ชัน

แม้ว่าคุณจะทดสอบเฉพาะข้อมูลที่ 'ดี' 001 -> 999 ไม่ได้คิดเกี่ยวกับความเป็นไปได้ที่ 10A การตรวจสอบพารามิเตอร์จะบังคับให้คุณเขียนฟังก์ชันใหม่เมื่อคุณเริ่มใช้ตัวอักษรและตัวเลขเพื่อหลีกเลี่ยงข้อยกเว้นที่จะโยน


1
สิ่งนี้จะไม่ช่วยได้ - ฟังก์ชั่นไม่เปลี่ยนและการทดสอบจะไม่เริ่มล้มเหลวเนื่องจากข้อมูลการทดสอบเดียวกัน ใครบางคนจะต้องคิดเปลี่ยนการทดสอบเพื่อให้มันล้มเหลว แต่ถ้าพวกเขาคิดอย่างนั้นพวกเขาก็อาจจะคิดว่าการเปลี่ยนฟังก์ชั่นเช่นกัน
Hulk

(หรือบางทีฉันหายไปบางสิ่งบางอย่างที่ผมไม่แน่ใจว่าสิ่งที่คุณหมายถึง "การตรวจสอบพารามิเตอร์")
Hulk

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

แต่ฟังก์ชั่นจะไม่ใช้IsValidBranchCodeฟังก์ชั่นบางอย่างในการตรวจสอบนี้หรือไม่? และฟังก์ชั่นนี้อาจมีการเปลี่ยนแปลงโดยไม่จำเป็นต้องแก้ไขIsTestDataหรือไม่? ดังนั้นหากคุณทดสอบ 'ข้อมูลที่ดีเท่านั้น' การทดสอบจะไม่ช่วย การทดสอบเคสขอบจะต้องมีรหัสสาขาที่ถูกต้องในขณะนี้ (และไม่ใช่เพียงบางรหัสที่ยังไม่ถูกต้อง) เพื่อเริ่มการทำงานล้มเหลว
Hulk

1
หากการตรวจสอบอยู่ใน IsValidCode เพื่อให้ฟังก์ชั่นผ่านโดยไม่มีการตรวจสอบอย่างชัดเจนของตัวเองแล้วใช่มันเป็นไปได้ที่จะพลาด แต่แล้วเราจะมีชุดพิเศษของการทดสอบมากขึ้นเยาะเย้ยตัวตรวจสอบความถูกต้อง ฯลฯ หมายเลขทดสอบ "
Ewan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.