การทดสอบอัตโนมัติจะถูกใช้ในงานต่อไป และยังใช้กันอย่างแพร่หลายในโครงการจริงอีกด้วย
เมื่อเราเขียนฟังก์ชัน เรามักจะจินตนาการได้ว่าฟังก์ชันควรทำอย่างไร พารามิเตอร์ใดให้ผลลัพธ์ใด
ในระหว่างการพัฒนา เราสามารถตรวจสอบฟังก์ชันได้ด้วยการรันและเปรียบเทียบผลลัพธ์กับฟังก์ชันที่คาดหวัง เช่น เราสามารถทำได้ในคอนโซล
หากมีสิ่งผิดปกติเกิดขึ้น เราจะแก้ไขโค้ด เรียกใช้อีกครั้ง ตรวจสอบผลลัพธ์ และอื่นๆ จนกว่าจะใช้งานได้
แต่การ "รันซ้ำ" ด้วยตนเองนั้นไม่สมบูรณ์
เมื่อทดสอบโค้ดด้วยการรันซ้ำด้วยตนเอง อาจพลาดบางสิ่งได้ง่าย
ตัวอย่างเช่น เรากำลังสร้างฟังก์ชัน f
เขียนโค้ดบางส่วน การทดสอบ: f(1)
ใช้งานได้ แต่ f(2)
ไม่ทำงาน เราแก้ไขโค้ดและตอนนี้ f(2)
ใช้งานได้ ดูเสร็จแล้วเหรอ? แต่เราลืมทดสอบอีกครั้ง f(1)
นั่นอาจนำไปสู่ข้อผิดพลาดได้
นั่นเป็นเรื่องปกติมาก เมื่อเราพัฒนาบางสิ่งบางอย่าง เราจะคำนึงถึงกรณีการใช้งานที่เป็นไปได้มากมาย แต่เป็นเรื่องยากที่จะคาดหวังว่าโปรแกรมเมอร์จะตรวจสอบทั้งหมดด้วยตนเองหลังการเปลี่ยนแปลงทุกครั้ง ดังนั้นจึงกลายเป็นเรื่องง่ายที่จะแก้ไขสิ่งหนึ่งและทำลายอีกสิ่งหนึ่ง
การทดสอบอัตโนมัติหมายความว่าการทดสอบจะถูกเขียนแยกกัน นอกเหนือจากโค้ด พวกเขาเรียกใช้ฟังก์ชันของเราในรูปแบบต่างๆ และเปรียบเทียบผลลัพธ์กับที่คาดหวัง
เรามาเริ่มต้นด้วยเทคนิคที่ชื่อว่า Behavior Driven Development หรือเรียกสั้นๆ ว่า BDD
BDD มีสามสิ่งในหนึ่งเดียว: การทดสอบและเอกสารประกอบและตัวอย่าง
เพื่อทำความเข้าใจ BDD เราจะพิจารณากรณีการพัฒนาเชิงปฏิบัติ
สมมติว่าเราต้องการสร้างฟังก์ชัน pow(x, n)
ที่ทำให้ x
เป็นจำนวนเต็มยกกำลัง n
เราถือว่า n≥0
งานนั้นเป็นเพียงตัวอย่าง: มีตัวดำเนินการ **
ใน JavaScript ที่สามารถทำได้ แต่ที่นี่เรามุ่งเน้นไปที่ขั้นตอนการพัฒนาที่สามารถนำไปใช้กับงานที่ซับซ้อนมากขึ้นได้เช่นกัน
ก่อนที่จะสร้างโค้ดของ pow
เราสามารถจินตนาการได้ว่าฟังก์ชันควรทำอะไรและอธิบายก่อน
คำอธิบายดังกล่าวเรียกว่า ข้อกำหนด หรือเรียกสั้น ๆ ว่าข้อมูลจำเพาะ และมีคำอธิบายของกรณีการใช้งานพร้อมกับการทดสอบดังนี้:
อธิบาย ("ธาร", ฟังก์ชั่น () { it("ยกกำลัง n", function() { assert.equal(ธาร(2, 3), 8); - -
ข้อมูลจำเพาะมีองค์ประกอบหลักสามประการที่คุณเห็นด้านบน:
describe("title", function() { ... })
เรากำลังอธิบายฟังก์ชันอะไร ในกรณีของเรา เรากำลังอธิบายฟังก์ชัน pow
ใช้เพื่อจัดกลุ่ม "คนงาน" - ซึ่ง it
บล็อก
it("use case description", function() { ... })
ในชื่อ it
เราอธิบายกรณีการใช้งานเฉพาะ ในลักษณะที่มนุษย์สามารถอ่านได้ และอาร์กิวเมนต์ที่สองคือฟังก์ชันที่ทดสอบ
assert.equal(value1, value2)
รหัสที่อยู่ภายใน it
หากการใช้งานถูกต้อง ควรดำเนินการโดยไม่มีข้อผิดพลาด
Functions assert.*
ใช้เพื่อตรวจสอบว่า pow
ทำงานตามที่คาดไว้หรือไม่ ที่นี่เราใช้หนึ่งในนั้น – assert.equal
โดยจะเปรียบเทียบอาร์กิวเมนต์และทำให้เกิดข้อผิดพลาดหากอาร์กิวเมนต์ไม่เท่ากัน ที่นี่จะตรวจสอบว่าผลลัพธ์ของ pow(2, 3)
เท่ากับ 8
มีการเปรียบเทียบและการตรวจสอบประเภทอื่นๆ ที่เราจะเพิ่มในภายหลัง
สามารถดำเนินการข้อกำหนดได้ และจะทำการทดสอบที่ระบุในบล็อก it
เราจะเห็นในภายหลัง
กระแสการพัฒนามักจะมีลักษณะดังนี้:
มีการเขียนข้อกำหนดเบื้องต้นพร้อมการทดสอบฟังก์ชันพื้นฐานที่สุด
มีการสร้างการใช้งานเบื้องต้น
เพื่อตรวจสอบว่าใช้งานได้หรือไม่ เราใช้เฟรมเวิร์กการทดสอบ Mocha (รายละเอียดเพิ่มเติมเร็วๆ นี้) ที่รันข้อมูลจำเพาะ แม้ว่าฟังก์ชันการทำงานจะไม่สมบูรณ์ แต่ก็มีข้อผิดพลาดแสดงขึ้น เราทำการแก้ไขจนกว่าทุกอย่างจะทำงาน
ตอนนี้เรามีการใช้งานเบื้องต้นพร้อมการทดสอบแล้ว
เราเพิ่มกรณีการใช้งานเพิ่มเติมให้กับข้อมูลจำเพาะ ซึ่งอาจยังไม่รองรับการใช้งาน การทดสอบเริ่มล้มเหลว
ไปที่ 3 อัปเดตการใช้งานจนกระทั่งการทดสอบไม่มีข้อผิดพลาด
ทำซ้ำขั้นตอนที่ 3-6 จนกว่าฟังก์ชันการทำงานจะพร้อมใช้งาน
ดังนั้นการพัฒนาจึงเป็นการ ทำซ้ำ เราเขียนข้อมูลจำเพาะ นำไปใช้ ตรวจสอบให้แน่ใจว่าการทดสอบผ่าน จากนั้นเขียนการทดสอบเพิ่มเติม ตรวจสอบให้แน่ใจว่ามันใช้งานได้ ฯลฯ ท้ายที่สุดแล้ว เราก็มีทั้งการใช้งานที่ใช้งานได้และการทดสอบ
เรามาดูขั้นตอนการพัฒนานี้กันในกรณีที่ใช้งานได้จริงของเรา
ขั้นตอนแรกเสร็จสมบูรณ์แล้ว: เรามีข้อมูลจำเพาะเริ่มต้นสำหรับ pow
ตอนนี้ ก่อนที่จะดำเนินการ ลองใช้ไลบรารี JavaScript สองสามไลบรารีเพื่อทำการทดสอบ เพื่อดูว่าไลบรารีเหล่านั้นกำลังทำงานอยู่ (ไลบรารีเหล่านี้ทั้งหมดจะล้มเหลว)
ในบทช่วยสอนเราจะใช้ไลบรารี JavaScript ต่อไปนี้สำหรับการทดสอบ:
Mocha – เฟรมเวิร์กหลัก: มันมีฟังก์ชันการทดสอบทั่วไป รวมถึง describe
และ it
และฟังก์ชันหลักที่ทำการทดสอบ
ชัย – ห้องสมุดที่มีข้ออ้างมากมาย ช่วยให้สามารถใช้การยืนยันที่แตกต่างกันได้มากมาย สำหรับตอนนี้เราต้องการเพียง assert.equal
เท่านั้น
Sinon – ไลบรารีสำหรับสอดแนมฟังก์ชันต่างๆ จำลองฟังก์ชันในตัว และอื่นๆ อีกมากมาย เราจะต้องการมันในภายหลัง
ไลบรารีเหล่านี้เหมาะสำหรับการทดสอบทั้งในเบราว์เซอร์และฝั่งเซิร์ฟเวอร์ ที่นี่เราจะพิจารณาตัวแปรของเบราว์เซอร์
หน้า HTML แบบเต็มพร้อมเฟรมเวิร์กและข้อมูลจำเพาะ pow
เหล่านี้:
<!DOCTYPE html> <html> <หัว> <!-- เพิ่ม mocha css เพื่อแสดงผลลัพธ์ --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css"> <!-- เพิ่มโค้ดเฟรมเวิร์กมอคค่า --> <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script> <สคริปต์> mocha.setup('bdd'); // การตั้งค่าขั้นต่ำ </สคริปต์> <!--เติมชัย--> <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script> <สคริปต์> // ชัยมีของมากมาย มาสร้างการยืนยันแบบสากลกันดีกว่า ให้ยืนยัน = chai.assert; </สคริปต์> </หัว> <ร่างกาย> <สคริปต์> ฟังก์ชั่นธาร(x, n) { /* รหัสฟังก์ชั่นสำหรับการเขียน, ว่างตอนนี้ */ - </สคริปต์> <!-- สคริปต์พร้อมการทดสอบ (อธิบายสิ...) --> <script src="test.js"></script> <!-- องค์ประกอบที่มี id="mocha" จะมีผลการทดสอบ --> <div id="มอคค่า"></div> <!-- ทำการทดสอบ! - <สคริปต์> มอคค่า.รัน(); </สคริปต์> </ร่างกาย> </html>
หน้าสามารถแบ่งออกเป็นห้าส่วน:
<head>
– เพิ่มไลบรารีและสไตล์ของบุคคลที่สามสำหรับการทดสอบ
<script>
พร้อมฟังก์ชันที่จะทดสอบ ในกรณีของเรา – พร้อมด้วยโค้ดสำหรับ pow
การทดสอบ – ในกรณีของเราคือสคริปต์ภายนอก test.js
ที่ describe("pow", ...)
จากด้านบน
องค์ประกอบ HTML <div id="mocha">
จะถูกใช้โดย Mocha เพื่อแสดงผลลัพธ์
การทดสอบเริ่มต้นโดยคำสั่ง mocha.run()
ผลลัพธ์:
ณ ขณะนี้ การทดสอบล้มเหลว มีข้อผิดพลาด นั่นเป็นตรรกะ: เรามีโค้ดฟังก์ชันว่างใน pow
ดังนั้น pow(2,3)
จึงส่งคืน undefined
แทนที่จะเป็น 8
ในอนาคต โปรดทราบว่ายังมีผู้ทดสอบระดับสูงมากขึ้น เช่น กรรมและอื่นๆ ที่ทำให้การทดสอบต่างๆ ทำงานโดยอัตโนมัติเป็นเรื่องง่าย
มาใช้งาน pow
อย่างง่าย ๆ เพื่อให้การทดสอบผ่าน:
ฟังก์ชั่นธาร(x, n) { กลับ 8; // :) เราโกง! -
ว้าว ตอนนี้มันใช้งานได้แล้ว!
สิ่งที่เราทำนั้นเป็นการโกงอย่างแน่นอน ฟังก์ชันไม่ทำงาน: การพยายามคำนวณ pow(3,4)
จะให้ผลลัพธ์ที่ไม่ถูกต้อง แต่การทดสอบผ่าน
…แต่สถานการณ์ค่อนข้างเป็นเรื่องปกติ มันเกิดขึ้นในทางปฏิบัติ การทดสอบผ่านไป แต่ฟังก์ชันทำงานผิดปกติ สเป็คของเราไม่สมบูรณ์ เราจำเป็นต้องเพิ่มกรณีการใช้งานเพิ่มเติมเข้าไป
เรามาเพิ่มอีกการทดสอบหนึ่งเพื่อตรวจสอบว่า pow(3, 4) = 81
เราสามารถเลือกหนึ่งในสองวิธีในการจัดการทดสอบได้ที่นี่:
ตัวแปรแรก – เพิ่ม assert
อีกหนึ่งรายการในอันเดียวกัน it
:
อธิบาย ("ธาร", ฟังก์ชั่น () { it("ยกกำลัง n", function() { assert.equal(ธาร(2, 3), 8); assert.equal(ธาร(3, 4), 81); - -
ประการที่สอง – ทำการทดสอบสองครั้ง:
อธิบาย ("ธาร", ฟังก์ชั่น () { it("2 ยกกำลัง 3 ได้ 8", function() { assert.equal(ธาร(2, 3), 8); - it("3 ยกกำลัง 4 ได้ 81", function() { assert.equal(ธาร(3, 4), 81); - -
ข้อแตกต่างหลักๆ ก็คือ เมื่อ assert
ก่อให้เกิดข้อผิดพลาด บล็อก it
จะยุติลงทันที ดังนั้น ในตัวแปรแรก หาก assert
ครั้งแรกล้มเหลว เราจะไม่เห็นผลลัพธ์ของ assert
ครั้งที่สอง
การแยกการทดสอบจะเป็นประโยชน์ในการรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่เกิดขึ้น ดังนั้นรูปแบบที่ 2 จึงดีกว่า
นอกจากนั้น ยังมีกฎอีกข้อหนึ่งที่ควรปฏิบัติตาม
การทดสอบหนึ่งครั้งจะตรวจสอบสิ่งหนึ่ง
หากเราดูการทดสอบและเห็นการตรวจสอบแยกกันสองรายการในนั้น จะเป็นการดีกว่าถ้าแยกออกเป็นสองรายการที่เรียบง่ายกว่า
เรามาต่อด้วยตัวแปรที่สองกัน
ผลลัพธ์:
อย่างที่เราคาดหวัง การทดสอบครั้งที่สองล้มเหลว แน่นอนว่าฟังก์ชันของเราจะส่งคืน 8
เสมอ ในขณะที่ assert
คาดหวัง 81
มาเขียนสิ่งที่เป็นจริงมากขึ้นเพื่อให้การทดสอบผ่าน:
ฟังก์ชั่นธาร(x, n) { ให้ผลลัพธ์ = 1; สำหรับ (ให้ i = 0; i < n; i++) { ผลลัพธ์ *= x; - ส่งคืนผลลัพธ์; -
เพื่อให้แน่ใจว่าฟังก์ชันทำงานได้ดี มาทดสอบเพื่อหาค่าเพิ่มเติมกันดีกว่า แทนที่จะเขียน it
ด้วยตนเอง เราสามารถสร้างมันขึ้นมา for
:
อธิบาย ("ธาร", ฟังก์ชั่น () { ฟังก์ชั่น makeTest (x) { ให้คาดหวัง = x * x * x; it(`${x} ยกกำลัง 3 คือ ${expected}`, function() { assert.equal(pow(x, 3), คาดหวัง); - - สำหรับ (ให้ x = 1; x <= 5; x++) { ทำการทดสอบ(x); - -
ผลลัพธ์:
เราจะเพิ่มการทดสอบเพิ่มเติม แต่ก่อนหน้านั้น โปรดทราบว่าฟังก์ชันตัวช่วย makeTest
และ for
ควรถูกจัดกลุ่มเข้าด้วยกัน เราไม่จำเป็นต้องมี makeTest
ในการทดสอบอื่นๆ เพราะจำเป็นเฉพาะใน for
: งานทั่วไปของพวกเขาคือการตรวจสอบว่า pow
เพิ่มขึ้นเป็นพลังที่กำหนดอย่างไร
การจัดกลุ่มเสร็จสิ้นโดยใช้ describe
แบบซ้อน:
อธิบาย ("ธาร", ฟังก์ชั่น () { อธิบาย ("เพิ่ม x ให้เป็นกำลัง 3", function() { ฟังก์ชั่น makeTest (x) { ให้คาดหวัง = x * x * x; it(`${x} ยกกำลัง 3 คือ ${expected}`, function() { assert.equal(pow(x, 3), คาดหวัง); - - สำหรับ (ให้ x = 1; x <= 5; x++) { ทำการทดสอบ(x); - - // ... การทดสอบเพิ่มเติมให้ติดตามที่นี่ ทั้งอธิบายและสามารถเพิ่มได้ -
describe
แบบซ้อนจะกำหนด "กลุ่มย่อย" ใหม่ของการทดสอบ ในผลลัพธ์เราจะเห็นการเยื้องชื่อ:
ในอนาคตเราสามารถ it
มากขึ้นและ describe
ในระดับบนสุดด้วยฟังก์ชันตัวช่วยของตนเอง พวกเขาจะไม่เห็น makeTest
before/after
และ beforeEach/afterEach
เราสามารถตั้งค่าฟังก์ชัน before/after
ที่ดำเนินการก่อน/หลังการทดสอบที่รันอยู่ และฟังก์ชัน beforeEach/afterEach
ที่ดำเนินการก่อน/หลัง it
ทุก ครั้ง
ตัวอย่างเช่น:
อธิบาย ("ทดสอบ" ฟังก์ชั่น () { before(() => alert("เริ่มการทดสอบ – ก่อนการทดสอบทั้งหมด")); after(() => alert("การทดสอบเสร็จสิ้น – หลังจากการทดสอบทั้งหมด")); beforeEach(() => alert("ก่อนการทดสอบ – เข้าสู่การทดสอบ")); afterEach(() => alert("หลังการทดสอบ – ออกจากการทดสอบ")); มัน('ทดสอบ 1', () => การแจ้งเตือน(1)); มัน('ทดสอบ 2', () => แจ้งเตือน(2)); -
ลำดับการทำงานจะเป็น:
เริ่มการทดสอบ – ก่อนการทดสอบทั้งหมด (ก่อน) ก่อนสอบ – เข้าสอบ (ก่อนสอบ) 1 หลังการทดสอบ – ออกจากการทดสอบ (afterEach) ก่อนสอบ – เข้าสอบ (ก่อนสอบ) 2 หลังการทดสอบ – ออกจากการทดสอบ (afterEach) การทดสอบเสร็จสิ้น – หลังจากการทดสอบทั้งหมด (หลัง)
เปิดตัวอย่างในแซนด์บ็อกซ์
โดยปกติแล้ว beforeEach/afterEach
และ before/after
จะถูกใช้เพื่อดำเนินการเริ่มต้น ลบศูนย์ หรือทำอย่างอื่นระหว่างการทดสอบ (หรือกลุ่มการทดสอบ)
ฟังก์ชั่นพื้นฐานของ pow
เสร็จสมบูรณ์แล้ว การพัฒนาซ้ำครั้งแรกเสร็จสิ้นแล้ว เมื่อเราเฉลิมฉลองและดื่มแชมเปญเสร็จแล้ว เรามาปรับปรุงกันดีกว่า
ตามที่กล่าวไว้ ฟังก์ชั่น pow(x, n)
มีไว้เพื่อทำงานกับค่าจำนวนเต็มบวก n
เพื่อระบุข้อผิดพลาดทางคณิตศาสตร์ ฟังก์ชัน JavaScript มักจะส่งคืน NaN
ลองทำเช่นเดียวกันกับค่าที่ไม่ถูกต้องของ n
ก่อนอื่นมาเพิ่มพฤติกรรมให้กับ spec(!):
อธิบาย ("ธาร", ฟังก์ชั่น () { - it("สำหรับค่าลบ n ผลลัพธ์คือ NaN", function() { assert.isNaN(ธาร(2, -1)); - it("สำหรับจำนวนที่ไม่ใช่จำนวนเต็ม n ผลลัพธ์คือ NaN", function() { assert.isNaN(ธาร(2, 1.5)); - -
ผลลัพธ์จากการทดสอบใหม่:
การทดสอบที่เพิ่มเข้ามาใหม่ล้มเหลว เนื่องจากการใช้งานของเราไม่รองรับ นั่นคือวิธีที่ BDD ทำ: อันดับแรกเราเขียนการทดสอบที่ล้มเหลว จากนั้นจึงดำเนินการทดสอบ
ข้อยืนยันอื่น ๆ
โปรดทราบการยืนยัน assert.isNaN
: จะตรวจสอบ NaN
ยังมีคำกล่าวอ้างอื่นๆ ในชัยด้วย เช่น
assert.equal(value1, value2)
– ตรวจสอบความเท่าเทียมกัน value1 == value2
assert.strictEqual(value1, value2)
– ตรวจสอบค่าความเท่าเทียมกันที่เข้มงวด value1 === value2
assert.notEqual
, assert.notStrictEqual
– การตรวจสอบแบบผกผันกับรายการด้านบน
assert.isTrue(value)
– ตรวจสอบว่า value === true
assert.isFalse(value)
– ตรวจสอบว่า value === false
…รายการทั้งหมดอยู่ในเอกสาร
ดังนั้นเราควรเพิ่มสองสามบรรทัดใน pow
:
ฟังก์ชั่นธาร(x, n) { ถ้า (n < 0) ส่งคืน NaN; ถ้า (Math.round(n) != n) ส่งคืน NaN; ให้ผลลัพธ์ = 1; สำหรับ (ให้ i = 0; i < n; i++) { ผลลัพธ์ *= x; - ส่งคืนผลลัพธ์; -
ตอนนี้ใช้งานได้แล้ว การทดสอบทั้งหมดผ่าน:
เปิดตัวอย่างสุดท้ายแบบเต็มในแซนด์บ็อกซ์
ใน BDD ข้อมูลจำเพาะจะมาก่อน ตามด้วยการใช้งาน ในตอนท้ายเรามีทั้งสเป็คและโค้ด
ข้อมูลจำเพาะสามารถใช้งานได้สามวิธี:
เป็น แบบทดสอบ – รับประกันว่าโค้ดทำงานได้อย่างถูกต้อง
As Docs – ชื่อเรื่องของ describe
และ it
ว่าฟังก์ชันทำอะไร
เป็น ตัวอย่าง – การทดสอบเป็นตัวอย่างการทำงานจริงที่แสดงให้เห็นว่าสามารถใช้ฟังก์ชันได้อย่างไร
ด้วยข้อมูลจำเพาะนี้ เราสามารถปรับปรุง เปลี่ยนแปลง หรือเขียนฟังก์ชันใหม่ได้อย่างปลอดภัยตั้งแต่ต้น และตรวจสอบให้แน่ใจว่ายังคงทำงานได้อย่างถูกต้อง
นั่นเป็นสิ่งสำคัญอย่างยิ่งในโครงการขนาดใหญ่เมื่อมีการใช้ฟังก์ชันในหลายสถานที่ เมื่อเราเปลี่ยนฟังก์ชันดังกล่าว ไม่มีทางที่จะตรวจสอบด้วยตนเองว่าทุกสถานที่ที่ใช้งานฟังก์ชันดังกล่าวยังใช้งานได้ปกติหรือไม่
หากไม่มีการทดสอบ ผู้คนมีสองวิธี:
เพื่อดำเนินการเปลี่ยนแปลงไม่ว่าอย่างไรก็ตาม จากนั้นผู้ใช้ของเราก็พบกับจุดบกพร่อง เนื่องจากเราอาจไม่สามารถตรวจสอบบางอย่างด้วยตนเองได้
หรือหากการลงโทษสำหรับข้อผิดพลาดนั้นรุนแรง เนื่องจากไม่มีการทดสอบ ผู้คนจึงกลัวที่จะแก้ไขฟังก์ชันดังกล่าว และโค้ดก็ล้าสมัย ไม่มีใครอยากเข้าไปยุ่ง ไม่เป็นผลดีต่อการพัฒนา
การทดสอบอัตโนมัติช่วยหลีกเลี่ยงปัญหาเหล่านี้!
หากโครงการครอบคลุมการทดสอบ ก็ไม่มีปัญหาดังกล่าว หลังจากการเปลี่ยนแปลงใดๆ เราสามารถดำเนินการทดสอบและดูการตรวจสอบจำนวนมากได้ในเวลาไม่กี่วินาที
นอกจากนี้โค้ดที่ได้รับการทดสอบอย่างดียังมีสถาปัตยกรรมที่ดีกว่าอีกด้วย
โดยปกติแล้ว นั่นเป็นเพราะว่าโค้ดที่ทดสอบอัตโนมัตินั้นง่ายต่อการแก้ไขและปรับปรุง แต่ยังมีเหตุผลอื่นอีกด้วย
ในการเขียนการทดสอบ โค้ดควรได้รับการจัดระเบียบในลักษณะที่ทุกฟังก์ชันมีงานที่อธิบายไว้อย่างชัดเจน มีอินพุตและเอาท์พุตที่กำหนดไว้อย่างดี นั่นหมายถึงสถาปัตยกรรมที่ดีตั้งแต่เริ่มต้น
ในชีวิตจริงบางครั้งมันก็ไม่ง่ายขนาดนั้น บางครั้งการเขียน spec ก่อนโค้ดจริงอาจเป็นเรื่องยาก เนื่องจากยังไม่ชัดเจนว่าควรทำงานอย่างไร แต่ในการทดสอบการเขียนทั่วไปทำให้การพัฒนาเร็วขึ้นและมีเสถียรภาพมากขึ้น
ต่อมาในบทช่วยสอน คุณจะได้พบกับงานมากมายที่มีการทดสอบในตัว ดังนั้นคุณจะเห็นตัวอย่างที่เป็นประโยชน์มากขึ้น
การทดสอบการเขียนต้องใช้ความรู้ JavaScript ที่ดี แต่เราเพิ่งเริ่มเรียนรู้มัน ดังนั้น เพื่อจัดการทุกอย่างให้เรียบร้อย ณ ตอนนี้คุณไม่จำเป็นต้องเขียนแบบทดสอบ แต่คุณควรจะสามารถอ่านข้อสอบได้แล้ว แม้ว่ามันจะซับซ้อนกว่าในบทนี้เล็กน้อยก็ตาม
ความสำคัญ: 5
มีอะไรผิดปกติในการทดสอบ pow
ด้านล่าง?
it("เพิ่ม x ยกกำลัง n", function() { ให้ x = 5; ให้ผลลัพธ์ = x; assert.equal(ธาร(x, 1) ผลลัพธ์); ผลลัพธ์ *= x; assert.equal(ธาร(x, 2) ผลลัพธ์); ผลลัพธ์ *= x; assert.equal(ธาร(x, 3) ผลลัพธ์); -
PS การทดสอบทางวากยสัมพันธ์นั้นถูกต้องและผ่าน
การทดสอบแสดงให้เห็นถึงสิ่งล่อใจอย่างหนึ่งที่นักพัฒนาพบเมื่อเขียนการทดสอบ
จริงๆ แล้วสิ่งที่เรามีที่นี่คือการทดสอบ 3 รายการ แต่จัดวางเป็นฟังก์ชันเดียวพร้อมการยืนยัน 3 รายการ
บางครั้งการเขียนแบบนี้ง่ายกว่า แต่ถ้าเกิดข้อผิดพลาด ก็จะมองเห็นได้ชัดเจนน้อยลงว่าเกิดอะไรขึ้น
หากเกิดข้อผิดพลาดระหว่างขั้นตอนการดำเนินการที่ซับซ้อน เราจะต้องค้นหาข้อมูล ณ จุดนั้น เราจะต้อง แก้ไขข้อบกพร่องของการทดสอบ จริงๆ
จะดีกว่ามากถ้าแบ่งการทดสอบออกเป็นหลาย ๆ it
ด้วยอินพุตและเอาต์พุตที่เขียนไว้อย่างชัดเจน
แบบนี้:
อธิบาย ("เพิ่ม x ให้เป็นกำลัง n", function() { it("5 ยกกำลัง 1 เท่ากับ 5", function() { assert.equal(ธาร(5, 1), 5); - it("5 ยกกำลัง 2 เท่ากับ 25", function() { assert.equal(ธาร(5, 2), 25); - it("5 ยกกำลัง 3 เท่ากับ 125", function() { assert.equal(ธาร(5, 3), 125); - -
เราแทนที่ it
เดียวด้วย describe
และกลุ่มของ it
บล็อก ตอนนี้ถ้ามีอะไรล้มเหลว เราจะเห็นได้อย่างชัดเจนว่าข้อมูลคืออะไร
นอกจากนี้เรายังสามารถแยกการทดสอบเดี่ยวและรันในโหมดสแตนด์อโลนโดยการเขียน it.only
it
:
อธิบาย ("เพิ่ม x ให้เป็นกำลัง n", function() { it("5 ยกกำลัง 1 เท่ากับ 5", function() { assert.equal(ธาร(5, 1), 5); - // Mocha จะทำงานเฉพาะบล็อกนี้เท่านั้น it.only("5 ยกกำลัง 2 เท่ากับ 25", function() { assert.equal(ธาร(5, 2), 25); - it("5 ยกกำลัง 3 เท่ากับ 125", function() { assert.equal(ธาร(5, 3), 125); - -