portaldacalheta.pt
  • หลัก
  • การจัดการวิศวกรรม
  • บุคลากรและทีมงานของผลิตภัณฑ์
  • อื่น ๆ
  • นวัตกรรม
ส่วนหน้าของเว็บ

Test-driven React.js Development: React.js Unit Testing with Enzyme and Jest



ส่วนของรหัสใด ๆ ที่ไม่มีการทดสอบจะกล่าวว่าเป็นรหัสเดิมตาม Michael Feathers ดังนั้นวิธีที่ดีที่สุดวิธีหนึ่งในการหลีกเลี่ยงการสร้างรหัสเดิมคือการใช้การทดสอบขับเคลื่อนการพัฒนา (TDD)

แม้ว่าจะมีเครื่องมือมากมายสำหรับ JavaScript และ React.js การทดสอบหน่วยในโพสต์นี้เราจะใช้ Jest และ Enzyme เพื่อสร้างส่วนประกอบ React.js ด้วยฟังก์ชันพื้นฐานโดยใช้ TDD



เหตุใดจึงต้องใช้ TDD เพื่อสร้างส่วนประกอบ React.js

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



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



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

เราจะทดสอบส่วนประกอบของ React.js ได้อย่างไร

มีหลายกลยุทธ์ที่เราสามารถใช้เพื่อทดสอบส่วนประกอบ React.js:



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

ในการใช้กลยุทธ์เหล่านี้เราจะใช้เครื่องมือสองอย่างที่มีประโยชน์ในการทำงานกับการทดสอบใน React.js: คือ และ เอนไซม์ .

เหตุใดฉันจึงควรใช้ node.js

การใช้ Jest เพื่อสร้างการทดสอบหน่วย

Jest เป็นกรอบการทดสอบโอเพ่นซอร์สที่สร้างโดย Facebook ซึ่งมีการทำงานร่วมกับ React.js อย่างดีเยี่ยม มีเครื่องมือบรรทัดคำสั่งสำหรับการดำเนินการทดสอบที่คล้ายกับข้อเสนอของจัสมินและมอคค่า นอกจากนี้ยังช่วยให้เราสามารถสร้างฟังก์ชันจำลองที่มีการกำหนดค่าเกือบเป็นศูนย์และมีชุดตัวจับคู่ที่ดีมากซึ่งทำให้การยืนยันอ่านง่ายขึ้น



นอกจากนี้ยังมีคุณสมบัติที่ดีมากที่เรียกว่า 'การทดสอบภาพรวม' ซึ่งช่วยให้เราตรวจสอบและยืนยันผลการแสดงผลส่วนประกอบ เราจะใช้การทดสอบสแนปชอตเพื่อจับโครงสร้างขององค์ประกอบและบันทึกลงในไฟล์ที่เราสามารถใช้เพื่อเปรียบเทียบกับแผนภูมิการแสดงผล (หรืออะไรก็ตามที่เราส่งผ่านไปยังฟังก์ชัน expect เป็นอาร์กิวเมนต์แรก)

การใช้ Enzyme เพื่อ Mount React.js Components

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



เอนไซม์มีฟังก์ชันพื้นฐานสองอย่างสำหรับการติดตั้งส่วนประกอบ: shallow และ mount. shallow ฟังก์ชั่นโหลดในหน่วยความจำเฉพาะองค์ประกอบรูทในขณะที่ mount โหลดทรี DOM แบบเต็ม

เราจะรวม Enzyme และ Jest เพื่อติดตั้งส่วนประกอบ React.js และเรียกใช้การยืนยันมากกว่านั้น



TDD ขั้นตอนในการสร้างส่วนประกอบปฏิกิริยา

การสร้างสภาพแวดล้อมของเรา

คุณสามารถดูได้ที่ repo นี้ ซึ่งมีการกำหนดค่าพื้นฐานเพื่อเรียกใช้ตัวอย่างนี้



เรากำลังใช้เวอร์ชันต่อไปนี้:

{ 'react': '16.0.0', 'enzyme': '^2.9.1', 'jest': '^21.2.1', 'jest-cli': '^21.2.1', 'babel-jest': '^21.2.0' }

การสร้างคอมโพเนนต์ React.js โดยใช้ TDD

ขั้นตอนแรกคือการสร้างการทดสอบที่ล้มเหลวซึ่งจะพยายามสร้าง React.js Component โดยใช้ฟังก์ชันตื้นของเอนไซม์

// MyComponent.test.js import React from 'react'; import { shallow } from 'enzyme'; import MyComponent from './MyComponent'; describe('MyComponent', () => { it('should render my component', () => { const wrapper = shallow(); }); });

หลังจากทำการทดสอบเราได้รับข้อผิดพลาดต่อไปนี้:

ReferenceError: MyComponent is not defined.

จากนั้นเราจะสร้างส่วนประกอบที่จัดเตรียมไวยากรณ์พื้นฐานเพื่อให้การทดสอบผ่าน

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { render() { return ; } }

ในขั้นตอนต่อไปเราจะตรวจสอบให้แน่ใจว่าองค์ประกอบของเราแสดงเค้าโครง UI ที่กำหนดไว้ล่วงหน้าโดยใช้ toMatchSnapshot ฟังก์ชั่นจาก Jest

หลังจากเรียกเมธอดนี้ Jest จะสร้างไฟล์สแน็ปช็อตชื่อ [testFileName].snap โดยอัตโนมัติซึ่งเพิ่ม __snapshots__ โฟลเดอร์

ไฟล์นี้แสดงถึงเค้าโครง UI ที่เราคาดหวังจากการแสดงผลคอมโพเนนต์ของเรา

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

อาจฟังดูสับสนเล็กน้อยเนื่องจากเราไม่ทราบว่า Jest ใช้รูปแบบใดในการแสดงเลย์เอาต์นี้

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

ไฟล์สแน็ปช็อตมีเค้าโครงที่ตรงกับชื่อของการทดสอบ ซึ่งหมายความว่าหากการทดสอบของเรามีรูปแบบนี้:

desc('ComponentA' () => { it('should do something', () => { … } });

เราควรระบุสิ่งนี้ในส่วนการส่งออก: Component A should do something 1.

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการทดสอบสแนปชอต ที่นี่ .

วิกฤตหนี้กรีซ อธิบายง่ายๆ

ดังนั้นเราจึงสร้าง MyComponent.test.js.snap ก่อน ไฟล์.

//__snapshots__/MyComponent.test.js.snap exports[`MyComponent should render initial layout 1`] = ` Array [ , ] `;

จากนั้นสร้างการทดสอบหน่วยที่จะตรวจสอบว่าสแนปชอตตรงกับองค์ประกอบลูกของคอมโพเนนต์

// MyComponent.test.js ... it('should render initial layout', () => { // when const component = shallow(); // then expect(component.getElements()).toMatchSnapshot(); }); ...

เราสามารถพิจารณา components.getElements อันเป็นผลมาจากวิธีการแสดงผล

เราส่งผ่านองค์ประกอบเหล่านี้ไปยัง expect เพื่อรันการตรวจสอบกับไฟล์สแนปชอต

หลังจากดำเนินการทดสอบเราได้รับข้อผิดพลาดต่อไปนี้:

Received value does not match stored snapshot 1. Expected: - Array [ , ] Actual: + Array []

Jest กำลังบอกเราว่าผลลัพธ์จาก component.getElements ไม่ตรงกับสแนปชอต ดังนั้นเราจึงทำให้การทดสอบนี้ผ่านไปโดยการเพิ่มองค์ประกอบอินพุตใน MyComponent

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { render() { return ; } }

ขั้นตอนต่อไปคือการเพิ่มฟังก์ชันให้กับ input โดยเรียกใช้ฟังก์ชันเมื่อค่าของมันเปลี่ยนไป เราทำได้โดยระบุฟังก์ชันใน onChange เสา

ก่อนอื่นเราต้องเปลี่ยนภาพรวมเพื่อให้การทดสอบล้มเหลว

//__snapshots__/MyComponent.test.js.snap exports[`MyComponent should render initial layout 1`] = ` Array [ , ] `;

ข้อเสียของการแก้ไขสแน็ปช็อตอันดับแรกคือลำดับของอุปกรณ์ประกอบฉาก (หรือแอตทริบิวต์) มีความสำคัญ

Jest จะเรียงอุปกรณ์ประกอบฉากที่ได้รับตามตัวอักษรใน expect ก่อนที่จะตรวจสอบกับสแนปชอต ดังนั้นเราควรระบุตามลำดับนั้น

หลังจากดำเนินการทดสอบเราได้รับข้อผิดพลาดต่อไปนี้:

Received value does not match stored snapshot 1. Expected: - Array [ onChange={[Function]} , ] Actual: + Array [ , ]

เพื่อให้การทดสอบนี้ผ่านเราสามารถจัดเตรียมฟังก์ชันว่างให้กับ onChange

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { render() { return {}} type='text' /> ; } }

จากนั้นตรวจสอบให้แน่ใจว่าสถานะของคอมโพเนนต์เปลี่ยนไปหลังจาก onChange เหตุการณ์ถูกส่งไป

อึก vs grunt vs webpack

ในการดำเนินการนี้เราจะสร้างการทดสอบหน่วยใหม่ซึ่งจะเรียกว่า onChange ฟังก์ชันในอินพุตโดยส่งไฟล์ เหตุการณ์ เพื่อเลียนแบบเหตุการณ์จริงใน UI

จากนั้นเราจะตรวจสอบว่าส่วนประกอบนั้น สถานะ มีคีย์ชื่อ input

// MyComponent.test.js ... it('should create an entry in component state', () => { // given const component = shallow(); const form = component.find('input'); // when form.props().onChange({target: { name: 'myName', value: 'myValue' }}); // then expect(component.state('input')).toBeDefined(); });

ตอนนี้เราได้รับข้อผิดพลาดต่อไปนี้

Expected value to be defined, instead received undefined

สิ่งนี้บ่งชี้ว่าคอมโพเนนต์ไม่มีคุณสมบัติในสถานะที่เรียกว่า input

เราทำให้การทดสอบผ่านไปโดยการตั้งค่ารายการนี้ในสถานะของส่วนประกอบ

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { render() { return {this.setState({input: ''})}} type='text' /> ; } }

จากนั้นเราต้องแน่ใจว่ามีการตั้งค่าในรายการสถานะใหม่ เราจะได้ค่านี้จากเหตุการณ์

ลองสร้างการทดสอบที่ทำให้แน่ใจว่าสถานะมีค่านี้

// MyComponent.test.js ... it('should create an entry in component state with the event value', () => { // given const component = shallow(); const form = component.find('input'); // when form.props().onChange({target: { name: 'myName', value: 'myValue' }}); // then expect(component.state('input')).toEqual('myValue'); }); ~~~ Not surprisingly, we get the following error. ~~ Expected value to equal: 'myValue' Received: ''

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

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { render() { return { this.setState({input: event.target.value})}} type='text' /> ; } }

หลังจากแน่ใจว่าการทดสอบทั้งหมดผ่านแล้วเราสามารถเปลี่ยนรหัสของเราใหม่ได้

เราสามารถแยกฟังก์ชั่นที่ส่งผ่านใน onChange สนับสนุนฟังก์ชันใหม่ที่เรียกว่า updateState

// MyComponent.js import React from 'react'; export default class MyComponent extends React.Component { updateState(event) { this.setState({ input: event.target.value }); } render() { return ; } }

ตอนนี้เรามีคอมโพเนนต์ React.js ง่ายๆที่สร้างโดยใช้ TDD

โปรแกรมที่เขียนด้วย c++

สรุป

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

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

การใช้กระบวนการ TDD ที่เข้มงวดน้อยกว่าก็ใช้ได้เช่นกันและอาจใช้งานได้ดี

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

หากคุณสนใจที่จะเรียนรู้เพิ่มเติมเกี่ยวกับ TDD และการพัฒนาที่ขับเคลื่อนด้วยพฤติกรรม (BDD) โปรดอ่าน เจ้านายของคุณจะไม่ชื่นชม TDD โดยเพื่อน ApeeScapeer Ryan Wilcox

ทำความเข้าใจพื้นฐาน

การพัฒนาที่ขับเคลื่อนด้วยการทดสอบคืออะไร?

การพัฒนาที่ขับเคลื่อนด้วยการทดสอบเป็นกระบวนการพัฒนาซอฟต์แวร์ตามลำดับที่เราเขียนรหัสทดสอบและการผลิต โดยสรุปเราต้องการให้น้อยที่สุดทั้งรหัสทดสอบที่จำเป็นในการล้มเหลวและรหัสการผลิตที่จำเป็นในการผ่าน

ส่วนประกอบของปฏิกิริยาคืออะไร?

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

ความจริงเสริมกับ ความจริงเสมือนกับ ความเป็นจริงผสม: คู่มือเบื้องต้น

การออกแบบ Ux

ความจริงเสริมกับ ความจริงเสมือนกับ ความเป็นจริงผสม: คู่มือเบื้องต้น
การใช้ Spring Boot สำหรับการใช้งาน WebSocket กับ STOMP

การใช้ Spring Boot สำหรับการใช้งาน WebSocket กับ STOMP

แบ็คเอนด์

โพสต์ยอดนิยม
แหล่งข้อมูลสำหรับธุรกิจขนาดเล็กสำหรับ COVID-19: เงินกู้เงินช่วยเหลือและสินเชื่อ
แหล่งข้อมูลสำหรับธุรกิจขนาดเล็กสำหรับ COVID-19: เงินกู้เงินช่วยเหลือและสินเชื่อ
วิธีออกแบบประสบการณ์ที่ยอดเยี่ยมสำหรับอินเทอร์เน็ตในทุกสิ่ง
วิธีออกแบบประสบการณ์ที่ยอดเยี่ยมสำหรับอินเทอร์เน็ตในทุกสิ่ง
กลยุทธ์การสื่อสารที่มีประสิทธิภาพสำหรับนักออกแบบ
กลยุทธ์การสื่อสารที่มีประสิทธิภาพสำหรับนักออกแบบ
เรียนรู้ Markdown: เครื่องมือการเขียนสำหรับนักพัฒนาซอฟต์แวร์
เรียนรู้ Markdown: เครื่องมือการเขียนสำหรับนักพัฒนาซอฟต์แวร์
แนวโน้มต่อไปนี้: การแสดงความเคารพกับการลอกเลียนแบบการออกแบบ
แนวโน้มต่อไปนี้: การแสดงความเคารพกับการลอกเลียนแบบการออกแบบ
 
คู่มือสไตล์ Sass: บทช่วยสอน Sass เกี่ยวกับวิธีการเขียนโค้ด CSS ที่ดีขึ้น
คู่มือสไตล์ Sass: บทช่วยสอน Sass เกี่ยวกับวิธีการเขียนโค้ด CSS ที่ดีขึ้น
ทำลายกระบวนการคิดเชิงออกแบบ
ทำลายกระบวนการคิดเชิงออกแบบ
การออกแบบเว็บไซต์ CMS: คู่มือการใช้งานเนื้อหาแบบไดนามิก
การออกแบบเว็บไซต์ CMS: คู่มือการใช้งานเนื้อหาแบบไดนามิก
ทำคณิตศาสตร์: การปรับขนาดแอปพลิเคชันไมโครเซอร์วิสด้วย Orchestrators
ทำคณิตศาสตร์: การปรับขนาดแอปพลิเคชันไมโครเซอร์วิสด้วย Orchestrators
การปฏิวัติหุ่นยนต์เชิงพาณิชย์ที่กำลังจะเกิดขึ้น
การปฏิวัติหุ่นยนต์เชิงพาณิชย์ที่กำลังจะเกิดขึ้น
โพสต์ยอดนิยม
  • หน้าจอ @media และ (ความกว้างสูงสุด:
  • aws โซลูชั่นสถาปนิก - สอบร่วม
  • คลังข้อมูลไม่รวมข้อมูลที่ซื้อจากแหล่งภายนอก
  • ผู้รับเหมา vs เงินเดือนประจำ
  • ตำแหน่งบริการ Google Play api
หมวดหมู่
  • การจัดการวิศวกรรม
  • บุคลากรและทีมงานของผลิตภัณฑ์
  • อื่น ๆ
  • นวัตกรรม
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt