Next.js ใช้หลักสูตรการพัฒนาซึ่งทำให้วิธีการทดสอบนำมาใช้โดยห้องสมุดนี้ล้าสมัย หน้าถัดไปผู้ดูแลผู้ดูแลแนะนำให้ใช้การทดสอบเบราว์เซอร์แทน
เครื่องมือทดสอบการรวม DOM ที่หายไปสำหรับ Next.js
ด้วยเส้นทางถัดไป JS ไลบรารีนี้จะ แสดงหน้าการจับคู่ใน JSDOM ซึ่งมี อุปกรณ์ประกอบฉาก ที่คาดหวังที่ได้จาก ระบบการกำหนดเส้นทาง ถัดไปของ JS และ วิธีการดึงข้อมูล
import { getPage } from 'next-page-tester' ;
import { screen , fireEvent } from '@testing-library/react' ;
describe ( 'Blog page' , ( ) => {
it ( 'renders blog page' , async ( ) => {
const { render } = await getPage ( {
route : '/blog/1' ,
} ) ;
render ( ) ;
expect ( screen . getByText ( 'Blog' ) ) . toBeInTheDocument ( ) ;
fireEvent . click ( screen . getByText ( 'Link' ) ) ;
await screen . findByText ( 'Linked page' ) ;
} ) ;
} ) ; แนวคิดที่อยู่เบื้องหลังห้องสมุดนี้คือการทำซ้ำอย่างใกล้ชิดที่สุดเท่าที่จะเป็นไปได้ในวิธีต่อไป JS ทำงานโดยไม่ต้องปั่นเซิร์ฟเวอร์และแสดงผลในสภาพแวดล้อม JSDOM ท้องถิ่น
เพื่อให้ประสบการณ์การทดสอบที่มีค่าผ่าน next-page-tester จำลอง การเรนเดอร์ของแอปพลิเคชัน next.js จริง :
head ) แอปพลิเคชันที่ติดตั้งนั้นมี การโต้ตอบ และสามารถทดสอบได้ด้วยไลบรารีการทดสอบ DOM ใด ๆ (เช่น @testing-library/react )
next-page-tester จะดูแล:
getServerSideProps , getInitialProps หรือ getStaticProps ) หากกรณี_app และ _document ที่กำหนดเองLink , router.push , router.replaceredirect หน้าเว็บnext/router , next/head , next/link , next/config และตัวแปรสภาพแวดล้อม getPage ยอมรับวัตถุตัวเลือกและส่งคืนค่า 4 ค่า:
import { getPage } from 'next-page-tester' ;
const { render , serverRender , serverRenderToString , page } = await getPage ( {
options ,
} ) ; ประเภท: () => { nextRoot: HTMLElement<NextRoot> }
ส่งคืน: องค์ประกอบองค์ประกอบรูท #__next
หากคุณไม่ได้มีกรณีการใช้งานขั้นสูงคุณควรใช้วิธีนี้เป็นส่วนใหญ่ ภายใต้ฮูดมันเรียกว่า serverRender() จากนั้นติดตั้ง/ให้ความชุ่มชื้นกับแอปพลิเคชัน React ลงในองค์ประกอบ JSDOM #__next นี่คือสิ่งที่ผู้ใช้จะได้รับ/ดูเมื่อพวกเขาเยี่ยมชมหน้า
ประเภท: () => { nextRoot: HTMLElement<NextRoot> }
ส่งคืน: องค์ประกอบองค์ประกอบรูท #__next
ฉีดเอาต์พุตของการแสดงผลด้านเซิร์ฟเวอร์ลงใน DOM แต่ไม่ติดตั้งปฏิกิริยา ใช้เพื่อทดสอบว่า next.js แสดงผลในสถานการณ์ต่อไปนี้:
ประเภท: () => { html: string }
แสดงผลเอาต์พุตของการแสดงผลด้านเซิร์ฟเวอร์เป็นสตริง HTML นี่เป็นวิธีที่บริสุทธิ์โดยไม่มีผลข้างเคียง
ประเภท: React.ReactElement<AppElement>
องค์ประกอบตอบสนองของแอปพลิเคชัน
| คุณสมบัติ | คำอธิบาย | พิมพ์ | ค่าเริ่มต้น |
|---|---|---|---|
| เส้นทาง (บังคับ) | เส้นทางต่อไป (ต้องเริ่มต้นด้วย / ) | string | - |
| req | ปรับปรุงวัตถุคำขอล้อเลียนเริ่มต้น | req => req | - |
| ความละเอียด | ปรับปรุงวัตถุการตอบสนองที่ถูกล้อเลียนเริ่มต้น | res => res | - |
| เราเตอร์ | ปรับปรุงวัตถุเราเตอร์ถัดไปที่ล้อเลียนเริ่มต้น | router => router | - |
| USEAPP | แสดงส่วนประกอบแอพที่กำหนดเอง | boolean | true |
| แสดงส่วนประกอบเอกสาร | boolean | false | |
| การตี | เส้นทางที่แน่นอนไปยังโฟลเดอร์รูท next.js | string | ตรวจพบอัตโนมัติ |
| dotenvfile | เส้นทางสัมพัทธ์ไปยังตัวแปรสภาพแวดล้อมการถือครองไฟล์ .env | string | - |
| เสื้อคลุม | เส้นทางที่แน่นอนไปยังไฟล์ wrappers มีประโยชน์ในการตกแต่งต้นไม้ส่วนประกอบด้วยผู้ให้บริการที่ล้อเลียน | string | - |
| SharedModules | รายการของโมดูลที่ควรเก็บรักษาตัวตนระหว่างบริบทไคลเอนต์และเซิร์ฟเวอร์ | string[] | - |
หากหน้า/ส่วนประกอบของคุณนำเข้า ประเภทไฟล์ที่ไม่ได้รับการจัดการโดย node.js (เช่นแผ่นสไตล์, รูปภาพ, .svg , ... ) คุณควรกำหนดค่าสภาพแวดล้อมการทดสอบของคุณเพื่อประมวลผลอย่างถูกต้อง เช่นในกรณีที่ตลกคุณอาจต้องการกำหนดค่า moduleNameMapper
next-page-tester คาดว่าจะพบกับสภาพแวดล้อม JSDOM หากใช้ jest เพิ่มบรรทัดนี้ในการกำหนดค่า jest ของคุณ:
"testEnvironment" : "jsdom" , เนื่องจาก next.js ไม่ได้ถูกออกแบบมาให้ทำงานในสภาพแวดล้อม JSDOM เราจำเป็นต้อง ตั้งค่า JSDOM เริ่มต้น เพื่อให้ได้รับประสบการณ์การทดสอบที่ราบรื่นขึ้น โดยค่า next-page-tester จะ:
window.scrollTo และ IntersectionObserver mocks อย่างไรก็ตามคุณอาจเลือกที่จะข้ามการล้างข้อมูลอัตโนมัติและผู้ช่วยเริ่มต้นโดยการตั้งค่าตัวแปร NPT_SKIP_AUTO_SETUP Env เป็น true คุณสามารถทำได้ด้วย cross-env เช่นนี้:
cross - env NPT_SKIP_AUTO_SETUP = true jestหากใช้ Jest V26 คุณอาจต้องแก้ไขเพื่อโหลดโมดูลด้วยสภาพแวดล้อมเซิร์ฟเวอร์/ไคลเอนต์ที่เหมาะสม ความพยายามในการบำรุงรักษาจะกำหนดเป้าหมายเวอร์ชันตลกล่าสุด
ภายใต้ตัวอย่างโฟลเดอร์เราบันทึกกรณีการทดสอบซึ่งเปิดใช้ next-page-tester
next-page-tester มุ่งเน้นไปที่การสนับสนุนเฉพาะรุ่นสุดท้ายของ next.js และ jest:
| หน้าหน้า | next.js | ล้อเล่น |
|---|---|---|
| v0.1.0 -> v0.7.0 | v9.xx | v26.xx |
| v0.8.0 -> v0.22.0 | v10.0.0 -> v10.0.7 | |
| v0.23.0 -> v0.25.x | v10.0.8 -> v11.0.x | |
| v0.26.0 -> v0.27.x | v10.0.8 -> v11.0.x | v27.xx |
| v0.28.0 -> v0.28.x | v11.1.0 | |
| v0.29.0 + | v11.1.1 -> v11.x | |
| v0.31.0 + | v12.1.0 | |
| v0.32.0 + | v12.1.1 + |
เนื่องจาก:
โปรดทราบว่าเราไม่สามารถรับประกันการสนับสนุนสำหรับรุ่นต่อไปของ next.js ออกจากกล่อง แม้แต่แพตช์หรือรุ่นรองอาจแตก ในกรณีนี้คุณจะต้องรอรุ่น next-page-tester ใหม่ที่จะเปิดตัว
การมีส่วนร่วมยินดีต้อนรับอย่างมากและเราพยายามอย่างเต็มที่เพื่อสนับสนุนผู้มีส่วนร่วมภายนอก
req และ res จะถูกล้อเลียนด้วยโหนด mocks-http@types/react-dom และ @types/webpack เมื่อใช้ typescrip ในโหมด strict เนื่องจากข้อผิดพลาดนี้useDocument งาน ตัวเลือก useDocument ถูกนำไปใช้บางส่วนและอาจไม่เสถียร
วิธีที่แนะนำครั้งแรกในการเยาะเย้ยคำขอเครือข่ายประกอบด้วย การเยาะเย้ยที่เลเยอร์เครือข่าย ที่มีห้องสมุดเช่น Mock service worker และ Mirage JS
อีกวิธีหนึ่งที่มีศักยภาพอาจประกอบด้วย การเยาะเย้ยวัตถุ Global fetch กับไลบรารีเช่น fetch-mock
ในกรณีที่คุณต้องการวิธีการแบบดั้งเดิมมากขึ้นที่เกี่ยวข้องกับการเยาะเย้ยโมดูลที่ดินผู้ใช้ที่รับผิดชอบในการดึงข้อมูลคุณต้องพิจารณาขั้นตอนพิเศษ: เนื่องจาก next-page-tester แยกโมดูลระหว่าง "ไคลเอนต์" และ "เซิร์ฟเวอร์" การแสดงผลการเยาะเย้ยเหล่านั้นที่สร้างขึ้นในการทดสอบ (บริบทไคลเอนต์) จะไม่ดำเนินการในบริบทของเซิร์ฟเวอร์
เพื่อเอาชนะสิ่งนั้นเราจำเป็นต้อง "taint" โมดูลดังกล่าวเป็น (รักษา/แบ่งปัน) ตัวตนของพวกเขาระหว่างบริบท "ไคลเอนต์" และ "เซิร์ฟเวอร์" โดยส่งผ่านพวกเขาผ่านตัวเลือก sharedModules
test ( 'as a user I want to mock a module in client & server environment' , async ( ) => {
const stub = jest . spyOn ( api , 'getData' ) . mockReturnValue ( Promise . resolve ( 'data' ) )
const { render } = await getPage ( {
route : '/page' ,
nextRoot ,
sharedModules : [ ` ${ process . cwd ( ) } /src/path/to/my/module` ] ,
} ) ;
expect ( stub ) . toHaveBeenCalledTimes ( 1 ) ; // this was executed in your data fetching method
} คุณสามารถตั้งค่าคุกกี้ได้โดยผนวกเข้ากับ document.cookie ก่อนโทรหา getPage next-page-tester จะเผยแพร่คุกกี้ไปยัง ctx.req.headers.cookie เพื่อให้พวกเขาสามารถใช้วิธีการดึงข้อมูล นอกจากนี้ยังใช้กับวิธีการดึงข้อมูลที่ตามมาเรียกว่าทริกเกอร์โดยการนำทางไคลเอนต์
test ( 'authenticated page' , async ( ) => {
document . cookie = 'SessionId=super=secret' ;
document . cookie = 'SomeOtherCookie=SomeOtherValue' ;
const { render } = await getPage ( {
route : '/authenticated' ,
} ) ;
render ( ) ;
} ) ; หมายเหตุ: document.cookie ไม่ได้รับการทำความสะอาดโดยอัตโนมัติ คุณจะต้องล้างด้วยตนเองหลังจากการทดสอบแต่ละครั้งเพื่อให้ทุกอย่างอยู่แยกกัน
next.js ส่วนประกอบ Link เรียกใช้ window.scrollTo เมื่อคลิกซึ่งไม่ได้ใช้งานในสภาพแวดล้อม JSDOM ในการแก้ไขข้อผิดพลาดคุณควรตั้งค่าสภาพแวดล้อมการทดสอบของคุณหรือให้ window.scrollTo ของคุณเอง
คำเตือนนี้หมายความว่าหน้าของคุณแสดงผลแตกต่างกันระหว่างเซิร์ฟเวอร์และเบราว์เซอร์ นี่อาจเป็นพฤติกรรมที่คาดหวังหรือส่งสัญญาณบั๊กในรหัสของคุณ
คำเตือนนี้หมายความว่าแอปพลิเคชันของคุณในระหว่างกระบวนการเรนเดอร์ดำเนินการตามคำขอเครือข่ายบางอย่างที่ยังไม่ได้ล้อเลียน คุณควรค้นหาพวกเขาและเยาะเย้ยตามต้องการ
trailingSlash next.js trailingslash_error ที่กำหนดเองdebug เพื่อบันทึกข้อมูลการดำเนินการ ขอบคุณไปที่คนที่ยอดเยี่ยมเหล่านี้ (คีย์อีโมจิ):
Andrea Carraro - | Matej Šnuderl - | เจสันวิลเลียมส์ - | arelaxend - | Kfazinic - | Tomasz Rondio - | Alexander Mendes |
Jan Sepke - | Davidorchard - | Doaa Ismael - | Andrew Hurle - | Massimeddu-Sonic - | Jess Telford - | โจเซฟ - |
Gergo Tolnai - | เบร็ท - | วลาด Elagin | Daniel Stockman | Madeuz | ดร. ดีเร็กออสติน - | ความกลัว - |
Jan R. Biasi - | Otávio Augusto Soares - |
โครงการนี้เป็นไปตามข้อกำหนดทั้งหมดของผู้เข้าร่วม การมีส่วนร่วมทุกชนิดยินดีต้อนรับ!