การทดสอบหน่วย - แอปคู่ฐานข้อมูล


15

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

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


1
ที่น่าสนใจว่าคำตอบที่มีประสิทธิภาพว่า "เขียนรหัสแอปของคุณใหม่" ได้รับการโหวต
AD7six

คำตอบ:


10

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

อย่าเชื่อมต่อกับฐานข้อมูลการผลิตเพื่อทำการทดสอบ!


1
ด้วย DI และการออกแบบแอปพลิเคชันที่เหมาะสมคุณควรทดสอบได้โดยไม่ต้องมีฐานข้อมูลใด ๆ - หากมีการเยาะเย้ยที่คุณฉีดให้การเยาะเย้ยอย่างละเอียดเพียงพอของฐานข้อมูลส่วนหลัง
Peter K.

4

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


2

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

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


1

ฉันมีปัญหาที่คล้ายกัน - ฉันไม่มีความเป็นไปได้ที่จะรับประกันฐานข้อมูลการทดสอบของฉันเก็บค่าไว้ ดังนั้นในอนาคตฉันจะได้รับเช่นราคาอื่น ๆ

ฉันดึงข้อมูลที่ฉันต้องการลงในsqlite -DB ขนาดเล็กและใช้ DB นี้สำหรับการทดสอบของฉัน ตอนนี้ Test-DB เป็นส่วนหนึ่งของการตั้งค่าการทดสอบหน่วยของฉัน


2
จุดทดสอบหน่วยคือการทดสอบรหัสของคุณในการแยก หากคุณใช้ dbllite db ก็จะไม่แยก ความไม่สอดคล้องกันระหว่างฐานข้อมูลอาจทำให้เกิดข้อผิดพลาด
Tom Squires

0

"ดีที่สุด" เป็นเรื่องส่วนตัว แต่คุณสามารถใช้การเชื่อมต่อทดสอบฐานข้อมูลได้

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


การอธิบายการทดสอบหน่วยที่ทดสอบฟังก์ชั่นซึ่งทำหน้าที่ในฐานข้อมูลเนื่องจากการทดสอบการรวมเป็นส่วนหนึ่งที่ทำให้เข้าใจผิด @murph
AD7six

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

0

ฉันสร้างปลั๊กอินสำหรับ Symfony 1.4 (PHP)เพื่อแก้ไขปัญหานี้ (อื่น ๆ ) มันถูกจำลองตามวิธีการทำงานของกรอบการทดสอบของ Django (Python) : เฟรมเวิร์กจะสร้างและเติมฐานข้อมูลการทดสอบแยกต่างหากก่อนที่การทดสอบแต่ละครั้งจะเริ่มขึ้นและจะทำลายฐานข้อมูลการทดสอบหลังจากการทดสอบแต่ละครั้งเสร็จสิ้น

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

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

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

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


0

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

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

ตัวอย่างเช่นแทนที่จะปล่อย SQL โดยตรงในโค้ดที่คุณต้องการมีวิธีเรียกใช้เมธอดที่ทำเฉพาะสิ่งที่ SQL ทำ ใช้สำหรับตัวอย่างเช่นแทนที่จะPerson.getPhoneNumber() SELECT phone_number FROM person WHERE id = <foo>ไม่เพียง แต่จะทำความสะอาดและเข้าใจได้ง่ายขึ้นเท่านั้น แต่ในระหว่างการทดสอบคุณสามารถเยาะเย้ยวัตถุบุคคลเพื่อที่getPhoneNumber()จะกลับมา555-555-5555หรือบางสิ่งบางอย่างแทนการสัมผัสฐานข้อมูล


0

มันค่อนข้างง่ายที่จะทำกับ Junit ถ้ายืดเยื้อมานาน

"การตั้งค่า" ควรกำหนดและเติมชุดของตารางชั่วคราว

จากนั้นคุณสามารถทำการทดสอบหน่วยสำหรับการอัพเดทแทรกการลบทั้งหมด

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

ในช่วง "teardown" คุณวางตารางทั้งหมด

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

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