การตรวจสอบการโทร TDD จำลอง - มันเป็นรูปแบบต่อต้านหรือไม่?


11

ฉันทำ TDD มาหลายปีแล้วตอนนี้ฉันรู้สึกดีกับมันมากฉันชอบห้องทดสอบและทุกอย่าง อย่างไรก็ตามฉันสังเกตเห็นว่าเมื่อเร็ว ๆ นี้ฉันได้ทำการตรวจสอบการโทรจำลองจำนวนมาก ตัวอย่างเช่นฉันมีบริการที่จะมีพื้นที่เก็บข้อมูลที่ฉีด - ในการทดสอบหน่วยของฉันฉันจะผ่านการจำลองของพื้นที่เก็บข้อมูลและตรวจสอบว่ามันถูกเรียกว่าภายในวิธีการที่ฉันกำลังทดสอบ จากนั้นฉันจะตรวจสอบว่าผลลัพธ์ที่ส่งคืนนั้นถูกต้อง (ในการทดสอบอื่น) สิ่งนี้ "รู้สึก" ผิดเนื่องจากการทดสอบหน่วยของฉันตอนนี้ควบคู่ไปกับรายละเอียดการใช้งานมาก ฉันได้ยินมาว่าคุณควรทดสอบ "พฤติกรรม" อย่างไรก็ตามในหลาย ๆ สถานการณ์นั่นคือ ... emm - เป็นไปไม่ได้เหรอ? หากคุณมีvoidตัวอย่างเช่นคุณมักจะทดสอบผลข้างเคียง ฉันหมายความว่ามันเป็นเรื่องง่ายที่จะไปข้างหน้าและแสดงรหัสง่ายๆของกะตะซึ่งสามารถแสดงให้เห็นได้ แต่ IMHO มันไม่ได้สะท้อนถึงโปรแกรมโลกที่เราเขียนได้ดีนัก ฉันทำผิดหรือเปล่า? การทดสอบประเภทนี้เป็นรูปแบบการต่อต้านหรือไม่ ฉันขอขอบคุณความคิดเห็นของคุณเกี่ยวกับเรื่องนี้ฉันยังคงเป็นมือใหม่เมื่อพูดถึง TDD


2
คำตอบสั้น ๆ : ใช่ มีคำถามที่น่าสนใจเกี่ยวกับหัวข้อนี้อยู่ที่ไหนสักแห่งที่นี่แล้ว การทดสอบหน่วยของคุณไม่ควรแตกหักง่ายและขึ้นอยู่กับการใช้งานของคุณเป็นอย่างมาก นี่คือเหตุผลที่การทดสอบในระดับที่สูงขึ้นสำหรับ (รวม ฯลฯ ) ที่นี่: programmers.stackexchange.com/questions/198453/…
Kemoda

@Kemoda ฉันขอขอบคุณถ้าคุณสามารถเชื่อมโยงฉันเข้ากับการสนทนาหรือเนื้อหาเพิ่มเติมเกี่ยวกับเรื่องนี้ฉันอยากจะปรับปรุงเทคนิคของฉัน
Dimitar Dimitrov

1
คุณมีสิ่งนี้เช่นprogrammers.stackexchange.com/questions/198453/ …ฉันจะหาลิงค์อื่น ๆ ภายหลัง
Kemoda

คำตอบ:


8

คุณควรลองทดสอบอินพุตและเอาต์พุต คุณควรตรวจสอบพฤติกรรมที่มองเห็นจากภายนอก "สัญญา" หรือ "สัญญา" ที่ชั้นเรียนของคุณทำ

ในขณะเดียวกันบางครั้งก็ไม่มีวิธีที่ดีกว่าในการทดสอบวิธีที่จะทำตามที่คุณพูด

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


2

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

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

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


"แต่ถ้าใช้งานจริงในการทดสอบมีราคาแพง (เช่นเพราะพวกเขาต้องการทรัพยากรที่ซับซ้อนในการตั้งค่า) ฉันต้องใช้ mocks ในกรณีนี้ใช่ไหม"

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

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


1
ฉันเห็นสิ่งที่คุณพูด หัวข้อนี้ค่อนข้างสับสนว่า "การทดสอบเป็นการทดสอบที่มากเกินไป" สมมุติว่าฉันมี "บริการรวม" ซึ่งโดยทั่วไปเป็นส่วนหน้าและเพียงแค่ "กาว" รวมบริการ / คลังเก็บ / ส่วนประกอบอื่น ๆ เข้าด้วยกัน คุณเขียนมันหรือไม่ ทั้งหมดที่ฉันคิดได้ก็คือการยืนยันการโทร ฉันหวังว่าฉันจะทำให้รู้สึก
Dimitar Dimitrov

2

ความคิดของฉันเป็น: 'บริการรวม'

การยืนยันการโทรจะทำเช่นนี้ แต่จะไม่ให้คุณค่ามากนัก คุณแค่ตรวจสอบสายไฟของคุณ

มี 3 วิธีที่ไม่เฉพาะเจาะจงวิธีนี้:

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

  2. ใช้การสร้างรหัสเพื่อสร้างบริการโดยตรงจากบริการที่รวบรวม

  3. ใช้การไตร่ตรองหรือภาษาแบบไดนามิกเพื่อทำสิ่งเดียวกัน ตัวอย่างเช่นใน Java อาจเป็นไปได้ที่จะใช้อินเทอร์เฟซแบบ Groovy ซึ่งส่งผ่านการโทรโดยตรง

อาจมีวิธีอื่นในการทำเช่นนี้ แต่เพียงแค่ตรวจสอบการเดินสายมีการจ่ายคืนที่ต่ำมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.