แบบจำลองแหล่งที่มาของการทดสอบหน่วย


10

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

<?php
namespace Sample\News\Model\Author\Source;

use Magento\Framework\Option\ArrayInterface;

class Type implements ArrayInterface
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;

    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        $_options = [
            [
                'value' => '',
                'label' => ''
            ],
            [
                'value' => self::COLLABORATOR,
                'label' => __('Collaborator')
            ],
            [
                'value' => self::EMPLOYEE,
                'label' => __('Employee')
            ],
        ];
        return $_options;
    }

    /**
     * get options as key value pair
     *
     * @return array
     */
    public function getOptions()
    {
        $_tmpOptions = $this->toOptionArray();
        $_options = [];
        foreach ($_tmpOptions as $option) {
            $_options[$option['value']] = $option['label'];
        }
        return $_options;
    }
}

คำตอบ:


15

นี่เป็นหัวข้อที่ยอดเยี่ยมและฉันชอบทั้งคำตอบจาก @KAndy และ @fschmengler
ฉันต้องการเพิ่มความคิดเพิ่มเติมที่ฉันพบว่ามีค่าเมื่อถามคำถามเช่น "ฉันควรทดสอบ X หรือไม่" หรือ "ฉันจะทดสอบ X ได้อย่างไร"

มีอะไรผิดพลาด?

  • ฉันสามารถพิมพ์ผิดโง่ (เกิดขึ้นตลอดเวลา)
    นี้มักจะไม่ปรับการเขียนการทดสอบ
  • ฉันจะคัดลอกรหัสที่ฉันต้องการจากคอร์หรือโมดูลอื่นแล้วปรับมันตามความต้องการของฉันได้หรือไม่?
    ฉันพบว่าสิ่งนี้เป็นสิ่งที่อันตรายมากที่มักทำอย่างนั้นให้แมลงตัวเล็ก ๆ ในกรณีนี้ฉันชอบเขียนแบบทดสอบถ้ามันไม่แพงเกินไป การทำให้การกำหนดค่าโมเดลต้นทางนั้นเป็นจริงจะทำให้ IMO มีความเสี่ยงมากขึ้น
  • จะมีข้อขัดแย้งกับโมดูลอื่นได้หรือไม่?
    เกือบจะใช้กับรหัสการกำหนดค่าเท่านั้น ในกรณีเช่นนี้ฉันต้องการทดสอบการรวมระบบที่บอกฉันว่าเกิดอะไรขึ้น
  • Magento เปลี่ยน API ในการเปิดตัวในอนาคตหรือไม่?
    ในกรณีนี้ไม่น่าเป็นไปได้มากเนื่องจากรหัสของคุณขึ้นอยู่กับส่วนต่อประสานเท่านั้น แต่ยิ่งมีชั้นเรียนที่เป็นรูปธรรมมากขึ้นหรือถ้ารหัสของฉันขยายคลาสหลักสิ่งนี้จะกลายเป็นความเสี่ยงที่อาจเกิดขึ้น
  • PHP เวอร์ชันใหม่อาจทำลายรหัสของฉันได้ หรือบางทีฉันต้องการสนับสนุน PHP 5.6 สำหรับปีต่อ ๆ ไป
    อีกครั้งไม่น่าเป็นไปได้สูงที่นี่ แต่ในบางกรณีฉันต้องการทดสอบเพื่อเตือนฉันฉันควรเปลี่ยนรหัสในอนาคตเพื่อใช้ไวยากรณ์ที่เข้ากันไม่ได้

การทดสอบรหัสมีราคาแพงแค่ไหน

นี่มีสองด้าน:

  • ระยะเวลาและความพยายามในการเขียนการทดสอบ
  • จำนวนความพยายามและเวลาที่ใช้ในการทดสอบชิ้นส่วนของรหัสที่ฉันจะเขียนด้วยตนเอง

ในระหว่างการพัฒนาโค้ดบางส่วนฉันมักจะต้องรันโค้ดที่ฉันเขียนบ่อยๆจนกว่าฉันจะพิจารณาเสร็จ หลักสูตรนี้ง่ายกว่ามากเมื่อใช้การทดสอบหน่วย

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

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

รหัสที่ฉันเขียนมีค่าขนาดไหน

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

รหัสจะต้องเปลี่ยนหรือไม่

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

มันต้องการเอกสารประกอบไหม?

การใช้รหัสยากแค่ไหน? ในตัวอย่างของคุณมันไม่สำคัญ แต่ในบางกรณีที่ซับซ้อนมากขึ้นการทดสอบนั้นดีมากสำหรับวัตถุประสงค์ด้านเอกสารสำหรับนักพัฒนาอื่น ๆ (หรือตัวฉันเองในอีกไม่กี่เดือน)

การสำรวจและการเรียนรู้

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

วินัยและความเครียด

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

จะทดสอบอะไรและอย่างไร

พิจารณาว่าคุณสามารถเขียนการทดสอบด้วยความละเอียดที่แตกต่างกันมาก

  • ทดสอบค่าส่งคืนที่แน่นอน
    นี่จะเป็นการทดสอบที่เข้มงวดมากซึ่งจะต้องมีการปรับเปลี่ยนทุกครั้ง คุณต้องการให้การทดสอบแตกตัวอย่างเช่นถ้าลำดับของรายการในอาร์เรย์ส่งคืนมีการเปลี่ยนแปลงหรือไม่?
  • ทดสอบโครงสร้างของค่าส่งคืน
    สำหรับโมเดลต้นทางสิ่งนี้สามารถตรวจสอบแต่ละอาร์เรย์ย่อยเป็นสองเรคคอร์ดหนึ่งรายการที่มีlabelและอีกหนึ่งรายการมีvalueคีย์
  • ArrayInterfaceการตรวจสอบการดำเนินการในชั้นเรียน
  • การทดสอบคลาสให้getOptions()แม้ว่าวิธีนั้นจะไม่ได้เป็นส่วนหนึ่งของอินเตอร์เฟสที่ใช้งาน

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

สรุป

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


2
คำตอบที่ดี! ฉันต้องการให้ส่วน "ลบการทดสอบเมื่อพวกเขาไม่ให้คุณค่าอีกต่อไป" - บางครั้งการทดสอบแบบเก่าที่ช่วยในระหว่างการเริ่มต้นการพัฒนากำลังได้รับในระยะยาว
Fabian Schmengler

1
คุณเพิ่งตอบคำถามอื่นอีก 2 คำถามที่ฉันสงสัย ขอบคุณ
Marius

6

ในความคิดของฉันไม่มีคำตอบทั่วไปในการ "เขียนการทดสอบหน่วยสำหรับแบบจำลองแหล่งที่มาใช่หรือไม่"

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

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

  1. ทดสอบหน่วย
  2. การทดสอบบูรณาการ
  3. ดูการกำหนดค่าด้วยตนเอง

คุณกำลังติดตาม TDD หรือไม่ จากนั้นเลือกระหว่าง (1) และ (2) หรือทั้งสองอย่าง มิฉะนั้นเลือกระหว่าง (2) และ (3)


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


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

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


ด้วยคลาสฐานดังกล่าวโมเดลต้นทางของคุณอาจมีลักษณะเช่นนี้:

class Type extends ArraySource
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;
    protected $elements = [
        self::COLLABORATOR => 'Collaborator',
        self::EMPLOYEE     => 'Employee',
    ];
    protected $withEmpty = true;
    protected $translate = true;
}

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

ฉันไม่เห็นว่ารูปแบบแหล่งที่มา "สถานะ" จะแตกต่างจากตัวอย่าง "ประเภทผู้แต่ง" ของคุณอย่างไร
Fabian Schmengler

เพราะฉันอาจใช้ค่า 0 และ 1 (เป็นค่าคงที่คลาส) บนส่วนหน้าเพื่อกรองตัวอย่างเอนทิตีที่เปิดใช้งาน ฉันหมายถึงในกรณีนี้ค่าตัวเลือกมีตรรกะอยู่เบื้องหลัง พวกเขาไม่ได้เป็นเพียงแค่key=>valueคู่
Marius

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

5

ฉันจะทดสอบหน่วยเหล่านั้นได้อย่างไร

ฉันคิดว่าคุณไม่ควร

เพิ่มรหัสที่ให้การสนับสนุนระบบเพิ่มขึ้นและค่าใช้จ่ายในการบำรุงรักษา แต่กระบวนการทดสอบควรจะLEAN

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


1
ขอบคุณ ดังนั้นคุณกำลังบอกว่าตัวเลือกเหล่านี้ไม่ควรมีการกำหนดค่าตายตัว แต่มาจากไฟล์กำหนดค่า (ตัวอย่างเช่น di.xml) ฉันทำได้ แต่จะเหมือนกันกับรุ่นแหล่งที่มาของสถานะหรือไม่ ฉันหมายถึงถ้าฉันมีคลาสเดียวกันกับด้านบน แต่เฉพาะเมื่อเปิดใช้งานสถานะและปิดใช้งาน (1,0) ฉันควรใช้วิธีกำหนดค่าแบบเดียวกันหรือไม่ ถ้าใช่ฉันอยากจะบอกว่ามันเป็นเหมือนวิศวกรรมมากเกินไปสำหรับฉัน
Marius
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.