มาดำดิ่งสู่ Cypress เพื่อการทดสอบแบบ End-to-End

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ การทดสอบแบบ end-to-end เป็นหัวข้อที่เจ็บปวดสำหรับคุณหรือไม่? ในบทความนี้ Ramona Schwering อธิบายวิธีจัดการกับการทดสอบแบบ end-to-end ด้วย Cypress และทำให้มันไม่น่าเบื่อและมีราคาแพงสำหรับตัวคุณเอง แต่สนุกแทน

การพัฒนาซอฟต์แวร์โดยไม่ใช้การทดสอบอัตโนมัติเป็นเรื่องยากที่จะจินตนาการได้ในปัจจุบัน ขั้นตอนการทดสอบต่างๆ ที่หลากหลายจะช่วยรับประกันคุณภาพในระดับสูง เป็นพื้นฐานสำหรับการทดสอบ เราสามารถใช้การทดสอบหน่วยจำนวนหนึ่งได้ ยิ่งไปกว่านั้น ตรงกลางของปิรามิดนั้นเป็นการทดสอบการรวมเข้าด้วยกัน การทดสอบแบบ end-to-end อยู่ที่ระดับบนสุด ครอบคลุมกรณีการใช้งานที่สำคัญที่สุด การทดสอบประเภทที่สามนี้จะเป็นจุดสนใจของบทความนี้

อย่างไรก็ตาม การทดสอบแบบ end-to-end มีข้อผิดพลาดบางประการ ที่ทำให้เกิดความกังวล:

  • การทดสอบแบบ end-to-end นั้นช้า ดังนั้นจึงเป็นอุปสรรคสำคัญในทุกกลยุทธ์การผสานรวมอย่างต่อเนื่องและการปรับใช้อย่างต่อเนื่อง (CI/CD) ไม่เพียงแค่นั้น แต่ลองจินตนาการว่าการทำงาน คุณลักษณะ หรือการใช้งานอื่นๆ เสร็จสิ้น การรอการทดสอบดำเนินการอาจทำให้ทุกคนหมดความอดทน
  • การทดสอบแบบ end-to-end ดังกล่าวยากต่อการบำรุงรักษา เกิดข้อผิดพลาดได้ง่าย และมีราคาแพงในทุกวิถีทางเนื่องจากการพยายามแก้ไขจุดบกพร่อง ปัจจัยต่าง ๆ อาจทำให้เกิดสิ่งนี้ การทดสอบของคุณควรรู้สึกเหมือนเป็นผู้ช่วย ไม่เป็นอุปสรรค
  • ฝันร้ายที่ใหญ่ที่สุดสำหรับนักพัฒนาคือการทดสอบที่ไม่สม่ำเสมอ ซึ่งเป็นการทดสอบที่ดำเนินการในลักษณะเดียวกัน แต่นำไปสู่ผลลัพธ์ที่แตกต่างกัน มันเหมือนกับ “Heisenbug” ซึ่งจะเกิดขึ้นหากคุณไม่ได้วัดแอปพลิเคชันที่กำลังทดสอบ นั่นคือถ้าคุณไม่ดู
ไฮเซนบักส์
Heisenfails เป็นของจริงและคล้ายกับ Heisenbugs (ตัวอย่างขนาดใหญ่)

แต่อย่ากังวล: คุณไม่จำเป็นต้องยอมจำนนต่อข้อผิดพลาดเหล่านี้ เรามาดูวิธีการป้องกันหลายๆ อย่างกัน อย่างไรก็ตาม ฉันจะไม่เพียงแค่สัญญากับดวงจันทร์และไม่ส่งมอบ ในคู่มือนี้ เราจะเขียนการทดสอบร่วมกัน ซึ่งเราได้เผยแพร่ให้กับคุณในที่เก็บ GitHub ด้วยวิธีนี้ ฉันหวังว่าจะแสดงให้คุณเห็นว่าการทดสอบ end-end เป็นเรื่องสนุก! มาเริ่มกันเลย.

การทดสอบแบบ End-to-End คืออะไร?

เมื่อพูดถึงการทดสอบแบบ end-to-end (หรือ E2E) ฉันชอบที่จะเรียกว่าเป็น "ตามเวิร์กโฟลว์" วลีนี้สรุปผลการทดสอบแบบ end-to-end ได้ดี: จำลองเวิร์กโฟลว์ของผู้ใช้จริงและควรรวมพื้นที่การทำงานและส่วนต่าง ๆ ของสแต็กเทคโนโลยีที่ใช้ในแอปพลิเคชันให้มากที่สุด ในที่สุดคอมพิวเตอร์ก็ปลอมตัวเป็นลูกค้าและพยายามทำตัวเหมือนผู้ใช้จริง การทดสอบเหล่านี้เหมาะที่สุดสำหรับการใช้ความเค้นคงที่กับทั้งระบบของแอปพลิเคชันของคุณ ดังนั้นจึง เป็นการวัดที่ยอดเยี่ยมในการรับรองคุณภาพ เมื่อมีแอปพลิเคชันสแต็กทั้งหมด

หุ่นยนต์
การทดสอบแบบ end-to-end ดำเนินการโดยคอมพิวเตอร์จำลองผู้ใช้จริง (ตัวอย่างขนาดใหญ่)

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

นี่เป็นคำถามที่ถูกต้อง คุณอาจพบคำตอบที่เป็นไปได้ในคำอุปมา: ปิรามิดระบบอัตโนมัติสำหรับการทดสอบ ซึ่งเปิดตัวครั้งแรกโดย Mike Cohn และระบุเพิ่มเติมโดย Martin Fowler แสดง วิธีทำให้การทดสอบมีประสิทธิภาพ เราพบการทดสอบหน่วยที่รวดเร็วและราคาถูกที่ระดับพีระมิดที่ต่ำที่สุด และการทดสอบ UI ที่ใช้เวลานานและมีราคาแพง (การทดสอบแบบ end-to-end) ที่ด้านบน

ปิรามิดทดสอบ
ปิรามิดทดสอบระบบอัตโนมัติ (ตัวอย่างขนาดใหญ่)

การอธิบายสิ่งนี้และข้อดีและข้อเสียก็เพียงพอแล้วสำหรับบทความของตัวเอง ฉันต้องการเน้นในระดับหนึ่ง การทดสอบแบบ end-to-end โดยเฉพาะสามารถนำมาปรับปรุงคุณภาพได้อย่างมากหากจัดลำดับความสำคัญอย่างมีประสิทธิภาพ ในการทำเช่นนั้น เราสามารถทำให้ระบบของเราอยู่ภายใต้ความเครียดได้อย่างต่อเนื่อง และทำให้แน่ใจว่าฟังก์ชันหลักของแอปพลิเคชันของเราทำงานอย่างถูกต้อง

การเดินทางของฉันสู่ Cypress

เมื่อฉันเริ่มเรียนรู้วิธีเขียนการทดสอบแบบ end-to-end ฉันใช้ Mink ซึ่งเป็นไลบรารี PHP ที่ด้านบนของ Behat ซึ่งเป็นเฟรมเวิร์กการพัฒนาที่ขับเคลื่อนโดยพฤติกรรมตามสถานการณ์ (BDD) ฉันเริ่มใช้ซีลีเนียมโดยมีข้อดีและข้อเสียทั้งหมด เนื่องจากทีมของฉันเริ่มทำงานกับ Vue.js เป็นจำนวนมาก เราจึงเปลี่ยนไปใช้เฟรมเวิร์กการทดสอบที่ใช้ JavaScript เพื่อให้แน่ใจว่ามีการผสานรวมและเข้ากันได้อย่างไม่มีที่ติ ตัวเลือกของเราในตอนนั้นคือ Nightwatch.js ดังนั้นฉันจึงสร้างชุดทดสอบใหม่ตั้งแต่ต้น

ในช่วงเวลานี้ เรามักพบปัญหาความเข้ากันได้ คุณสามารถเรียกมันว่า การพึ่งพาอาศัยกัน — ไม่ต้องพูดถึงข้อจำกัดทั้งหมดที่เราเห็นใน Selenium และในภายหลังด้วย WebDriver

  • ในทีมของเรา เราไม่สามารถตรึง CI เวอร์ชัน Chrome ของเราได้ ดังนั้น หากมีการอัปเดต Chrome ออกมา Nightwatch.js ไม่เร็วพอที่จะเข้ากันได้ ทำให้เกิดความล้มเหลวมากมายในไปป์ไลน์การทดสอบของเรา
  • จำนวนสาเหตุด้านทดสอบของการทดสอบที่ไม่สม่ำเสมอเริ่มเพิ่มขึ้น เนื่องจากความเป็นไปได้ในการรอของ Nightwatch.js ไม่ตรงกับผลิตภัณฑ์ของเราอย่างเหมาะสมที่สุด

ดังนั้นเราจึงมาพิจารณาสร้างชุดทดสอบของเราใหม่ หลังจากเยี่ยมชมการประชุม ฉันก็พบ Cypress

Cypress เป็นเฟรมเวิร์กการทดสอบแบบ all-in-one ที่ไม่ใช้ Selenium หรือ WebDriver เครื่องมือนี้ใช้ Node.js เพื่อเริ่มเบราว์เซอร์ภายใต้การควบคุมพิเศษ การทดสอบในเฟรมเวิร์กนี้ทำงานในระดับเบราว์เซอร์ ไม่ใช่แค่การควบคุมจากระยะไกล ที่มีข้อดีหลายประการ

กล่าวโดยย่อ นี่คือเหตุผลที่ฉันเลือกเฟรมเวิร์กนี้:

  • ความสามารถในการดีบักที่ยอดเยี่ยม
    ตัวดำเนินการทดสอบของ Cypress สามารถย้อนกลับไปยังสถานะใดก็ได้ของแอปพลิเคชันผ่านสแนปชอต ดังนั้นเราจึงสามารถเห็นข้อผิดพลาดและขั้นตอนทั้งหมดก่อนหน้านั้นได้โดยตรง นอกจากนี้ยังมีการเข้าถึงเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome (DevTools) อย่างเต็มรูปแบบ และการคลิกจะได้รับการบันทึกอย่างสมบูรณ์
  • วิธีที่ดีกว่าในการรอการดำเนินการในการทดสอบหรือ UI หรือในการตอบกลับจาก API
    Cypress ทำให้เกิดการรอโดยปริยาย ดังนั้นจึงไม่จำเป็นต้องมีการตรวจสอบที่เหมาะสม คุณยังทำให้การทดสอบรอภาพเคลื่อนไหวและการตอบสนอง API ได้อีกด้วย
  • การทดสอบเขียนด้วยจาวาสคริปต์
    สิ่งนี้ช่วยลดเส้นโค้งการเรียนรู้ในการเขียนการทดสอบ ตัวดำเนินการทดสอบของ Cypress เป็นโอเพ่นซอร์ส ดังนั้นจึงเหมาะกับกลยุทธ์ผลิตภัณฑ์ของเรา

อย่างไรก็ตาม บทความนี้เป็นเพียงแนวทาง ดังนั้นเรามาหยุดที่ข้อมูลทั่วไปและไปต่อกันดีกว่า

เริ่มต้น

ติดตั้งและเริ่ม Cypress

เริ่มจากศูนย์กันก่อน ในการพูดของฉันเกี่ยวกับ Cypress ฉันมักจะเริ่มต้นด้วยการสร้างไดเร็กทอรีใหม่ผ่าน mkdir แล้วติดตั้ง Cypress ทันที วิธีที่ง่ายที่สุดในการติดตั้งแสดงในภาพวาดนี้:

Cypress ใช้ Node.js
Cypress ใช้ Node.js (ตัวอย่างขนาดใหญ่)

คำแนะนำเล็กน้อย: หากคุณไม่ต้องการใช้ npm คุณสามารถติดตั้ง Cypress ผ่าน Yarn:

 yarn add cypress --dev

ทางเลือกอื่นคือการดาวน์โหลดโดยตรง โดยใช้โฟลเดอร์ ZIP ที่ Cypress จัดเตรียมให้ แค่นั้นแหละ! เมื่อการติดตั้งเสร็จสิ้น คุณก็พร้อมที่จะเริ่มต้น

มีสองวิธีในการเริ่มการทดสอบ Cypress อย่างแรกคือการเริ่ม Cypress ในคอนโซล และรันการทดสอบของคุณแบบไม่มีส่วนหัว:

 ./node_modules/.bin/cypress run

วิธีที่สองคือการใช้หนึ่งในคุณสมบัติที่เรียบร้อยของ Cypress ซึ่งเป็นตัวดำเนินการทดสอบแบบรวม ผู้ทดสอบคือ UI สำหรับการเรียกใช้การทดสอบ ในการเปิดใช้งาน คุณสามารถใช้คำสั่งที่คล้ายกัน:

 ./node_modules/.bin/cypress open

คำสั่งนี้จะเปิดตัวดำเนินการทดสอบ เมื่อคุณเปิด Cypress เป็นครั้งแรก คุณจะเห็นอินเทอร์เฟซนี้:

รองชนะเลิศอันดับ Cypress
นักวิ่งทดสอบของ Cypress ตั้งแต่แรกเห็น (ตัวอย่างขนาดใหญ่)

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

ความประทับใจครั้งแรกของโครงสร้างของ Cypress

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

 smashing-example └── cypress └── fixtures └── integration └── plugins └── support └── cypress.json

มาดูโฟลเดอร์เหล่านี้กัน:

  • fixtures
    ที่นี่คุณจะพบข้อมูลการทดสอบแบบตายตัว ซึ่งไม่เกี่ยวข้องกับเอนทิตีอื่นๆ ดังนั้นจึงไม่มีการจัดเก็บ ID ไว้ที่นี่ ซึ่งสามารถเปลี่ยนแปลงได้ตามสถานะในเครื่อง
  • integration
    คุณจะพบการทดสอบจริงที่นี่
  • plugins
    ที่นี่ คุณสามารถขยาย Cypress ไม่ว่าจะด้วยปลั๊กอิน Cypress ที่มีอยู่หรือของคุณเอง
  • support
    ที่นี่ คุณสามารถขยาย Cypress ได้เอง คำสั่งและผู้ช่วยของคุณเองอยู่ที่นี่
  • cypress.json
    แก้ไขการกำหนดค่าที่นี่ รวมถึงสำหรับสภาพแวดล้อม

เอาล่ะ ฉันคิดว่าเราสามารถหาทางไปรอบๆ Cypress ได้แล้ว ไม่ว่าจะเป็นผู้ทำการทดสอบหรือซอร์สโค้ด แต่เราจะเริ่มต้นอย่างไร เราต้องการทดสอบอะไร

เลือกกรณีทดสอบ

การทดสอบแบบ end-to-end ทั่วไปอาจมีความซับซ้อน โดยเฉพาะอย่างยิ่งหากมีขั้นตอนมากมาย การดำเนินการด้วยตนเองจะใช้เวลามาก เนื่องจากความซับซ้อนนี้ การทดสอบ E2E จึงเป็นระบบอัตโนมัติและทำงานช้าได้ยาก เป็นผลให้เราจำเป็นต้องตัดสินใจอย่างรอบคอบว่ากรณีใดที่จะทำให้เป็นอัตโนมัติ

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

ในทีมของฉัน เรามีเกณฑ์หลายประการสำหรับโครงการของเรา กรณีทดสอบควร:

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

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

ตัวอย่าง:

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

ตัวอย่าง: การค้นหาบทความของฉันใน Smashing Magazine

ฉันต้องการเขียนแบบทดสอบสำหรับเว็บไซต์นี้ Smashing Magazine ฉันไม่สามารถรับรองได้ว่าการทดสอบนี้จะเป็นปัจจุบันตลอดไป แต่หวังว่าการทดสอบนี้จะคงอยู่ตลอดไป ไม่ว่าจะด้วยวิธีใด คุณจะพบตัวอย่างนี้ในที่เก็บ GitHub

สร้างการทดสอบ Cypress ครั้งแรกของเรา

ในโฟลเดอร์ integration เราจะเริ่มต้นด้วยการสร้างไฟล์ใหม่ เรียกมัน find-author.spec.js คำต่อท้าย .spec ย่อมาจาก “ .spec ” ในแง่ของการทดสอบ หมายถึงรายละเอียดทางเทคนิคของคุณลักษณะหรือแอปพลิเคชันที่กำหนดซึ่งแอปพลิเคชันของคุณจะต้องปฏิบัติตาม

ในการเปลี่ยนไฟล์ JavaScript ที่ว่างเปล่านี้เป็นหน้าแรกของการทดสอบ เราจะเริ่มต้นด้วยการกำหนดโครงสร้างของชุดการทดสอบ เราจะใช้วิธีที่เรียกว่า describe describe() หรือ context() ใช้เพื่อบรรจุและจัดระเบียบการทดสอบ กล่าวอีกนัยหนึ่ง วิธีนี้ทำหน้าที่เป็นกรอบสำหรับการทดสอบของเรา ดังนั้น ไฟล์ทดสอบของเราจะมีลักษณะดังนี้:

 // find-author.spec.js describe('Find authors at smashing', () => { //... });

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

 // find-author.spec.js describe('Find authors at smashing', () => { it('Find the author Ramona Schwering', () => { cy.log('This is our brand-new test'); }); });

คำแนะนำเล็กน้อย : หากคุณคุ้นเคยกับ Mocha คุณอาจสังเกตเห็นความคล้ายคลึงกันบางอย่าง Cypress สร้างขึ้นบน Mocha ดังนั้นไวยากรณ์จึงเหมือนกัน

เอาล่ะ ไปกันเลย หากเราทำการทดสอบในโปรแกรมทดสอบของ Cypress เราจะสังเกตเห็นว่า Cypress จะเปิดเบราว์เซอร์เพื่อทำการทดสอบ เบราว์เซอร์นี้มีให้เห็นในภาพหน้าจอด้านล่าง:

การทดสอบครั้งแรกของเรา
การทดสอบครั้งแรกของเราดำเนินการในโปรแกรมทดสอบของ Cypress (ตัวอย่างขนาดใหญ่)

ยินดีด้วย! เราได้เขียนการทดสอบครั้งแรกของเรา! แน่นอนว่ามันไม่ได้ช่วยอะไรมาก เราจำเป็นต้องดำเนินการต่อ มาเติมบททดสอบด้วยชีวิตกันเถอะ

เติมบททดสอบด้วยชีวิต

สิ่งแรกที่ต้องทำเมื่อทดสอบเว็บไซต์คืออะไร ถูกต้อง เราต้องเปิดเว็บไซต์ เราสามารถทำได้โดยใช้คำสั่ง Cypress คำสั่งคืออะไรคุณอาจสงสัย?

การทำงานกับคำสั่ง

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

ดังนั้น คำสั่งแรกของเราคือคำสั่งที่นำทางไปยังเว็บไซต์ — smashingmagazine.com คำสั่งนี้เรียกว่า visit

เมื่อใช้การทดสอบของเราจะมีลักษณะดังนี้:

 // find-author.spec.js describe('Find authors at smashing', () => { it('Find the author Ramona Schwering', () => { cy.visit('https://www.smashingmagazine.com/'); }); });

มีคำสั่งหนึ่งที่ฉันใช้บ่อย – และคุณก็จะทำเช่นกัน เรียกว่า get :

 cy.get('selector');

คำสั่งนี้ส่งคืนองค์ประกอบตามตัวเลือก - คล้ายกับ $(…) ของ jQuery ดังนั้น คุณจะใช้คำสั่งนี้เพื่อค้นหาส่วนต่างๆ ที่จะโต้ตอบด้วย โดยปกติ คุณจะใช้มันเพื่อเริ่มชุดคำสั่ง แต่เดี๋ยวก่อน - สายการบังคับบัญชาหมายถึงอะไร?

ดังที่กล่าวไว้ในตอนต้นของบทความนี้ การทดสอบทั้งหมดและทุกอย่างอื่นที่เกี่ยวข้องนั้นเขียนด้วย JavaScript คุณสามารถใส่คำสั่งในการทดสอบ (เช่นคำสั่ง) ในห่วงโซ่ (กล่าวอีกนัยหนึ่ง) ซึ่งหมายความว่าคำสั่งสามารถส่งผ่านเรื่อง (หรือคืนค่า) ของคำสั่งไปยังคำสั่งต่อไปนี้ ตามที่เราทราบจากกรอบการทดสอบจำนวนมาก

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

โต้ตอบกับองค์ประกอบ

Cypress มีคุณสมบัติที่จะช่วยคุณค้นหาตัวเลือกขององค์ประกอบที่คุณต้องการใช้งาน คุณลักษณะนี้เรียกว่า Selector Playground และช่วยให้คุณค้นพบตัวเลือกเฉพาะของส่วนประกอบหรือเพื่อดูองค์ประกอบที่ตรงกันทั้งหมดสำหรับตัวเลือกหรือสตริงข้อความ ดังนั้น คุณลักษณะนี้สามารถช่วยคุณได้มากในงานนี้ หากต้องการเปิดใช้งาน เพียงคลิกไอคอนเป้าเล็งในส่วนหัวของ UI ของการทดสอบ แล้ววางเมาส์เหนือองค์ประกอบที่ต้องการ:

การใช้ตัวเลือกสนามเด็กเล่น
การใช้ Selector Playground เพื่อระบุตัวเลือกที่ไม่ซ้ำ (ตัวอย่างขนาดใหญ่)

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

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

ไม่ใช่ตัวเลือกในอุดมคติ
ตัวเลือกนี้อาจไม่เหมาะที่จะใช้ (ตัวอย่างขนาดใหญ่)

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

การค้นหาตัวเลือกผ่านเครื่องมือสำหรับนักพัฒนา
การใช้เครื่องมือสำหรับนักพัฒนาของเบราว์เซอร์เพื่อค้นหาตัวเลือกที่ไม่ซ้ำใคร (ตัวอย่างขนาดใหญ่)

เพื่อให้แน่ใจว่าตัวเลือกจะไม่ซ้ำกัน ฉันขอแนะนำให้ค้นหาในมุมมองโค้ดของ DevTools หากคุณพบผลลัพธ์เพียงรายการเดียว คุณสามารถมั่นใจได้ว่าผลลัพธ์นั้นไม่ซ้ำใคร

คุณรู้หรือไม่ว่า ซีเล็คเตอร์มีหลายประเภท ? การทดสอบอาจมีลักษณะและทำงานค่อนข้างแตกต่างไปจากเดิมอย่างสิ้นเชิง ทั้งนี้ขึ้นอยู่กับความหลากหลาย บางพันธุ์เหมาะสำหรับการทดสอบแบบ end-to-end มากกว่ารุ่นอื่นๆ หากคุณต้องการทราบว่าตัวเลือกใดที่จะใช้เพื่อให้การทดสอบของคุณมีความเสถียรและสะอาด ฉันสามารถแนะนำบทความของฉันที่ครอบคลุมปัญหานี้ให้คุณได้ นักพัฒนาของ Cypress เองได้ให้คำแนะนำเกี่ยวกับหัวข้อนี้ในแนวทางปฏิบัติที่ดีที่สุด

การทดสอบของเราเป็นลำดับของคำสั่ง

ตกลงกลับไปที่การทดสอบของเรา ในนั้น เราต้องการแสดงเวิร์กโฟลว์ของเรา:

“ในฐานะผู้ใช้ ฉันจะค้นหาบทความของผู้เขียนและไปที่เว็บไซต์ของผู้เขียนผ่านพื้นที่อ้างอิงในบทความของพวกเขา”

เราจะทำซ้ำขั้นตอนที่ผู้ใช้จะทำโดยใช้คำสั่ง ฉันจะวางด้านล่างการทดสอบเสร็จสิ้นพร้อมความคิดเห็น ซึ่งจะอธิบายขั้นตอนต่างๆ:

 // find-author.spec.js it('Find the author Ramona Schwering', () => { // Open the website cy.visit('https://www.smashingmagazine.com'); // Enter author's name in search field cy.get('#js-search-input').type('Ramona Schwering'); // Navigate to author's article cy.get('h2 > a').first().click(); // Open the author's page cy.get('.author-post__author-title').click(); });

ตัวอย่างนี้เกี่ยวข้องกับเวิร์กโฟลว์ที่เราต้องการทดสอบ Cypress จะดำเนินการทดสอบนี้ ถึงเวลากล่าวคำว่า "ยินดีด้วย" แล้วหรือยัง? ในที่สุดเราก็เขียนการทดสอบครั้งแรกเสร็จแล้วหรือยัง?

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

การทำงานกับการยืนยัน

คำสั่งประเภทที่สองดูแลคำอธิบายของสถานะที่ต้องการของ UI นั่นคือ ไม่ว่าบางสิ่งควรมีอยู่ มองเห็นได้ หรือไม่ปรากฏอีกต่อไป การยืนยันใน Cypress ขึ้นอยู่กับการยืนยันของ Chai และ Sinon-Chai ซึ่งสังเกตได้ชัดเจนในไวยากรณ์

จำไว้ว่าเราต้องการตรวจสอบว่าเราอยู่ในหน้าโปรไฟล์ของผู้เขียนหรือไม่ — ของฉันในตัวอย่างนี้ ดังนั้น เราต้องเพิ่มคำยืนยันให้แน่ชัดว่า:

 // find-author.spec.js it('Find the author Ramona Schwering', () => { // Open the website cy.visit('https://www.smashingmagazine.com'); // Enter author's name in search field cy.get('#js-search-input').type('Ramona Schwering'); // Navigate to author's article cy.get('h2 > a').first().click(); // Open the author's page cy.get('.author-post__author-title').click(); // Check if we're on the author's site cy.contains('.author__title', 'Ramona Schwering').should('be.visible'); });

เอาล่ะ ตอนนี้เราได้เขียนการทดสอบที่มีค่าแล้ว ใช่ ขอแสดงความยินดีกับการเขียนการทดสอบครั้งแรกของคุณ... แม้ว่าจะยังไม่สมบูรณ์แบบก็ตาม

มาทำให้การทดสอบของเราสวยขึ้น

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

ใช้เวลาของคุณ

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

เวลาในการทดสอบแบบ end-to-end
เวลาเป็นสิ่งสำคัญในการทดสอบแบบ end-to-end (ตัวอย่างขนาดใหญ่)

ผู้ใช้จะทำอย่างไรหากพวกเขาต้องการเห็นเว็บไซต์ที่ยังโหลดอยู่ พวกเขามักจะรอจนกว่าบางส่วนของเว็บไซต์จะมองเห็นได้ (ดังนั้น โหลดแล้ว) และโต้ตอบกับพวกเขา ในการทดสอบของเรา เราต้องการเลียนแบบอย่างแม่นยำว่า: เราต้องการ รอการเปลี่ยนแปลงใน UI ก่อนที่จะเริ่มโต้ตอบ ในกรณีส่วนใหญ่ เราจะจำกัดพฤติกรรมนี้ไว้ที่องค์ประกอบที่เราต้องการ ดังนั้นจึงใช้การยืนยันกับองค์ประกอบเหล่านั้น

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

ลองดูส่วนหนึ่งของการทดสอบของเราเป็นตัวอย่าง ฉันได้เพิ่มการยืนยันหนึ่งรายการเพื่อ ให้แน่ใจว่าหน้าของเราโหลดเต็มแล้ว :

 // find-author-assertions.spec.js // Open website cy.visit('https://www.smashingmagazine.com'); // Ensure site is fully loaded cy.get('.headline-content').should('be.visible'); // Enter author's name in the search field cy.get('#js-search-input').type('Ramona Schwering');

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

เพื่อหลีกเลี่ยงไม่ให้ตกหลุมพรางของการทดสอบที่ไม่สม่ำเสมอ ฉันอยากจะบอกใบ้สุดท้ายกับคุณ: อย่าใช้เวลารอแบบตายตัว เช่น cy.wait(500) หรืออื่นๆ ที่คล้ายกัน

การตอบสนอง API คือเพื่อนของคุณ

มีความเป็นไปได้อย่างหนึ่งในการรอโดยเฉพาะอย่างยิ่งที่ฉันชอบใช้ในการทดสอบของฉัน ใน Cypress คุณสามารถทำงานกับคุณลักษณะเครือข่ายได้ — อีกวิธีหนึ่งที่เป็นประโยชน์ในการรอในแอปพลิเคชันของคุณคือการ ใช้คุณสมบัติเหล่านี้เพื่อทำงานกับคำขอของเครือข่าย ด้วยวิธีนี้ คุณสามารถทำให้การทดสอบรอการตอบกลับ API ที่สำเร็จได้

หากเราจำเวิร์กโฟลว์ของเราเป็นตัวอย่างได้ ขั้นตอนเดียวอาจใช้ความเป็นไปได้ในการรอ API ได้อย่างดีเยี่ยม ฉันกำลังคิดเกี่ยวกับการค้นหา เรื่องราวของผู้ใช้ที่เกี่ยวข้องอาจเป็นดังนี้:

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

ลองใช้สิ่งนั้นกับการทดสอบของเรา อันดับแรก เราต้องกำหนดเส้นทางที่เราต้องการรอในภายหลัง เราสามารถใช้คำสั่ง intercept สำหรับสิ่งนี้ ฉันจะค้นหาคำขอโดยนำข้อมูลที่ฉันต้องการ – ผลการค้นหาในกรณีนี้

เพื่อให้ตัวอย่างนี้ง่ายขึ้น ฉันจะใช้สัญลักษณ์แทนสำหรับ URL หลังจากนั้น ฉันจะใช้นามแฝงเพื่อให้ Cypress สามารถทำงานกับเส้นทางนี้ได้ในภายหลัง

 // find-author-hooks.spec.js // Set the route to work with it('Find the author Ramona Schwering', () => { // Route to wait for later cy.intercept({ url: '*/indexes/smashingmagazine/*', method: 'POST' }).as('search'); // With this alias Cypress will find the request again //...

ใน Cypress เส้นทางที่กำหนดทั้งหมดจะแสดงที่จุดเริ่มต้นของการทดสอบ ดังนั้น ฉันอยากจะใส่คำสั่ง intercept เหล่านั้นไว้ที่จุดเริ่มต้นของการทดสอบของฉันด้วย

เส้นทาง API ในตัวดำเนินการทดสอบของ Cypress
เส้นทาง API จะแสดงที่ด้านบนของการทดสอบของเรา (ตัวอย่างขนาดใหญ่)

ตอนนี้ เราสามารถใช้นามแฝงของเส้นทางนี้ในการยืนยันได้ วิธีที่ง่ายที่สุดในการทำเช่นนี้คือใช้คำสั่ง wait ของ Cypress โดยใช้นามแฝงที่กล่าวถึงก่อนหน้านี้โดยตรง อย่างไรก็ตาม การใช้คำสั่งนี้เพียงอย่างเดียวอาจนำไปสู่การ รอการตอบสนองโดยไม่คำนึงถึงผลลัพธ์ แม้แต่รหัสข้อผิดพลาด เช่น 400 หรือ 500 ก็นับว่าผ่าน ในขณะที่แอปพลิเคชันของคุณมักจะใช้งานไม่ได้ ดังนั้นฉันขอแนะนำให้เพิ่มการยืนยันอื่นเช่นนี้:

 // find-author-hooks.spec.js // Later: Assertion of the search request's status code cy.wait('@search') .its('response.statusCode').should('equal', 200);
การยืนยันการตอบสนอง API
การยืนยันการตอบสนอง API ตามที่เห็นในตัวดำเนินการทดสอบของ Cypress (ตัวอย่างขนาดใหญ่)

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

การกำหนดค่า Cypress

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

 // Cypress describe('Find author at smashing', () => { beforeEach(() => { // Open website cy.visit('https://www.smashingmagazine.com'); }); //...

ฉันใช้สแลชเพื่อเปิดเว็บไซต์ของนิตยสาร Smashing เท่านั้น มันทำงานอย่างไร? การใช้คำสั่งแบบนี้จะนำทางไปยัง baseUrl ของการทดสอบของเรา baseUrl เป็นค่าคอนฟิกูเรชันที่สามารถใช้เป็นคำนำหน้าสำหรับ URL ของคำสั่ง cy.visit() หรือ cy.request() ในบรรดาค่าอื่นๆ เราสามารถกำหนดค่านี้ได้ในไฟล์ cypress.json สำหรับการทดสอบของเรา เราจะตั้งค่า baseUrl ดังนี้:

 // cypress.json { "baseUrl": "https://www.smashingmagazine.com" }

รางวัลชมเชย: Hooks

เหลืออีกหัวข้อหนึ่งที่ฉันอยากจะพูดถึง แม้ว่าการทดสอบตัวอย่างของเราจะไม่เหมาะกับการใช้งานก็ตาม ตามปกติในเฟรมเวิร์กการทดสอบอื่นๆ เราสามารถกำหนดสิ่งที่เกิดขึ้นก่อนและหลังการทดสอบของเราผ่านสิ่งที่เรียกว่า lifecycle hooks แม่นยำยิ่งขึ้น สิ่งเหล่านี้มีอยู่เพื่อรันโค้ดก่อนหรือหลังการทดสอบหนึ่งหรือทั้งหมด:

 // Cypress describe('Hooks', function() { before(() => { // Runs once before all tests }); after(() => { // Runs once after all tests }); beforeEach(() => { // Runs before each test }); afterEach(() => { // Runs after each test }); });

เราต้องการเติมไฟล์ทดสอบของเราด้วยการทดสอบมากกว่าหนึ่งรายการ ดังนั้นเราควรมองหาขั้นตอนทั่วไปที่เราต้องการดำเนินการก่อนหรือหลังการทดสอบ บรรทัดแรกของเราเป็นกรณีตัวอย่าง คือ คำสั่งการ visit สมมติว่าเราต้องการเปิดเว็บไซต์นี้ก่อนการทดสอบแต่ละครั้ง a beforeEach hook ในตัวอย่างของเราจะมีลักษณะดังนี้:

 // Cypress describe('Find author at smashing', () => { beforeEach(() => { // Open website cy.visit('https://www.smashingmagazine.com'); }); //... 
ก่อนตะขอแต่ละอัน
beforeEach hook จะแสดงในบันทึกของผู้วิ่งทดสอบ (ตัวอย่างขนาดใหญ่)

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

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

บทสรุป

ในความเห็นของฉัน การทดสอบแบบ end-to-end เป็นองค์ประกอบสำคัญของ CI ทำให้คุณภาพของแอปพลิเคชันอยู่ในระดับสูง และในขณะเดียวกันก็ช่วยลดการทำงานของผู้ทดสอบ Cypress เป็นเครื่องมือที่ฉันเลือกสำหรับการดีบักการทดสอบแบบ end-to-end อย่างรวดเร็ว เสถียร และมีประสิทธิภาพ และสำหรับการรันแบบขนานกับคำขอดึงใดๆ ซึ่งเป็นส่วนหนึ่งของ CI เส้นโค้งการเรียนรู้นั้นไม่ซับซ้อน หากคุณคุ้นเคยกับ JavaScript อยู่แล้ว

ฉันหวังว่าฉันจะสามารถแนะนำคุณได้เล็กน้อยและเป็นจุดเริ่มต้นในการเขียนการทดสอบ Cypress และคำแนะนำที่เป็นประโยชน์ในการเริ่มต้น แน่นอน ตัวอย่างโค้ดทั้งหมดมีอยู่ในที่เก็บ GitHub ดังนั้นลองดูตามสบาย

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

ทรัพยากร

  • ตัวอย่างยอดเยี่ยมดั้งเดิม Ramona Schwering
    ที่เก็บ GitHub สำหรับตัวอย่างในบทความนี้
  • เอกสาร Cypress
  • “สูตรอาหาร”, Cypress
    การเลือกตัวอย่าง สูตรอาหาร และหลักสูตร
  • “เรียนรู้การเขียนโค้ดด้วย JavaScript: Cypress” (บทเรียน), CodeLikeThis
  • แนวทางปฏิบัติที่ดีที่สุดในการเขียนการทดสอบตั้งแต่ต้นจนจบ”, Shopware Docs