หลังจากเปลี่ยนแปลงหรือเพิ่มโค้ด คุณควรเรียกใช้การทดสอบหน่วยที่มีอยู่และลองเขียนเพิ่ม การทดสอบทั้งหมดจะดำเนินการกับโค้ดเวอร์ชันที่ไม่มีการบีบอัด
การทดสอบหน่วยมี 2 ชุด ได้แก่ การทดสอบ JS และการทดสอบเครื่องมือสร้างบล็อก
การทดสอบ JS
การทดสอบ JS จะยืนยันการทำงานของฟังก์ชัน JavaScript ภายในในบริการหลักของ Blockly เราใช้ 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 ให้เริ่มทำงานทันที (กำหนดค่าได้)
- ตั้งค่าการล้างข้อมูล blockTypes ที่กําหนดผ่าน
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)
อีกครั้งในการรื้อถอนชุดย่อยภายในนี้
- หากคุณกำหนด
โครงสร้างการทดสอบ
โดยทั่วไปแล้ว การทดสอบหน่วยจะเป็นไปตามโครงสร้างที่กำหนด ซึ่งสรุปได้ดังนี้ จัดเรียง ดำเนินการ ยืนยัน
- จัดเรียง: ตั้งค่าสถานะของสภาพแวดล้อมและเงื่อนไขที่จําเป็นสําหรับลักษณะการทํางานที่ทดสอบ
- ดำเนินการ: เรียกใช้โค้ดที่ทดสอบเพื่อทริกเกอร์ลักษณะการทำงานที่ทดสอบ
- Assert: ยืนยันเกี่ยวกับผลลัพธ์ที่แสดงหรือการทำงานกับออบเจ็กต์จำลองเพื่อตรวจสอบความถูกต้อง
ในการทดสอบง่ายๆ อาจไม่มีลักษณะการทำงานใดๆ ให้จัดเรียง และสามารถรวมขั้นตอนการดำเนินการและการยืนยันไว้โดยใส่การเรียกโค้ดภายใต้การทดสอบในการยืนยัน ในกรณีที่ซับซ้อนมากขึ้น การทดสอบจะอ่านได้ง่ายขึ้นหากคุณทำตาม 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 เพื่อยืนยันเกี่ยวกับโค้ด
- คุณสามารถระบุอาร์กิวเมนต์สตริงซึ่งไม่บังคับที่จะปรากฏหากการทดสอบล้มเหลว ซึ่งจะช่วยให้แก้ไขข้อบกพร่องของการทดสอบที่ไม่ทำงานได้ง่ายขึ้น
- ลำดับของพารามิเตอร์คือ
chai.assert.equal(actualValue, expectedValue, optionalMessage)
หากคุณสลับactual
กับexpected
ข้อความแสดงข้อผิดพลาดจะดูไม่สมเหตุสมผล
- Sinon ใช้สำหรับสร้างสตับเมธอดเมื่อคุณไม่ต้องการเรียกใช้โค้ดจริง ในตัวอย่างนี้ เราไม่ต้องการใช้ฟังก์ชันเมตริกจริงเนื่องจากไม่เกี่ยวข้องกับการทดสอบนี้ เราจะสนใจเฉพาะวิธีที่วิธีที่ใช้ทดสอบ
นำผลลัพธ์ไปใช้เท่านั้น Sinon จะสร้างสแต็บฟังก์ชัน
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 หน่วยของตัวเอง การทดสอบเหล่านี้จะยืนยันว่าบล็อกสร้างโค้ดมากกว่าฟังก์ชันตามที่ตั้งใจไว้
- โหลด
tests/generators/index.html
ใน Firefox หรือ Safari โปรดทราบว่า Chrome และ Opera มีข้อจำกัดด้านความปลอดภัยที่ป้องกันไม่ให้โหลดการทดสอบจากระบบ "file://" ในเครื่อง (ปัญหา 41024 และ 47416) - เลือกส่วนที่เกี่ยวข้องของระบบที่จะทดสอบจากเมนูแบบเลื่อนลง และคลิก "โหลด" การบล็อกควรปรากฏในพื้นที่ทำงาน
- คลิกที่ "JavaScript"
คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในคอนโซล JavaScript หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่านไปแล้ว - คลิก "Python"
คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในโปรแกรมแปลภาษา Python หากผลลัพธ์ลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่านแล้ว - คลิก "PHP"
คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในอินเตอร์พรีเตอร์ PHP หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่าน - คลิก "Lua"
คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในโปรแกรมแปลภาษา Lua หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่าน - คลิก "Dart"
คัดลอกและเรียกใช้โค้ดที่สร้างขึ้นในโปรแกรมแปลภาษา Dart หากเอาต์พุตลงท้ายด้วย "OK" แสดงว่าการทดสอบผ่าน
การแก้ไขการทดสอบเครื่องมือสร้างบล็อก
- โหลด
tests/generators/index.html
ในเบราว์เซอร์ - เลือกส่วนที่เกี่ยวข้องของระบบจากเมนูแบบเลื่อนลง แล้วคลิก "โหลด" บล็อกจะปรากฏในพื้นที่ทํางาน
- ทำการเปลี่ยนแปลงหรือเพิ่มเติมบล็อก
- คลิก "XML"
- คัดลอก XML ที่สร้างขึ้นลงในไฟล์ที่เหมาะสมใน
tests/generators/