เมื่อเขียนการทดสอบหน่วย อย่าใช้การเยาะเย้ย

เผยแพร่แล้ว: 2018-05-02

หมายเหตุ: นี่เป็นโพสต์ด้านเทคนิคล่าสุดของเราที่เขียนโดยวิศวกรหลัก Seth Ammons ขอขอบคุณเป็นพิเศษกับ Sam Nguyen, Kane Kim, Elmer Thomas และ Kevin Gillette สำหรับการทบทวนโพสต์ นี้ และ หากโพสต์ในลักษณะนี้ โปรดดูบล็อกทางเทคนิคของเรา

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

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

มาดูคำจำกัดความบนโต๊ะกัน

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

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

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

ระบุสั้นกว่านี้เล็กน้อย: เยาะเย้ยยืนยันพฤติกรรมเช่น:

MyMock.Method("foo")).Called(1).WithArgs("bar")).Returns("raz") เรียก

ฉันสนับสนุน "ของปลอมมากกว่าการเยาะเย้ย"

ของปลอมเป็นการทดสอบแบบทวีคูณที่อาจมีพฤติกรรมทางธุรกิจ [2] ของปลอมเป็นเพียงโครงสร้างที่พอดีกับอินเทอร์เฟซและเป็นรูปแบบของการฉีดพึ่งพาที่เราควบคุมพฤติกรรม ประโยชน์หลักของของปลอมคือ พวกมันลด coupling ในโค้ด โดยที่ mocks จะเพิ่ม coupling และ coupling ทำให้ refactoring ยากขึ้น [3]

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

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

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

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

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

Naive Approach: แค่เรียกไลบรารี่และระดับระบบ

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

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

เราจำเป็นต้องจัดเตรียมฟังก์ชันพื้นฐานบางอย่าง ตรวจสอบรหัสไร้เดียงสาที่นี่ [4]; ด้านล่างเป็นรุ่นที่ลดลง หมายเหตุ นี่เป็นตัวอย่างที่ยังไม่เสร็จสิ้น และเรากำลังจะทำการปรับโครงสร้างสิ่งต่างๆ

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

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

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

เราจะทำให้รหัสนี้สามารถทดสอบหน่วยได้มากขึ้นได้อย่างไร มีสองโรงเรียนของความคิด หนึ่งคือการใช้ตัวสร้างแบบจำลอง (เช่น https://github.com/vektra/mockery หรือ https://github.com/golang/mock) ที่สร้างรหัสสำเร็จรูปสำหรับใช้เมื่อทำการทดสอบการเยาะเย้ย

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

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

วิธีการเชื่อมต่อ: นามธรรมที่มากขึ้น การทดสอบที่ง่ายขึ้น

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

พวกเขาอาจเห็นว่าเรามีไคลเอนต์ Minio ดังนั้นพวกเขาจึงอาจเริ่มต้นด้วยการสร้างอินเทอร์เฟซที่ตรงกับวิธีการและการใช้งานทั้งหมดของไคลเอนต์ Minio (หรือไคลเอนต์ s3) พวกเขาลืม Go Proverb [5] [6] ของ "ยิ่งอินเทอร์เฟซยิ่งใหญ่เท่าไหร่ สิ่งที่เป็นนามธรรมยิ่งอ่อนแอ"

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

เมื่อนำสิ่งที่เป็นนามธรรมเหล่านี้มาใช้แล้ว เราสามารถปรับโครงสร้างการนำไปใช้ครั้งแรกของเราได้ เราจะใส่ localFetcher และ remoteFetcher ลงใน Getter struct และรีแฟคเตอร์ GetFile เพื่อใช้งาน ตรวจสอบโค้ด refactored เวอร์ชันเต็มได้ที่นี่ [7] ด้านล่างนี้เป็นข้อมูลโค้ดที่เข้าใจง่ายขึ้นเล็กน้อยโดยใช้อินเทอร์เฟซเวอร์ชันใหม่:

โค้ดที่ปรับโครงสร้างใหม่นี้สามารถทดสอบได้ต่อยูนิตมากขึ้น เนื่องจากเราใช้อินเทอร์เฟซเป็นพารามิเตอร์บนโครงสร้าง Getter และเราสามารถเปลี่ยนประเภทที่เป็นรูปธรรมสำหรับของปลอมได้ แทนที่จะเยาะเย้ยการเรียก OS หรือต้องการการเยาะเย้ยไคลเอนต์ Minio หรืออินเทอร์เฟซขนาดใหญ่ เราแค่ต้องการของปลอมง่ายๆ สองอย่าง: fakeLocalFetcher และ fakeRemoteFetcher

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

เมื่อคำนึงถึงสิ่งนี้ หัวใจของการทดสอบจะกลายเป็น:

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

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

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

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

การเยาะเย้ย: แล้วรายละเอียดการใช้งานที่ละเอียดอ่อนและมีไหวพริบล่ะ?

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

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

คำพูดที่ยอดเยี่ยมที่ฉันเพิ่งอ่านกล่าวว่า "การเยาะเย้ยทำให้เกิดสมมติฐาน ซึ่งทำให้เกิดความเสี่ยง [10] คุณกำลังสมมติว่าไลบรารีของไคลเอ็นต์ได้รับการติดตั้งอย่างถูกต้อง คุณกำลังสมมติว่าขอบเขตทั้งหมดแน่นหนา คุณกำลังสมมติว่าคุณรู้ว่าไลบรารีมีพฤติกรรมอย่างไร

การเยาะเย้ยห้องสมุดเป็นเพียงการล้อเลียนสมมติฐานและทำให้การทดสอบของคุณเปราะบางและอาจเปลี่ยนแปลงได้เมื่อคุณอัปเดตโค้ด (ซึ่งเป็นสิ่งที่มาร์ติน ฟาวเลอร์สรุปไว้ใน Mocks Aren't Stubs [3]) เมื่อยางมาบรรจบกับท้องถนน เราจะต้องตรวจสอบว่าเราใช้ไคลเอ็นต์ Minio อย่างถูกต้องหรือไม่ ซึ่งหมายถึงการทดสอบการรวมระบบ (สิ่งเหล่านี้อาจอยู่ในการตั้งค่า Docker หรือสภาพแวดล้อมการทดสอบ) เนื่องจากเราจะมีทั้งการทดสอบหน่วยและการทดสอบการรวม ไม่จำเป็นต้องมีการทดสอบหน่วยเพื่อให้ครอบคลุมการใช้งานที่แน่นอน เนื่องจากการทดสอบการรวมจะครอบคลุมถึงนั้น

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

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

myClientMock.ExpectsCall("GetObject")).Returns(mockObject).NumberOfCalls(1).WithArgs(key, bucket) – และนั่นคือถ้าคุณสามารถเรียกคืนคาถาที่ถูกต้องสำหรับ DSL เฉพาะนี้

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

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

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

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

อินเทอร์เฟซ: ความเรียบง่ายและการทดสอบหน่วยสำหรับ win

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

ฉันหวังว่าจะได้รับโพสต์เกี่ยวกับวิธีการรันการทดสอบการรวมในอนาคต คอยติดตาม!

อ้างอิง

1: Endo-Testing: การทดสอบหน่วยด้วย Mock Objects (2000): ดูคำแนะนำสำหรับคำจำกัดความของวัตถุจำลอง
2: The Little Mocker: ดูส่วนที่เป็นของปลอม โดยเฉพาะ “ของปลอมมีพฤติกรรมทางธุรกิจ คุณสามารถขับของปลอมให้มีพฤติกรรมต่างกันโดยให้ข้อมูลที่แตกต่างกัน”
3: เยาะเย้ยไม่ใช่สตับ: ดูหัวข้อ "ฉันควรเป็นนักคลาสสิกหรือนักเยาะเย้ย" มาร์ติน ฟาวเลอร์กล่าวว่า “ฉันไม่เห็นประโยชน์ใด ๆ ที่น่าสนใจสำหรับ TDD เยาะเย้ย และกังวลเกี่ยวกับผลที่ตามมาของการทดสอบการประกบกับการใช้งาน”
4: Naive Approach: โค้ดเวอร์ชันที่เรียบง่าย ดู [7].
5: https://go-proverbs.github.io/: รายการ Go Proverbs พร้อมลิงก์พูดคุย
6: https://www.youtube.com/watch?v=PAAkCSZUG1c&t=5m17s: ลิงก์โดยตรงเพื่อพูดคุยโดย Rob Pike เกี่ยวกับขนาดอินเทอร์เฟซและสิ่งที่เป็นนามธรรม
7: โค้ดสาธิตเวอร์ชันเต็ม: คุณสามารถโคลน repo และเรียกใช้ 'go test'
8: การทดสอบตามตาราง: กลยุทธ์การทดสอบสำหรับการจัดระเบียบรหัสทดสอบเพื่อลดความซ้ำซ้อน
9: ทดสอบเวอร์ชันเต็มของโค้ดสาธิต คุณสามารถเรียกใช้ได้ด้วย `ไปทดสอบ'
10: คำถามที่ถามตัวเองเมื่อเขียนการทดสอบโดย Michal Charemza: การเยาะเย้ยทำให้เกิดสมมติฐานและสมมติฐานก่อให้เกิดความเสี่ยง