แนวปฏิบัติที่ดีที่สุดสำหรับการทดสอบหน่วยใน Magento 1.9


11

ฉันบำรุงรักษาเว็บไซต์ Magento 1.9 ด้วยโมดูลที่กำหนดเองหลายอย่าง ฟังก์ชั่นบางอย่างมีความสำคัญอย่างยิ่งสำหรับธุรกิจและจำเป็นต้องทดสอบหน่วย เช่นเครื่องคิดเลขราคาต่อหน่วย

ฉันมักจะพัฒนาใน Symfony และต้องการใช้ PHPUnit (w / นักแต่งเพลง) อย่างแท้จริงถ้าเป็นไปได้

ฟังก์ชั่นบางอย่างขึ้นอยู่กับข้อมูลที่นำเข้าไปยังตารางฐานข้อมูลที่กำหนดเองหลาย ๆ ตัวดังนั้นฉันจึงต้องการโหลดตัวโหลดอย่างใด

ดังนั้นฉันกำลังมองหาวิธีปฏิบัติที่ดีที่สุดในการเขียนแบบทดสอบหน่วย ฉันจะ Glady ยอมรับบทเรียนหรือสิ่งที่คล้ายกัน ความช่วยเหลือใด ๆ ที่ชื่นชม

คำตอบ:


10

ฉันต้องเผชิญกับปัญหาเดียวกันในขณะที่กลับ

ฉันพิจารณาการใช้โมดูล Ecomdev PHPUnitแต่ฉันพบว่ามันใช้งานยากและมีเอกสารไม่ดี (แต่ฉันก็ยังรักสิ่งที่ Ivan ทำและสนับสนุนระบบนิเวศของ Magento อย่างยอดเยี่ยม)

ดังนั้นด้วยความช่วยเหลือของ Vinai ฉันจึงพัฒนาโมดูลเฟรมเวิร์กการทดสอบต่อไปนี้: https://github.com/digitalpianism/testframework

จุดประสงค์ดั้งเดิมมีไว้สำหรับการทดสอบการรวมระบบ แต่ฉันใช้เพื่อการทดสอบหน่วยด้วย คุณสามารถดูได้ที่นี่: https://github.com/digitalpianism/easytoplinks/blob/master/app/code/community/DigitalPianism/EasyToplinks/Test/Unit/Block/Page/Template/LinksTest.php

เกี่ยวกับการแข่งขันฉันใช้การย้อนกลับธุรกรรมเพื่อหลีกเลี่ยงการสร้างข้อมูลตัวอย่างในฐานข้อมูล


มันดูมีแนวโน้มมาก ฉันจะลองดู ขอบคุณ
frigg

13

การติดตั้ง

เนื่องจาก Magento 1 ไม่ได้ใช้นักแต่งเพลงนอกกรอบฉันไม่คิดว่ามันจะสร้างความแตกต่างอย่างมากหากคุณติดตั้ง phpunit โดยใช้นักแต่งเพลงหรือเพียงแค่ดาวน์โหลดเวอร์ชั่นphar
หากคุณใช้นักแต่งเพลงเพื่อจัดการโมดูลหรือไลบรารีบุคคลที่สามอื่น ๆ ในไซต์ของคุณอยู่แล้วผู้เรียบเรียงอาจเหมาะสมที่สุด ยกเว้นว่าคุณใช้ PHP7 คุณจะถูก จำกัด phpunit เวอร์ชันเก่า (นั่นคือเหตุผลที่ฉันเชื่อมโยงกับเวอร์ชั่น 4.8 ด้านบน)

การทดสอบการรวมกับ / / และ / หรือการทดสอบหน่วย

เนื่องจาก Magento 1 นั้นเป็นแอพพลิเคชั่นที่มีน้ำหนักมากมันจึงเป็นเรื่องเหมาะสมที่จะแยก phpunit bootstrap ให้เป็นหนึ่งสำหรับการรวมเข้าด้วยกันและอีกอันสำหรับการทดสอบหน่วย
bootstrap ทดสอบหน่วยจะต้องเริ่มต้น autoloader เท่านั้นในขณะที่ bootstrap ทดสอบรวมจะต้องเริ่มต้นสภาพแวดล้อมของแอปพลิเคชันทั้งหมดรวมถึงการโหลดการกำหนดค่าและการเชื่อมต่อ db
เนื่องจากการทดสอบการรวมใน Magento มีแนวโน้มที่จะทำงานช้าลงมากจากนั้นทำการทดสอบหน่วย (ยิ่งไปกว่านั้นในการใช้งานอื่น ๆ )

Bootstrapping Magento สู่ phpunit

  • Autoloader ของ Magento ไม่เข้ากันได้กับ PSR-0 เนื่องจากมันมีข้อยกเว้นหากไม่สามารถหาไฟล์ที่มี class อยู่ในนั้นสิ่งนี้จะเป็นการแบ่งประเพณีของclass_existsphpunit มีวิธีแก้ปัญหาที่เป็นไปได้หลายอย่าง (ถ้าแฮ็ก):

    • ยกเลิกการลงทะเบียนตัวโหลดอัตโนมัติของวีโอไอพีโดยห่อ\Varien_Autoload::autoload()ในมัณฑนากรโดยไม่สนใจข้อยกเว้นที่อยู่ภายในและลงทะเบียนตัวห่อหุ้มเป็นออโต้โหลดใหม่ สิ่งนี้มีโอกาสน้อยที่จะเกิดข้อขัดแย้งกับห้องสมุดบุคคลที่สามซึ่งลงทะเบียนออโต้โหลดและขึ้นอยู่กับคำสั่งออโต้โหลดที่เฉพาะเจาะจง
    • ใช้ตัวจัดการข้อผิดพลาดที่กำหนดเองซึ่งรวมอยู่ใน Magento 1 ตัวจัดการข้อผิดพลาดที่กำหนดเองจะกลืนข้อผิดพลาดที่เกิดจากระบบอัตโนมัติของ Magento นี่คือวิธีการแก้ปัญหาว่าราฟาเอลของการใช้กรอบทดสอบ ดูเหมือนว่าจะเข้ากันได้กับส่วนขยายอื่น ๆ ของบุคคลที่สามมากที่สุด
    • ใช้การรวมเส้นทางแฮ็กเพื่อแทนที่\Varien_Autoload::autoload()เพื่อไม่ให้เกิดข้อผิดพลาดหากไฟล์ไม่มีอยู่ อย่างไรก็ตามสิ่งนี้ขัดแย้งกับหลายโมดูลที่แทนที่คลาสเดียวกัน ฉันไม่ได้ใช้วิธีการนี้ด้วยตนเอง
  • เพื่อหลีกเลี่ยงข้อผิดพลาดจากเซสชันที่กำลังเริ่มต้นในระหว่างการทดสอบเพียงแค่ตั้งค่า$_SESSON = []ใน bootstrap

  • ตั้งค่าวัตถุการตอบสนองที่กำหนดเองผ่านทางMage::app()->setResponse($testResponse)ที่ขยายจริง แต่ไม่ส่งออกหรือส่วนหัว

  • Mage::reset(); Mage::app()เพื่อเตรียมใช้งานใหม่วีโอไอพีระหว่างการทดสอบการรวมที่สมบูรณ์เปลี่ยนสถานะรันไทม์ใช้ โปรดทราบว่าหลังจากนั้นตัวจัดการข้อผิดพลาดจะต้องได้รับการตกแต่งใหม่

การแข่งขัน

สำหรับการติดตั้ง DB createSimpleProduct($sku)ฉันมักจะใช้รูปแบบปกติในวิธีการติดตั้งเพื่อสร้างการแข่งขันเช่น เช่นเดียวกับ Raphael ที่กล่าวว่าใช้setUp()และtearDown()ห่อการทดสอบในธุรกรรมที่ย้อนกลับหลังการทดสอบ (ตัวอย่างMage::getSingleton('core/resource')->getConnection('default_setup')->beginTransaction())

สำหรับการกำหนดค่าการติดตั้งร้านค้าฉันมักจะตั้งค่าการติดตั้งในหน่วยความจำโดยใช้Mage::app()->getStore()->setConfig($path, $value)เท่านั้น

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

ทดสอบสองเท่า

สตรีที่สามารถใช้ในการฉีดคู่ทดสอบสำหรับวัตถุที่สร้างขึ้นผ่านทางMage::getSingleton(), และMage::getResourceSingleton() สามารถตั้งค่าวัตถุกลางอื่น ๆ ได้(เช่นคำขอ) ในการแทนที่คลาสที่สร้างผ่านหรือด้วยการทดสอบเป็นสองเท่าจะต้องใช้wrapperการกำหนดค่าวัตถุแบบกำหนดเอง ดูตัวอย่างนี้ในกรอบการทดสอบของราฟาเอลว่าทำได้อย่างไร Mage::helper()
Mage::app()
Mage::getModel()Mage::getResourceModel()

สรุป

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


ฉันไม่เคยลองเลย แต่ทำไมไม่ลองใช้ Magento Test Framework? ( docs.magento.com/m1/ce/user_guide/magento/... )
รา

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

@Vinai ฉันรู้ว่ามันสาย แต่โดยทั่วไปแล้วในคอนโทรลเลอร์มีการโทรไปยังโมเดลและคอลเล็กชันซึ่งในขณะที่การทดสอบเราไม่ต้องการ ฉันใช้เฟรมเวิร์กทดสอบของคุณ (DigitalPianism) และที่นั่นเราสามารถ TestDouble โมเดล แต่ในขณะที่ทำการร้องขอรับการดำเนินการควบคุมซึ่งในทางกลับกันใช้โมเดลฉันจะจำลองการโทร / การรวบรวมรุ่นนั้นได้อย่างไร
arqam
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.