การสร้างการทดสอบหน่วยบนชั้น CRUD ของแอปพลิเคชันฉันจะทำให้การทดสอบเป็นอิสระได้อย่างไร


14

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

สำหรับวิธีการเพิ่มฉันโดยทั่วไปต้องสร้างวัตถุจำลองและเพิ่มจากนั้นหลังจากการทดสอบสำเร็จฉันต้องลบวัตถุจำลอง

และสำหรับการทดสอบการลบฉันต้องสร้างวัตถุจำลองเพื่อที่จะสามารถลบได้

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

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

กรณีเช่นนี้หมายถึงการจัดการอย่างไร


คุณอาจต้องการดูคำถามนี้: programmers.stackexchange.com/questions/115455/…
Guven

คำตอบ:


13

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

วิธีที่ยอดเยี่ยมในการทำเช่นนั้นคือการทดสอบกับฐานข้อมูลในหน่วยความจำ

ในการทดสอบเพิ่มของคุณสร้างฐานข้อมูลเปล่าเพิ่มวัตถุและยืนยันว่ามันได้รับการเพิ่มแน่นอน

ในการทดสอบการลบของคุณสร้างฐานข้อมูลด้วยวัตถุที่คุณจะลบแล้วในมัน ลบวัตถุและยืนยันว่าถูกลบแล้ว

ระเบิดฐานข้อมูลในรหัสการฉีกขาดของคุณ


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

3

ใช้การทำธุรกรรม

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

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


รักความคิดนี้ ใช้งานได้อย่างยอดเยี่ยมในวันนี้
pimbrouwers

3

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


2

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

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

  • การทดสอบแต่ละรายการควรเป็นแบบแยกอิสระและไม่ได้รับผลกระทบจากการทดสอบอื่น ๆ
  • การทดสอบแต่ละหน่วยควรทดสอบสิ่งหนึ่งและสิ่งเดียวเท่านั้น
  • การทดสอบหน่วยไม่ควรโดนฐานข้อมูล

และอื่น ๆ และทุกคนมีสิทธิขึ้นอยู่กับว่าคุณกำหนดหน่วยทดสอบ '

ฉันจะกำหนด 'การทดสอบหน่วย' เป็นดังนี้: "การทดสอบที่ฝึกการทำงานหนึ่งส่วนสำหรับโค้ดหนึ่งหน่วยแยกจากส่วนประกอบที่ต้องพึ่งพาอื่น ๆ "

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

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

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

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


คุณกำลังบอกว่าคุณไม่สามารถทดสอบการลบหน่วยจากฐานข้อมูลหรือไม่
ChrisF

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

แต่ประเด็นก็คือบางคนอาจนิยาม 'การทดสอบหน่วย' แตกต่างกันดังนั้นเราต้องระวังเมื่อใช้คำแนะนำ 'การทดสอบหน่วย' เนื่องจากคำแนะนำอาจใช้ไม่ได้ในวิธีที่เราคิด
Eric King

1

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

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


1

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

ดังนั้น?

... สิ่งนี้ไม่ขัดกับแนวทางการทดสอบหน่วยใช่หรือไม่

เลขที่

กรณีเช่นนี้หมายถึงการจัดการอย่างไร

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

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


1

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

ฉันชอบอันสุดท้าย - ผู้ใช้สามารถช่วยคุณป้อนข้อมูลเพื่อให้การทดสอบของคุณใกล้เคียงกับโลกแห่งความเป็นจริงมากขึ้น


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