React Components ทำให้การทดสอบ UI เป็นเรื่องง่าย
เผยแพร่แล้ว: 2022-03-11การทดสอบแบ็กเอนด์เป็นเรื่องง่าย คุณใช้ภาษาที่คุณเลือก จับคู่กับเฟรมเวิร์กโปรด เขียนการทดสอบ แล้วกด "เรียกใช้" คอนโซลของคุณพูดว่า "Yay! มันได้ผล!" บริการบูรณาการอย่างต่อเนื่องของคุณทำการทดสอบของคุณในทุก ๆ แรงผลักดัน ชีวิตนั้นยอดเยี่ยม
แน่นอนว่าการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ (TDD) นั้นแปลกในตอนแรก แต่สภาพแวดล้อมที่คาดการณ์ได้ ตัวดำเนินการทดสอบหลายตัว เครื่องมือทดสอบที่รวมอยู่ในเฟรมเวิร์ก และการสนับสนุนการผสานรวมอย่างต่อเนื่อง ทำให้ชีวิตง่ายขึ้น เมื่อห้าปีที่แล้ว ฉันคิดว่าการทดสอบเป็นวิธีแก้ปัญหาทุกปัญหาที่ฉันเคยมี
จากนั้น Backbone ก็ใหญ่ขึ้น
เราทุกคนเปลี่ยนไปใช้ MVC ส่วนหน้า แบ็กเอนด์ที่ทดสอบได้ของเรากลายเป็นเซิร์ฟเวอร์ฐานข้อมูลที่ได้รับการยกย่อง โค้ดที่ซับซ้อนที่สุดของเราถูกย้ายไปยังเบราว์เซอร์ และแอปของเราก็ไม่สามารถทดสอบได้ในทางปฏิบัติอีกต่อไป
นั่นเป็นเพราะการทดสอบโค้ดส่วนหน้าและส่วนประกอบ UI นั้นค่อนข้างยาก
ไม่ใช่เรื่องเลวร้ายหากเราต้องการเพียงตรวจสอบว่าแบบจำลองของเราทำงานได้ดี หรือการเรียกใช้ฟังก์ชันนั้นจะเปลี่ยนค่าที่ถูกต้อง สิ่งที่เราต้องทำสำหรับการทดสอบหน่วย React คือ:
- เขียนโมดูลที่มีรูปแบบที่ดีและแยกออกมา
- ใช้การทดสอบจัสมินหรือมอคค่า (หรืออะไรก็ตาม) เพื่อเรียกใช้ฟังก์ชัน
- ใช้นักวิ่งทดสอบ เช่น Karma หรือ Chutzpah
แค่นั้นแหละ. รหัสของเราได้รับการทดสอบหน่วย
เมื่อก่อนการ เรียกใช้ การทดสอบส่วนหน้าเป็นส่วนที่ยาก ทุกเฟรมเวิร์กมีแนวคิดเป็นของตัวเอง และในกรณีส่วนใหญ่ คุณจะได้หน้าต่างเบราว์เซอร์ที่คุณจะรีเฟรชเองทุกครั้งที่คุณต้องการทำการทดสอบ แน่นอนคุณมักจะลืม อย่างน้อยฉันก็รู้ว่าฉันทำ
ในปี 2555 Vojta Jina ได้เปิดตัว Karma runner (ในเวลานั้นเรียกว่า Testacular) ด้วย Karma การทดสอบส่วนหน้าจะกลายเป็นพลเมืองเต็มรูปแบบของห่วงโซ่เครื่องมือ การทดสอบ React ของเราทำงานในเทอร์มินัลหรือบนเซิร์ฟเวอร์การรวมอย่างต่อเนื่อง โดยจะเรียกใช้ซ้ำเองเมื่อเราเปลี่ยนไฟล์ และเรายังสามารถทดสอบโค้ดของเราในเบราว์เซอร์หลายตัวพร้อมกันได้
เราต้องการอะไรอีก? เพื่อทดสอบโค้ดส่วนหน้าของเรา จริงๆ
การทดสอบส่วนหน้าต้องการมากกว่าการทดสอบหน่วย
การทดสอบหน่วยนั้นยอดเยี่ยม: เป็นวิธีที่ดีที่สุดในการดูว่าอัลกอริธึมทำสิ่งที่ถูกต้องทุกครั้งหรือไม่ หรือเพื่อตรวจสอบตรรกะการตรวจสอบความถูกต้องอินพุตของเรา หรือการแปลงข้อมูล หรือการดำเนินการแยกอื่นๆ การทดสอบหน่วยเหมาะสำหรับพื้นฐาน
แต่โค้ดส่วนหน้าไม่ได้เกี่ยวกับการจัดการข้อมูล เกี่ยวกับเหตุการณ์ของผู้ใช้และการแสดงมุมมองที่ถูกต้องในเวลาที่เหมาะสม ส่วนหน้าเป็นเรื่องเกี่ยวกับผู้ใช้
นี่คือสิ่งที่เราต้องการจะทำ:
- ทดสอบ React เหตุการณ์ผู้ใช้
- ทดสอบการตอบสนองต่อเหตุการณ์เหล่านั้น
- ตรวจสอบให้แน่ใจว่าสิ่งที่ถูกต้องแสดงในเวลาที่เหมาะสม
- ทำการทดสอบในหลายเบราว์เซอร์
- เรียกใช้การทดสอบอีกครั้งเกี่ยวกับการเปลี่ยนแปลงไฟล์
- ทำงานร่วมกับระบบการรวมอย่างต่อเนื่องเช่น Travis
ในช่วงสิบปีที่ฉันทำสิ่งนี้ ฉันไม่พบวิธีที่เหมาะสมในการทดสอบการโต้ตอบของผู้ใช้และดูการเรนเดอร์จนกระทั่งฉันเริ่มลองใช้ React
การทดสอบหน่วยตอบสนอง: ส่วนประกอบ UI
ปฏิกิริยาเป็นวิธีที่ง่ายที่สุดในการบรรลุเป้าหมายเหล่านี้ ส่วนหนึ่ง เนื่องจากวิธีที่มันบังคับให้เราออกแบบแอปโดยใช้รูปแบบที่ทดสอบได้ ส่วนหนึ่งเป็นเพราะมีเครื่องมือทดสอบ React ที่ยอดเยี่ยม
หากคุณไม่เคยใช้ React มาก่อน คุณควรตรวจสอบหนังสือของฉัน React+d3.js มันมุ่งสู่การแสดงภาพ แต่ฉันบอกว่ามัน เป็น
React บังคับให้เราสร้างทุกอย่างเป็น "ส่วนประกอบ" คุณสามารถคิดว่าส่วนประกอบ React เป็นวิดเจ็ตหรือเป็นส่วนของ HTML ที่มีตรรกะบางอย่าง พวกเขาปฏิบัติตามหลักการที่ดีที่สุดหลายประการของการเขียนโปรแกรมเชิงฟังก์ชัน ยกเว้นว่าเป็นวัตถุ
ตัวอย่างเช่น เมื่อกำหนดพารามิเตอร์ชุดเดียวกัน องค์ประกอบ React จะแสดงเอาต์พุตเดียวกันเสมอ ไม่ว่าจะเรนเดอร์กี่ครั้ง ไม่ว่าใครจะเรนเดอร์ก็ตาม ไม่ว่าเราจะวางเอาต์พุตไว้ที่ใด เหมือนเดิมเสมอ ด้วยเหตุนี้ เราจึงไม่ต้องดำเนินการนั่งร้านที่ซับซ้อนเพื่อทดสอบส่วนประกอบ React พวกเขาสนใจเฉพาะคุณสมบัติของพวกเขา ไม่จำเป็นต้องติดตามตัวแปรส่วนกลางและออบเจ็กต์การกำหนดค่า
เราบรรลุเป้าหมายส่วนใหญ่โดยหลีกเลี่ยงสถานะ คุณจะเรียกความโปร่งใสในการอ้างอิงนี้ในการเขียนโปรแกรมเชิงฟังก์ชัน ฉันไม่คิดว่าจะมีชื่อพิเศษสำหรับสิ่งนี้ใน React แต่เอกสารอย่างเป็นทางการแนะนำให้หลีกเลี่ยงการใช้สถานะให้มากที่สุด
เมื่อพูดถึงการทดสอบการโต้ตอบของผู้ใช้ React ได้กล่าวถึงเหตุการณ์ที่เกี่ยวข้องกับการเรียกกลับของฟังก์ชัน ตั้งค่าสายลับทดสอบได้ง่าย และตรวจสอบให้แน่ใจว่าเหตุการณ์การคลิกเรียกใช้ฟังก์ชันที่ถูกต้อง และเนื่องจากส่วนประกอบ React แสดงตัวเอง เราจึงสามารถทริกเกอร์เหตุการณ์การคลิกและตรวจสอบ HTML สำหรับการเปลี่ยนแปลงได้ สิ่งนี้ใช้ได้เพราะองค์ประกอบ React ใส่ใจในตัวเองเท่านั้น การคลิก ที่นี่ ไม่เปลี่ยนแปลงสิ่งต่างๆ ที่ นั่น เราจะไม่ต้องจัดการกับตัวจัดการเหตุการณ์ที่ซ้อนกัน เพียงแค่เรียกใช้ฟังก์ชันที่กำหนดไว้อย่างดี
โอ้ และเนื่องจาก React เป็นเวทมนตร์ เราจึงไม่ต้องกังวลเกี่ยวกับ DOM React ใช้สิ่งที่เรียกว่า virtual DOM เพื่อแสดงผลส่วนประกอบเป็นตัวแปร JavaScript และการอ้างอิงถึง DOM เสมือนคือสิ่งที่เราต้องการเพื่อทดสอบส่วนประกอบ React จริงๆ
มันสวยหวาน
TestUtils
ของ React
React มาพร้อมกับชุด TestUtils
ในตัว มีนักวิ่งทดสอบที่แนะนำชื่อ Jest แต่ฉันไม่ชอบมัน ฉันจะอธิบายว่าทำไมในอีกสักครู่ ก่อนอื่น TestUtils
.
เราได้รับโดยทำสิ่งที่ต้องการ require('react/addons').addons.TestUtils
นี่คือจุดเริ่มต้นของเราในการทดสอบการโต้ตอบของผู้ใช้และตรวจสอบผลลัพธ์
React TestUtils
ช่วยให้เราเรนเดอร์องค์ประกอบ React โดยใส่ DOM ของมันในตัวแปร แทนที่จะแทรกลงในหน้า ตัวอย่างเช่น ในการเรนเดอร์องค์ประกอบ React เราจะทำสิ่งนี้:
var component = TestUtils.renderIntoDocument( <MyComponent /> );
จากนั้นเราสามารถใช้ TestUtils
เพื่อตรวจสอบว่าลูกทั้งหมดถูกเรนเดอร์หรือไม่ บางอย่างเช่นนี้:
var h1 = TestUtils.findRenderedDOMComponentWithTag( component, 'h1' );
findRenderedDOMComponentWithTag
จะทำสิ่งที่ดูเหมือน: ผ่านเด็ก ๆ ค้นหาองค์ประกอบที่เรากำลังมองหาและส่งคืน ค่าที่ส่งคืนจะทำงานเหมือนส่วนประกอบ React
จากนั้นเราสามารถใช้ getDOMNode()
เพื่อเข้าถึงองค์ประกอบ DOM ดิบและทดสอบค่าของมัน ในการตรวจสอบว่าแท็ก h1
ในคอมโพเนนต์ระบุว่า "A title" เราจะเขียนสิ่งนี้:
expect(h1.getDOMNode().textContent) .toEqual("A title");
เมื่อรวมกันแล้ว การทดสอบแบบเต็มจะมีลักษณะดังนี้:
it("renders an h1", function () { var component = TestUtils.renderIntoDocument( <MyComponent /> ); var h1 = TestUtils.findRenderedDOMComponentWithTag( component, 'h1' ); expect(h1.getDOMNode().textContent) .toEqual("A title"); });
ส่วนเด็ดคือ TestUtils ช่วยให้เราทริกเกอร์เหตุการณ์ของผู้ใช้ได้เช่นกัน สำหรับเหตุการณ์คลิก เราจะเขียนดังนี้:
var node = component .findRenderedDOMComponentWithTag('button') .getDOMNode(); TestUtils.Simulate.click(node);
สิ่งนี้จำลองการคลิกและทริกเกอร์ผู้ฟังที่เป็นไปได้ ซึ่งควรเป็นเมธอดของคอมโพเนนต์ที่เปลี่ยนเอาต์พุต สถานะ หรือทั้งสองอย่าง ผู้ฟังเหล่านั้นสามารถเรียกใช้ฟังก์ชันบนองค์ประกอบหลักได้หากจำเป็น
ทุกกรณีง่ายต่อการทดสอบ: สถานะที่เปลี่ยนแปลงอยู่ใน component.state
เราสามารถเข้าถึงเอาต์พุตด้วยฟังก์ชัน DOM ปกติ และการเรียกใช้ฟังก์ชันด้วยสายลับ
ทำไมไม่ตลก?
เอกสารทางการของ React แนะนำให้ใช้ https://facebook.github.io/jest/ เป็นตัวดำเนินการทดสอบและกรอบการทดสอบ React Jest สร้างขึ้นจากจัสมินและใช้รูปแบบเดียวกัน เหนือสิ่งอื่นใดที่คุณได้รับจากจัสมิน Jest ยังล้อเลียนทุกอย่าง ยกเว้นองค์ประกอบที่เรากำลังทดสอบ นี่เป็นเรื่องที่ยอดเยี่ยมในทางทฤษฎี แต่ฉันคิดว่ามันน่ารำคาญ อะไรก็ตามที่เรายังไม่ได้ใช้งาน หรือที่มาจากส่วนอื่นของ codebase นั้น undefined
แม้ว่าจะเป็นเรื่องปกติในหลายกรณี แต่ก็สามารถนำไปสู่ข้อผิดพลาดที่ล้มเหลวอย่างเงียบๆ
ฉันมีปัญหาในการทดสอบเหตุการณ์การคลิก เป็นต้น ไม่ว่าฉันจะพยายามทำอะไร มันก็ไม่เรียกมันว่าผู้ฟัง จากนั้นฉันก็รู้ว่าฟังก์ชันนี้ถูกล้อเลียนโดย Jest และมันไม่เคยบอกฉันเลย
แต่ความผิดที่เลวร้ายที่สุดของ Jest คือเมื่อก่อนไม่มีโหมดนาฬิกาเพื่อทดสอบการเปลี่ยนแปลงใหม่โดยอัตโนมัติ เราสามารถเรียกใช้ได้ครั้งเดียว รับผลการทดสอบ เท่านี้ก็เรียบร้อย (ฉันชอบทำการทดสอบในเบื้องหลังขณะทำงาน มิฉะนั้น ฉันลืมทำการทดสอบ) ปัจจุบันนี้ไม่ใช่ปัญหาอีกต่อไป
โอ้ และ Jest ไม่รองรับการทดสอบ React ในเบราว์เซอร์หลายตัว นี่เป็นปัญหาน้อยกว่าที่เคยเป็นมา แต่ฉันรู้สึกว่ามันเป็นคุณสมบัติที่สำคัญสำหรับโอกาสที่หายากนั้น heisenbug เกิดขึ้นใน Chrome เวอร์ชันใดรุ่นหนึ่งเท่านั้น...
หมายเหตุบรรณาธิการ: เนื่องจากบทความนี้ถูกเขียนขึ้นครั้งแรก Jest จึงมีการปรับปรุงอย่างมาก คุณสามารถอ่านบทช่วยสอนล่าสุดของเรา การทดสอบหน่วยตอบสนองโดยใช้เอนไซม์และ Jest และตัดสินใจด้วยตัวเองว่าการทดสอบ Jest นั้นขึ้นอยู่กับงานในปัจจุบันหรือไม่
การทดสอบปฏิกิริยา: ตัวอย่างแบบบูรณาการ
อย่างไรก็ตาม เราได้เห็นแล้วว่าการทดสอบ Front-end React ที่ดีควรทำงานอย่างไรในทางทฤษฎี มาลองใช้ตัวอย่างสั้นๆ กัน
เราจะเห็นภาพวิธีต่างๆ ในการสร้างตัวเลขสุ่มโดยใช้องค์ประกอบ scatterplot ที่สร้างด้วย React และ d3.js รหัสและการสาธิตนั้นอยู่ใน Github ด้วย
เราจะใช้ Karma เป็นตัวดำเนินการทดสอบ Mocha เป็นเฟรมเวิร์กการทดสอบ และใช้ Webpack เป็นตัวโหลดโมดูล
การตั้งค่า
ไฟล์ต้นฉบับของเราจะไปอยู่ใน <root>/src
และเราจะใส่การทดสอบลงใน <root>/src/__tests__
แนวคิดก็คือเราสามารถใส่ไดเร็กทอรีหลายรายการไว้ใน src
หนึ่งรายการสำหรับแต่ละองค์ประกอบหลัก และแต่ละไดเร็กทอรีมีไฟล์ทดสอบของตัวเอง การรวมซอร์สโค้ดและไฟล์ทดสอบในลักษณะนี้ช่วยให้นำส่วนประกอบ React มาใช้ซ้ำในโปรเจ็กต์ต่างๆ ได้ง่ายขึ้น
ด้วยโครงสร้างไดเร็กทอรี เราสามารถติดตั้งการพึ่งพาได้ดังนี้:
$ npm install --save-dev react d3 webpack babel-loader karma karma-cli karma-mocha karma-webpack expect
หากติดตั้งอะไรไม่ได้ ให้ลองเรียกใช้ส่วนนั้นอีกครั้งของการติดตั้ง NPM บางครั้งล้มเหลวในลักษณะที่หายไปในการเรียกใช้ซ้ำ
ไฟล์ package.json
ของเราควรมีลักษณะดังนี้เมื่อเราทำเสร็จแล้ว:
// package.json { "name": "react-testing-example", "description": "A sample project to investigate testing options with ReactJS", "scripts": { "test": "karma start" }, // ... "homepage": "https://github.com/Swizec/react-testing-example", "devDependencies": { "babel-core": "^5.2.17", "babel-loader": "^5.0.0", "d3": "^3.5.5", "expect": "^1.6.0", "jsx-loader": "^0.13.2", "karma": "^0.12.31", "karma-chrome-launcher": "^0.1.10", "karma-cli": "0.0.4", "karma-mocha": "^0.1.10", "karma-sourcemap-loader": "^0.3.4", "karma-webpack": "^1.5.1", "mocha": "^2.2.4", "react": "^0.13.3", "react-hot-loader": "^1.2.7", "react-tools": "^0.13.3", "webpack": "^1.9.4", "webpack-dev-server": "^1.8.2" } }
หลังจากกำหนดค่าบางอย่าง เราจะสามารถเรียกใช้การทดสอบด้วย npm test
หรือ karma start

Config
มีการกำหนดค่าไม่มาก เราต้องทำให้แน่ใจว่า Webpack รู้วิธีค้นหาโค้ดของเรา และ Karma รู้วิธีเรียกใช้การทดสอบ
เราใส่ JavaScript สองบรรทัดในไฟล์ ./tests.webpack.js
เพื่อช่วยให้ Karma และ Webpack เล่นด้วยกัน:
// tests.webpack.js var context = require.context('./src', true, /-test\.jsx?$/); context.keys().forEach(context);
สิ่งนี้บอกให้ Webpack พิจารณาทุกอย่างที่มีส่วนต่อท้าย -test
เพื่อเป็นส่วนหนึ่งของชุดการทดสอบ
การกำหนดค่า Karma ใช้เวลานานขึ้นเล็กน้อย:
// karma.conf.js var webpack = require('webpack'); module.exports = function (config) { config.set({ browsers: ['Chrome'], singleRun: true, frameworks: ['mocha'], files: [ 'tests.webpack.js' ], preprocessors: { 'tests.webpack.js': ['webpack'] }, reporters: ['dots'], webpack: { module: { loaders: [ {test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'} ] }, watch: true }, webpackServer: { noInfo: true } }); };
บรรทัดเหล่านี้ส่วนใหญ่มาจากการกำหนดค่า Karma เริ่มต้น เราใช้ browsers
เพื่อบอกว่าการทดสอบควรทำงานใน Chrome frameworks
ร์กเพื่อระบุเฟรมเวิร์กการทดสอบที่เรากำลังใช้ และ singleRun
เพื่อให้การทดสอบทำงานเพียงครั้งเดียวโดยค่าเริ่มต้น คุณสามารถให้กรรมทำงานในพื้นหลังด้วย karma start --no-single-run
สามคนนี้ชัดเจน สิ่งที่ Webpack น่าสนใจยิ่งขึ้น
เนื่องจาก Webpack จัดการแผนผังการขึ้นต่อกันของโค้ด เราจึงไม่ต้องระบุไฟล์ทั้งหมดของเราในอาร์เรย์ของ files
เราต้องการแค่ tests.webpack.js
ซึ่งต้องใช้ไฟล์ที่จำเป็นทั้งหมด
เราใช้การตั้งค่า webpack
เพื่อบอก Webpack ว่าต้องทำอย่างไร ในสภาพแวดล้อมปกติ ส่วนนี้จะอยู่ในไฟล์ webpack.config.js
นอกจากนี้เรายังบอกให้ Webpack ใช้ babel-loader
สำหรับ JavaScript ของเรา สิ่งนี้ทำให้เรามีคุณสมบัติใหม่แฟนซีจาก ECMAScript2015 และ JSX ของ React
ด้วยการกำหนดค่า webpackServer
เราบอก Webpack ไม่ให้พิมพ์ข้อมูลการดีบักใดๆ มันจะเสียผลการทดสอบของเราเท่านั้น
ส่วนประกอบปฏิกิริยาและการทดสอบ
ด้วยชุดทดสอบที่กำลังรันอยู่ ที่เหลือก็เป็นเรื่องง่าย เราจะต้องสร้างองค์ประกอบที่ยอมรับอาร์เรย์ของพิกัดสุ่มและสร้างองค์ประกอบ <svg>
ที่มีคะแนนจำนวนมาก
การปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดในการทดสอบ React เช่น แนวทางปฏิบัติ TDD มาตรฐาน เราจะเขียนการทดสอบก่อน จากนั้นจึงเขียนองค์ประกอบ React จริง เริ่มต้นด้วยไฟล์ทดสอบวานิลลาใน src/__tests__/
:
// ScatterPlot-test.jsx var React = require('react/addons'), TestUtils = React.addons.TestUtils, expect = require('expect'), ScatterPlot = require('../ScatterPlot.jsx'); var d3 = require('d3'); describe('ScatterPlot', function () { var normal = d3.random.normal(1, 1), mockData = d3.range(5).map(function () { return {x: normal(), y: normal()}; }); });
อันดับแรก เราต้องการ React, TestUtils, d3.js, ไลบรารีของ expect
และโค้ดที่เรากำลังทดสอบ จากนั้นเราสร้างชุดทดสอบใหม่พร้อม describe
และสร้างข้อมูลแบบสุ่ม
สำหรับการทดสอบครั้งแรก ให้ตรวจสอบให้แน่ใจว่า ScatterPlot
แสดงชื่อ การทดสอบของเราเข้าไปอยู่ในบล็อก describe
:
// ScatterPlot-test.jsx it("renders an h1", function () { var scatterplot = TestUtils.renderIntoDocument( <ScatterPlot /> ); var h1 = TestUtils.findRenderedDOMComponentWithTag( scatterplot, 'h1' ); expect(h1.getDOMNode().textContent).toEqual("This is a random scatterplot"); });
การทดสอบส่วนใหญ่จะเป็นไปตามรูปแบบเดียวกัน:
- แสดงผล
- ค้นหาโหนดเฉพาะ
- ตรวจสอบเนื้อหา
ดังที่เราได้เห็นก่อนหน้านี้แล้ว renderIntoDocument
แสดงผลองค์ประกอบของเรา findRenderedDOMComponentWithTag
ค้นหาส่วนเฉพาะที่เรากำลังทดสอบ และ getDOMNode
ให้สิทธิ์การเข้าถึง DOM แบบดิบแก่เรา
ในตอนแรกการทดสอบของเราจะล้มเหลว เพื่อให้ผ่าน เราต้องเขียนองค์ประกอบที่แสดงแท็กชื่อ:
var React = require('react/addons'); var d3 = require('d3'); var ScatterPlot = React.createClass({ render: function () { return ( <div> <h1>This is a random scatterplot</h1> </div> ); } }); module.exports = ScatterPlot;
แค่นั้นแหละ. คอมโพเนนต์ ScatterPlot
แสดงผล <div>
ด้วยแท็ก <h1>
ที่มีข้อความที่คาดไว้ และการทดสอบของเราจะผ่าน ใช่ มันยาวกว่าแค่ HTML แต่อดทนไว้
วาดส่วนที่เหลือของนกฮูก
คุณสามารถดูตัวอย่างที่เหลือใน GitHub ตามที่กล่าวไว้ข้างต้น เราจะข้ามการอธิบายทีละขั้นตอนในบทความนี้ แต่กระบวนการทั่วไปจะเหมือนกับข้างต้น ฉันต้องการแสดงให้คุณเห็นการทดสอบที่น่าสนใจกว่านี้ การทดสอบที่ทำให้แน่ใจว่าจุดข้อมูลทั้งหมดแสดงบนแผนภูมิ:
// ScatterPlot-test.jsx it("renders a circle for each datapoint", function () { var scatterplot = TestUtils.renderIntoDocument( <ScatterPlot data={mockData} /> ); var circles = TestUtils.scryRenderedDOMComponentsWithTag( scatterplot, 'circle' ); expect(circles.length).toEqual(5); });
เหมือน แต่ก่อน. แสดงผล ค้นหาโหนด ตรวจสอบผลลัพธ์ ส่วนที่น่าสนใจคือการวาดโหนด DOM เหล่านั้น เราเพิ่มเวทย์มนตร์ d3.js ให้กับองค์ประกอบ ScatterPlot
ดังนี้:
// ScatterPlot.jsx componentWillMount: function () { this.yScale = d3.scale.linear(); this.xScale = d3.scale.linear(); this.update_d3(this.props); }, componentWillReceiveProps: function (newProps) { this.update_d3(newProps); }, update_d3: function (props) { this.yScale .domain([d3.min(props.data, function (d) { return dy; }), d3.max(props.data, function (d) { return dy; })]) .range([props.point_r, Number(props.height-props.point_r)]); this.xScale .domain([d3.min(props.data, function (d) { return dx; }), d3.max(props.data, function (d) { return dx; })]) .range([props.point_r, Number(props.width-props.point_r)]); }, ...
เราใช้ componentWillMount
เพื่อตั้งค่ามาตราส่วน d3 ที่ว่างเปล่าสำหรับโดเมน X และ Y และ componentWillReceiveProps
เพื่อให้แน่ใจว่าจะอัปเดตเมื่อมีการเปลี่ยนแปลง จากนั้น update_d3
ตรวจสอบให้แน่ใจว่าได้ตั้งค่า domain
และ range
สำหรับสเกลทั้งสองแล้ว
เราจะใช้มาตราส่วนทั้งสองเพื่อแปลระหว่างค่าสุ่มในชุดข้อมูลและตำแหน่งบนรูปภาพ เครื่องกำเนิดแบบสุ่มส่วนใหญ่ส่งคืนตัวเลขในช่วง [0,1] ซึ่งเล็กเกินกว่าจะมองว่าเป็นพิกเซล
จากนั้นเราเพิ่มคะแนนให้กับวิธีการเรนเดอร์ของส่วนประกอบของเรา:
// ScatterPlot.jsx render: function () { return ( <div> <h1>This is a random scatterplot</h1> <svg width={this.props.width} height={this.props.height}> {this.props.data.map(function (pos, i) { var key = "circle-"+i; return ( <circle key={key} cx={this.xScale(pos.x)} cy={this.yScale(pos.y)} r={this.props.point_r} /> ); }.bind(this))}; </svg> </div> ); }
รหัสนี้ผ่านอาร์เรย์ this.props.data
และเพิ่มองค์ประกอบ <circle>
สำหรับแต่ละจุดข้อมูล เรียบง่าย.
หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการรวม React และ d3.js เพื่อสร้างองค์ประกอบการแสดงข้อมูลเป็นภาพ นั่นเป็นอีกเหตุผลที่ดีในการดูหนังสือของฉัน React+d3.js
การทดสอบส่วนประกอบปฏิกิริยาอัตโนมัติ: ง่ายกว่าเสียง
นั่นคือทั้งหมดที่เราต้องรู้เกี่ยวกับการเขียนส่วนประกอบ front-end ที่ทดสอบได้ด้วย React หากต้องการดูส่วนประกอบ React ของการทดสอบโค้ดเพิ่มเติม ให้ลองดู Codebase ตัวอย่างการทดสอบ React บน Github ตามที่กล่าวไว้ข้างต้น
เราได้เรียนรู้ว่า:
- React บังคับให้เราแยกส่วนและห่อหุ้ม
- ทำให้การทดสอบ React UI เป็นแบบอัตโนมัติได้ง่าย
- การทดสอบหน่วยไม่เพียงพอสำหรับส่วนหน้า
- กรรมเป็นนักวิ่งทดสอบที่ยอดเยี่ยม
- Jest มีศักยภาพ แต่ยังไม่ค่อยมี (หรืออาจจะเป็นตอนนี้ก็ได้)
หากคุณชอบบทความนี้ ติดตามฉันบน Twitter และแสดงความคิดเห็นด้านล่าง ขอบคุณสำหรับการอ่านและขอให้มีความสุขกับการทดสอบ React!