การทดสอบ 1 หน่วย

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

การทดสอบ 1 หน่วยมี 2 ชุด ได้แก่ การทดสอบ JS และการทดสอบเครื่องมือสร้างบล็อก

การทดสอบ JS

การทดสอบ JS จะยืนยันการทำงานของฟังก์ชัน JavaScript ภายในใน หลัก เราใช้ Mocha เพื่อเรียกใช้การทดสอบหน่วย, Sinon เพื่อจำลองการพึ่งพา และ Chai เพื่อยืนยันเกี่ยวกับโค้ด

การทดสอบที่ทำงานอยู่

ทั้ง blockly และ blockly-samples npm run test จะเรียกใช้การทดสอบหน่วย ใน โค้ดนี้จะทำการทดสอบอื่นๆ ด้วย เช่น การวิเคราะห์ซอร์สโค้ดและการคอมไพล์ นอกจากนี้ คุณยังเปิด tests/mocha/index.html ในเบราว์เซอร์เพื่อเรียกใช้การทดสอบ mocha ทั้งหมดแบบอินเทอร์แอกทีฟได้ด้วย

การทดสอบการเขียน

เราใช้อินเทอร์เฟซ Mocha TDD เพื่อทำการทดสอบ การทดสอบจะจัดระเบียบเป็นชุด ซึ่งอาจมีทั้งชุดย่อยและ/หรือการทดสอบเพิ่มเติม โดยทั่วไปแล้ว คอมโพเนนต์แต่ละรายการของ Blockly (เช่น toolbox หรือ workspace) จะมีไฟล์ทดสอบเป็นของตัวเอง ซึ่งมีชุดทดสอบอย่างน้อย 1 ชุด ห้องสวีทแต่ละห้องมี setup และ teardown ได้ ซึ่งจะเรียกใช้ก่อนและหลังการทดสอบแต่ละครั้งตามลำดับ ชุดโปรแกรม

ผู้ช่วยทดสอบ

เรามีฟังก์ชันตัวช่วยมากมายเฉพาะสำหรับ Blockly ซึ่งอาจเป็นประโยชน์เมื่อ ข้อสอบการเขียน ซึ่งจะอยู่ในไฟล์ core และ blockly-samples

ฟังก์ชันตัวช่วยประกอบด้วย sharedTestSetup และ sharedTestTeardown ซึ่ง จำเป็นเพื่อให้เรียกก่อนและหลังการทดสอบ (โปรดดูข้อกำหนด )

sharedTestSetup:
  • ตั้งค่าตัวจับเวลาปลอมแบบ sinon (ในการทดสอบบางอย่างที่คุณจำเป็นต้องใช้ this.clock.runAll)
  • Stubs Blockly.Events.fire ให้เริ่มทำงานทันที (กำหนดค่าได้)
  • แต่จะตั้งค่าการล้างข้อมูลการบล็อกประเภทการบล็อกโดยอัตโนมัติ defineBlocksWithJsonArray
  • ประกาศพร็อพเพอร์ตี้ 2-3 รายการในบริบท this ที่มีไว้เพื่อให้เข้าถึงได้ ดังนี้
    • this.clock (แต่ไม่ควรกู้คืน ไม่เช่นนั้นอาจทำให้เกิดปัญหาใน sharedTestTeardown)
    • this.eventsFireStub
    • this.sharedCleanup (ใช้กับ addMessageToCleanup และ addBlockTypeToCleanup) (หมายเหตุ: คุณไม่จำเป็นต้องใช้ addBlockTypeToCleanup หากกำหนดบล็อกโดยใช้ defineBlocksWithJsonArray)

ฟังก์ชันมีพารามิเตอร์ options ที่ไม่บังคับ 1 รายการเพื่อกําหนดค่าการตั้งค่า ปัจจุบันมีไว้เพื่อพิจารณาว่าจะจำลอง Blockly.Events.fire ให้ทำงานทันทีหรือไม่ (จะจำลองโดยค่าเริ่มต้น)

sharedTestTeardown:
  • กำจัดพื้นที่ทำงาน this.workspace (ขึ้นอยู่กับตำแหน่งที่กำหนดไว้ โปรดดูข้อมูลเพิ่มเติมในส่วนข้อกำหนดการทดสอบ)
  • กู้คืนข้อมูลโค้ดทั้งหมด
  • ล้างข้อมูลบล็อกทุกประเภทที่เพิ่มผ่าน defineBlocksWithJsonArray และ addBlockTypeToCleanup
  • ล้างข้อความทั้งหมดที่เพิ่มผ่าน addMessageToCleanup

ข้อกำหนดการทดสอบ

  • การทดสอบแต่ละครั้งต้องเรียกใช้ sharedTestSetup.call(this); เป็นบรรทัดแรกใน ชุดห้องนอกสุดและ sharedTestTeardown.call(this); เป็น บรรทัดสุดท้ายในการถอดชุดไฟล์ด้านนอกสุดของไฟล์
  • หากต้องการเวิร์กスペースที่มีกล่องเครื่องมือทั่วไป คุณสามารถใช้กล่องเครื่องมือที่กำหนดล่วงหน้ารายการใดรายการหนึ่งในindex.htmlทดสอบ โปรดดูตัวอย่างด้านล่าง
  • คุณต้องกำจัด this.workspace อย่างเหมาะสม ในการทดสอบส่วนใหญ่ คุณจะกําหนด this.workspace ในชุดทดสอบด้านนอกสุดและใช้ชุดทดสอบนั้นกับการทดสอบต่อๆ ไปทั้งหมด แต่ในบางกรณี คุณอาจกําหนดหรือกําหนดใหม่ในชุดทดสอบด้านใน (เช่น การทดสอบรายการหนึ่งต้องใช้เวิร์กスペースที่มีตัวเลือกแตกต่างจากที่คุณตั้งค่าไว้ตอนแรก) และต้องกำจัดเมื่อสิ้นสุดการทดสอบ
    • หากคุณกำหนด this.workspace ในชุดชั้นนอกสุดและไม่เคยกำหนดใหม่ คุณก็ไม่ต้องดำเนินการใดๆ เพิ่มเติม อุปกรณ์จะถูกกำจัดโดยอัตโนมัติภายใน sharedTestTeardown
    • หากคุณกำหนด this.workspace เป็นครั้งแรกในชุดภายใน (เช่น ไม่ได้กำหนดในชุดด้านนอก) กำจัดสิ่งที่เป็นอันตรายโดยโทรหา workspaceTeardown.call(this, this.workspace) ในการทำลายรหัสชุดนั้น
    • หากคุณกําหนด this.workpace ในชุดทดสอบด้านนอกสุด แต่กําหนดใหม่ในชุดทดสอบด้านใน คุณต้องเรียกใช้ workspaceTeardown.call(this, this.workspace) ก่อนกําหนดใหม่เพื่อรื้อถอนเวิร์กスペースเดิมที่กําหนดไว้ในชุดทดสอบระดับบนสุด นอกจากนี้ คุณยังต้องกำจัดค่าใหม่ด้วยตนเองโดยเรียกใช้ workspaceTeardown.call(this, this.workspace) อีกครั้งในการรื้อถอนชุดย่อยภายในนี้

โครงสร้างการทดสอบ

โดยทั่วไปแล้ว การทดสอบหน่วยจะเป็นไปตามโครงสร้างที่กำหนด ซึ่งสรุปได้ดังนี้ จัดเรียง ดำเนินการ ยืนยัน

  1. จัดเรียง: ตั้งค่าสถานะของสภาพแวดล้อมและเงื่อนไขที่จําเป็นสําหรับลักษณะการทํางานภายใต้การทดสอบ
  2. ดำเนินการ: เรียกใช้โค้ดที่ทดสอบเพื่อทริกเกอร์ลักษณะการทำงานที่ทดสอบ
  3. ยืนยัน: ยืนยันเกี่ยวกับผลลัพธ์ที่ได้หรือการทำงานกับออบเจ็กต์จำลองเพื่อตรวจสอบความถูกต้อง

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

ต่อไปนี้เป็นตัวอย่างไฟล์ทดสอบ (ปรับให้เข้าใจง่ายจากไฟล์จริง)

suite('Flyout', function() {
  setup(function() {
    sharedTestSetup.call(this);
    this.toolboxXml = document.getElementById('toolbox-simple');
    this.workspace = Blockly.inject('blocklyDiv',
        {
          toolbox: this.toolboxXml
        });
  });

  teardown(function() {
    sharedTestTeardown.call(this);
  });

  suite('simple flyout', function() {
    setup(function() {
      this.flyout = this.workspace.getFlyout();
    });
    test('y is always 0', function() {
      // Act and assert stages combined for simple test case
      chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout is 0');
    });
    test('x is right of workspace if flyout at right', function() {
      // Arrange
      sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
        viewWidth: 100,
      });
      this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
      this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;

      // Act
      var x = this.flyout.getX();

      // Assert
      chai.assert.equal(x, 100, 'x is right of workspace');
    });
  });
});

สิ่งที่ควรทราบจากตัวอย่างนี้มีดังนี้

  • หนึ่งชุดอาจมีชุดอื่นๆ ที่มีsetupและteardownวิธีเพิ่มเติม
  • ชุดทดสอบและการทดสอบแต่ละรายการจะมีชื่อที่สื่อความหมาย
  • การยืนยันของชาใช้เพื่อยืนยันโค้ด
    • คุณสามารถระบุอาร์กิวเมนต์สตริงที่ไม่บังคับซึ่งจะแสดงขึ้นหากการทดสอบไม่สําเร็จ ซึ่งจะช่วยให้แก้ไขข้อบกพร่องของการทดสอบที่ไม่ทำงานได้ง่ายขึ้น
    • ลำดับของพารามิเตอร์คือ chai.assert.equal(actualValue, expectedValue, optionalMessage) หากคุณสลับ actual กับ expected ข้อความแสดงข้อผิดพลาดนั้นจะไม่สมเหตุสมผล
  • Sinon ใช้สำหรับสร้างสตับเมธอดเมื่อคุณไม่ต้องการเรียกใช้โค้ดจริง ใน ตัวอย่างนี้ เราไม่ต้องการเรียกฟังก์ชันเมตริกจริงเนื่องจาก ไม่เกี่ยวข้องกับการทดสอบนี้ เราสนใจเฉพาะการใช้ผลการค้นหาโดย เมธอดภายใต้การทดสอบ Sinon stub ใช้ฟังก์ชัน getMetrics เพื่อแสดงผล คำตอบสำเร็จรูปที่เราตรวจสอบได้ง่ายๆ ในการยืนยันของเรา
  • เมธอด setup สำหรับแต่ละชุดควรมีการตั้งค่าทั่วไปที่ ใช้กับการทดสอบทั้งหมด หากการทดสอบสำหรับลักษณะการทำงานบางอย่างต้องใช้ เงื่อนไขใดเงื่อนไขหนึ่ง เงื่อนไขดังกล่าวควรมีการระบุไว้อย่างชัดเจนใน การทดสอบ

การทดสอบการแก้ไขข้อบกพร่อง

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

    suite.only('Workspace', function () {
      suite('updateToolbox', function () {
        test('test name', function () {
          // ...
        });
        test.skip('test I don’t care about', function () {
          // ...
        });
      });
    });
    

    อย่าลืมนำโค้ดเหล่านี้ออกก่อนที่จะยืนยันโค้ด

บล็อกการทดสอบเครื่องมือสร้าง

แต่ละบล็อกมีการทดสอบ 1 หน่วยของตัวเอง การทดสอบเหล่านี้จะยืนยันว่าบล็อกสร้างโค้ดมากกว่าฟังก์ชันตามที่ตั้งใจไว้

  1. โหลด tests/generators/index.html ใน Firefox หรือ Safari โปรดทราบว่า Chrome และ Opera มีข้อจำกัดด้านความปลอดภัยที่ป้องกันไม่ให้โหลดการทดสอบจากระบบ "file://" ในเครื่อง (ปัญหา 41024 และ 47416)
  2. เลือกส่วนที่เกี่ยวข้องของระบบที่จะทดสอบจากเมนูแบบเลื่อนลง แล้วคลิก "โหลด" บล็อกจะปรากฏในพื้นที่ทํางาน
  3. คลิก "JavaScript"
    คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในคอนโซล JavaScript หากเอาต์พุตสิ้นสุด "ตกลง" หมายความว่าการทดสอบได้ผ่านไปแล้ว
  4. คลิก "Python"
    คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในโปรแกรมแปลภาษา Python หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่าน
  5. คลิก "PHP"
    คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในอินเตอร์พรีเตอร์ PHP หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่านแล้ว
  6. คลิก "Lua"
    คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในล่าม Lua หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่านแล้ว
  7. คลิก "Dart"
    คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในล่าม Dart หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่าน

การแก้ไขการทดสอบเครื่องมือสร้างบล็อก

  1. โหลด tests/generators/index.html ในเบราว์เซอร์
  2. เลือกส่วนที่เกี่ยวข้องของระบบจากเมนูแบบเลื่อนลง แล้วคลิก "โหลด" บล็อกจะปรากฏในพื้นที่ทํางาน
  3. ทำการเปลี่ยนแปลงหรือเพิ่มบล็อก
  4. คลิกที่ "XML"
  5. คัดลอก XML ที่สร้างขึ้นลงในไฟล์ที่เหมาะสมใน tests/generators/