วิธีการสร้างการทดสอบบูรณาการฟรีและปรับขนาดได้ผลข้างเคียง?


14

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

นี่คือการทดสอบการรวมทั่วไป (การทดสอบเหล่านี้แตะเลเยอร์ฐานข้อมูล):

public class OrderTests {

    List<Order> ordersToDelete = new ArrayList<Order>(); 

    public testOrderCreation() {
        Order order = new Order();
        assertTrue(order.save());
        orderToDelete.add(order);
    }

    public testOrderComparison() {
        Order order = new Order();
        Order order2 = new Order();
        assertFalse(order.isEqual(order2);
        orderToDelete.add(order);
        orderToDelete.add(order2);
    }
    // More tests

    public teardown() {
         for(Order order : ordersToDelete)
             order.delete();
    }
}

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

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

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

คำตอบ:


6

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

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

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


ฟังดูเหมือนความคิดที่ดี ฉันชอบความโดดเดี่ยวของมันโดยเฉพาะอย่างยิ่ง เริ่มต้นด้วยการติดตั้งฐานข้อมูลใหม่ ดูเหมือนว่าจะใช้ความพยายาม แต่เมื่อติดตั้งแล้วมันจะมีประโยชน์มาก ขอบคุณ
Guven

3

นี่เป็นปัญหานิรันดร์ที่ทุกคนเผชิญในขณะที่เขียนการทดสอบการรวม

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

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


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

3

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

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

คุณควรล้างฐานข้อมูลด้วยตนเองหลังจากการทดสอบทุกครั้งผ่านไลบรารีเช่นJPAUnitหรือคล้ายกับวิธีนี้ (ล้างตารางทั้งหมดโดยใช้ JDBC)

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

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


คำตอบที่ดี. จุดหนึ่ง: มันอาจเป็นที่ยอมรับได้ในการเยาะเย้ยการพึ่งพาภายนอกบางอย่าง (เช่นการส่งอีเมล) แต่คุณควรล้อเลียนด้วยการตั้งค่าบริการ / เซิร์ฟเวอร์จำลองที่สมบูรณ์ไม่ใช่จำลองในโค้ด Java
sleske

Sleske ฉันเห็นด้วยกับคุณ โดยเฉพาะอย่างยิ่งเมื่อคุณใช้ JPA, EJB, JMS หรือนำไปใช้กับข้อกำหนดอื่น คุณสามารถสลับแอพพลิเคชันเซิร์ฟเวอร์ผู้ให้บริการคงอยู่หรือฐานข้อมูล ตัวอย่างเช่นคุณอาจต้องการใช้ Glassfish แบบฝังและ HSQLDB เพื่อตั้งค่าและปรับปรุงความเร็ว (คุณมีอิสระที่จะเลือกการใช้งานที่ผ่านการรับรองอื่น)
BenR

2

เกี่ยวกับความยืดหยุ่น

ฉันเคยมีปัญหานี้มาแล้วก่อนหน้านี้ว่าการทดสอบการรวมใช้เวลานานเกินไปในการทำงานและไม่เหมาะสำหรับนักพัฒนาเดียวที่จะทำงานอย่างต่อเนื่องในวงตอบรับที่เปลี่ยนแปลง กลยุทธ์บางอย่างที่จะรับมือกับสิ่งนี้คือ:

  • เขียนการทดสอบการรวมน้อยลง - ถ้าคุณมีความครอบคลุมที่ดีกับการทดสอบหน่วยในระบบการทดสอบการรวมควรเน้นประเด็นการรวม (ahem) มากขึ้นเกี่ยวกับการทำงานของส่วนประกอบต่างๆ พวกมันคล้ายกับการทดสอบควันมากขึ้นซึ่งลองดูว่าระบบยังคงทำงานโดยรวมหรือไม่ ดังนั้นการทดสอบหน่วยของคุณจะครอบคลุมส่วนการทำงานส่วนใหญ่ของแอปพลิเคชันและการทดสอบการรวมเพียงตรวจสอบว่าชิ้นส่วนเหล่านั้นมีปฏิสัมพันธ์ซึ่งกันและกันอย่างไร คุณไม่ต้องการความครอบคลุมที่ครอบคลุมของเส้นทางตรรกะที่นี่เพียงบางเส้นทางที่สำคัญผ่านระบบ
  • เรียกใช้ชุดย่อยของการทดสอบในแต่ละครั้ง - ในฐานะผู้พัฒนารายเดียวที่ทำงานกับฟังก์ชั่นบางอย่างโดยปกติคุณมีความรู้สึกว่าการทดสอบใดที่จำเป็นสำหรับการใช้งานนั้น เรียกใช้การทดสอบเหล่านั้นที่เหมาะสมเพื่อครอบคลุมการเปลี่ยนแปลงของคุณ กรอบเช่น JUnit ช่วยให้คุณสามารถติดตั้งกลุ่มในหมวดหมู่นี้ สร้างการจัดกลุ่มที่ให้ความคุ้มครองที่ดีที่สุดสำหรับแต่ละคุณสมบัติที่คุณมี แน่นอนว่าคุณยังต้องการรันการทดสอบการรวมทั้งหมดในบางจุดก่อนที่จะยอมรับระบบควบคุมแหล่งที่มาและที่เซิร์ฟเวอร์การรวมอย่างต่อเนื่อง
  • เพิ่มประสิทธิภาพของระบบ - การทดสอบการรวมเข้ากับการทดสอบประสิทธิภาพอาจให้ข้อมูลที่จำเป็นในการปรับแต่งส่วนที่ช้าของระบบเพื่อให้การทดสอบจะทำงานได้เร็วขึ้นในภายหลัง สิ่งนี้อาจช่วยเปิดเผยดัชนีที่จำเป็นในฐานข้อมูลอินเตอร์เฟส chatty ระหว่างระบบย่อยหรือคอขวดของประสิทธิภาพการทำงานอื่นที่จำเป็นต้องกำหนดแอดเดรส
  • ทำการทดสอบแบบขนาน - หากคุณมีการจัดกลุ่มการทดสอบแบบฉากตั้งฉากที่ดีคุณสามารถลองทดสอบแบบขนานได้ ใส่ใจกับความต้องการมุมฉากที่ฉันพูดถึง แต่คุณไม่ต้องการให้การทดสอบของคุณก้าวไปสู่กัน

ลองรวมเทคนิคเหล่านี้เพื่อให้ได้ผลที่ดียิ่งขึ้น


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

2

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

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