การรวมการทดสอบ Cypress กับ Docker, Buildkite และ CICD #frontend@twiiosendgrid
เผยแพร่แล้ว: 2020-12-30เราได้เขียนการทดสอบ Cypress แบบ end-to-end (E2E) จำนวนมากเพื่อตรวจสอบว่าเว็บแอปพลิเคชันของเรายังคงทำงานตามที่คาดไว้กับแบ็กเอนด์ หลังจากเขียนการทดสอบการทำงานอัตโนมัติของเบราว์เซอร์แล้ว เราต้องการให้การทดสอบ Cypress ทำงานหรือถูกทริกเกอร์ในลักษณะใดลักษณะหนึ่ง เช่น การทดสอบหน่วยของเรา ก่อนที่เราจะรวมโค้ดและปรับใช้กับสภาพแวดล้อมบางอย่าง สิ่งนี้นำเราไปสู่เส้นทางที่ต้องการเรียกใช้การทดสอบ Cypress ในคอนเทนเนอร์ Docker เพื่อผสานรวมกับผู้ให้บริการการผสานรวมอย่างต่อเนื่อง (CI) และเครื่องที่เราใช้ในคลาวด์เพื่อเรียกใช้คอนเทนเนอร์เหล่านี้
เมื่อพูดถึงโฟลว์การปรับใช้ เราใช้ Buildkite เป็นผู้ให้บริการ CI ของเรา ซึ่งช่วยให้เราสามารถสร้างขั้นตอนอัตโนมัติสำหรับแอปพลิเคชันของเราในไปป์ไลน์ Buildkite เมื่อเราวางแผนที่จะย้ายโค้ดไปทั่วกระดาน สำหรับบริบทเพิ่มเติม ไปป์ไลน์เป็นที่ที่มักจะเชื่อมโยงกับที่เก็บของแอปพลิเคชัน ซึ่งเราสามารถดูบิลด์หรือทริกเกอร์บิลด์ด้วยขั้นตอนบางอย่างเพื่อรันเมื่อคุณสร้างคำขอดึง พุชการเปลี่ยนแปลงโค้ดใหม่ รวมโค้ดไปยังต้นแบบ และปรับใช้กับสภาพแวดล้อมที่แตกต่างกัน . เราสร้างไปป์ไลน์หลายอันเพื่อจุดประสงค์ที่แยกจากกัน เช่น สำหรับการปรับใช้ การทดสอบ Cypress ที่ทริกเกอร์ และการทดสอบ Cypress เฉพาะที่ทำงานตามกำหนดเวลา
โพสต์ในบล็อกนี้ถือว่าคุณเคยเขียนการทดสอบ Cypress มาก่อนแล้วและมีการทดสอบบางอย่างที่ทำงานอยู่ แต่ต้องการแนวคิดเกี่ยวกับวิธีการเรียกใช้การทดสอบเหล่านี้ตลอดเวลาในโฟลว์การพัฒนาและการปรับใช้ของคุณ หากคุณต้องการภาพรวมเพิ่มเติมเกี่ยวกับการเขียนการทดสอบ Cypress แทน คุณสามารถอ่านโพสต์บนบล็อกก่อนหน้านี้แล้วกลับมาดูอีกครั้งเมื่อคุณมีสิ่งที่จะเรียกใช้
เรามุ่งหวังที่จะแนะนำคุณเกี่ยวกับแนวคิดในการผสานรวมการทดสอบ Cypress ในคอนเทนเนอร์ Docker กับผู้ให้บริการ CI ของคุณ โดยพิจารณาว่าเราได้ดำเนินการกับ Docker Compose และ Buildkite อย่างไรในไปป์ไลน์การปรับใช้ของเรา แนวคิดเหล่านี้สามารถขยายได้ในโครงสร้างพื้นฐานของคุณสำหรับกลยุทธ์ คำสั่ง และตัวแปรสภาพแวดล้อมที่จะใช้เมื่อเรียกใช้การทดสอบ Cypress
การไหลของ CICD มาตรฐานของเรา
ในโฟลว์การพัฒนาและการปรับใช้มาตรฐานของเรา เราตั้งค่าไปป์ไลน์สองท่อ:
- ขั้นแรกจัดการขั้นตอนการปรับใช้ของเราเมื่อเราพุชโค้ด
- ประการที่สองทริกเกอร์การทดสอบ Cypress ของเราให้ทำงานแบบคู่ขนานและถูกบันทึกไว้ ความสำเร็จหรือความล้มเหลวของสิ่งนี้ส่งผลต่อไปป์ไลน์การปรับใช้
ในไปป์ไลน์การปรับใช้ของเรา เราสร้างเนื้อหาแอปพลิเคชันเว็บของเรา เรียกใช้การทดสอบหน่วย และมีขั้นตอนในการทริกเกอร์การทดสอบ Cypress ที่เลือกก่อนที่จะปรับใช้กับแต่ละสภาพแวดล้อม เราตรวจสอบให้แน่ใจว่าพวกเขาผ่านก่อนที่จะยกเลิกความสามารถในการใช้งานปุ่มกด การทดสอบ Cypress ที่ทริกเกอร์เหล่านี้ในไปป์ไลน์ที่สองยังทำงานในคอนเทนเนอร์ Docker และเชื่อมต่อกับ Cypress Dashboard แบบชำระเงิน ผ่านคีย์การบันทึก เพื่อให้เราสามารถย้อนกลับไปดูวิดีโอ ภาพหน้าจอ และเอาต์พุตคอนโซลจากการทดสอบ Cypress เหล่านั้นเพื่อแก้ไขปัญหาใดๆ
ด้วยการใช้อินพุตที่เลือกของ Buildkite เราได้สร้างไดนามิก เลือกการผจญภัยของคุณเอง เพื่อให้ผู้ใช้สามารถเลือก "ใช่" หรือ "ไม่ใช่" เพื่อตัดสินใจว่าจะเรียกใช้โฟลเดอร์ข้อมูลจำเพาะ Cypress ใดและยืนยันเมื่อเราส่งโค้ดเพิ่มเติม คำตอบเริ่มต้นจะเป็น "ไม่" สำหรับตัวเลือกทั้งหมด แต่ค่าของ "ใช่" จะเป็นเส้นทาง glob ไปยังโฟลเดอร์ข้อมูลจำเพาะของ Cypress
ในบางครั้ง เราไม่ต้องการเรียกใช้การทดสอบ Cypress ทั้งหมดหากการเปลี่ยนแปลงโค้ดของเราไม่ส่งผลต่อหน้าอื่นๆ เราต้องการเพียงทริกเกอร์การทดสอบที่เราทราบว่าจะได้รับผลกระทบแทน เราอาจจำเป็นต้องปรับใช้การแก้ไขด่วนในการผลิตสำหรับปัญหาจุดบกพร่องอย่างเร่งด่วน เนื่องจากเรารู้สึกมั่นใจมากพอที่จะไม่ทำการทดสอบ Cypress ซึ่งอาจใช้เวลาตั้งแต่ 0 ถึง 10 นาที ขึ้นอยู่กับจำนวนการทดสอบที่เราเรียกใช้ เราให้ตัวอย่างทั้งทางสายตาและในขั้นตอน YML สำหรับส่วนนี้
ต่อไป เราใช้สคริปต์ทุบตีของเราเองที่ชื่อว่า runCypress.sh
เพื่อเรียกใช้หลังจากนั้น เลือกขั้นตอนเพื่อแยกวิเคราะห์ค่า "ใช่" หรือ "ไม่ใช่" ที่เลือก เราทำสิ่งนี้เพื่อสร้างรายการพาธข้อมูลจำเพาะที่คั่นด้วยเครื่องหมายจุลภาคเพื่อเรียกใช้และผนวกเป็นตัวเลือก --spec
ให้กับคำสั่ง Cypress ในที่สุดของเราที่ทำงานในคอนเทนเนอร์ Docker ในไปป์ไลน์ที่ทริกเกอร์ เราส่งออกตัวแปรสภาพแวดล้อม เช่น รายการข้อกำหนดที่เกิดขึ้นใน “CYPRESS_SPECS” และสภาพแวดล้อมการทดสอบปัจจุบันใน “CYPRESS_TEST_ENV” ที่จะใช้ในไปป์ไลน์ที่เราเรียกใช้ที่ส่วนท้ายของสคริปต์ด้วย buildkite-agent pipeline upload "$DIRNAME"/triggerCypress.yml
คุณอาจสังเกตเห็นว่าเราส่งออกตัวแปรสภาพแวดล้อม “ASYNC” อย่างไร ใน Buildkite คุณสามารถเลือกให้ขั้นตอนการสร้างที่ทริกเกอร์ถูกบล็อกหรือไม่บล็อกในแง่ของความสำเร็จหรือความล้มเหลว หากเราตั้งค่า “ASYNC” เป็นจริง ขั้นตอนไปป์ไลน์การปรับใช้หลักของเราจะยังคงทำงานต่อไปและจะไม่รอให้การทดสอบ Cypress ที่ทริกเกอร์ในไปป์ไลน์อื่นเสร็จสิ้น ความสำเร็จหรือความล้มเหลวของไปป์ไลน์ไม่ส่งผลต่อความสำเร็จหรือความล้มเหลวของไปป์ไลน์การปรับใช้
หากเราตั้งค่า “ASYNC” เป็นเท็จ ขั้นตอนไปป์ไลน์การปรับใช้หลักของเราจะถูกบล็อกจนกว่าการทดสอบ Cypress ที่ทริกเกอร์ในไปป์ไลน์อื่นจะเสร็จสิ้น ความสำเร็จหรือความล้มเหลวของบิวด์ที่ถูกทริกเกอร์จะนำไปสู่ความสำเร็จหรือความล้มเหลวโดยรวมของไปป์ไลน์การปรับใช้ที่จะเกิดขึ้นหลังจากนั้น
เมื่อโค้ดของเรายังคงอยู่ในสาขาคุณลักษณะที่เปิดคำขอดึง เราต้องการผลักดันการเปลี่ยนแปลงเพิ่มเติม เรียกใช้การทดสอบ Cypress และดูว่าสิ่งต่าง ๆ ทำงานอย่างไร แต่เราไม่ต้องการบล็อกขั้นตอนไปป์ไลน์การปรับใช้ที่เหลือเสมอไปหากการทดสอบที่ทริกเกอร์ล้มเหลว เนื่องจากอาจมีการเปลี่ยนแปลงเพิ่มเติมระหว่างทาง ในสถานการณ์สมมตินี้ เราตั้งค่า “ASYNC” เป็นเท็จเพื่อไม่ให้บล็อกหากการทดสอบ Cypress ล้มเหลว สำหรับกรณีที่เราได้รวมคำขอดึงของเราเป็นต้นแบบและปรับใช้กับการแสดงละคร แต่ต้องการทริกเกอร์การทดสอบ Cypress ก่อนที่เราจะปรับใช้กับการผลิต เราตั้งค่า "ASYNC" เป็นจริง เนื่องจากเราต้องการให้การทดสอบ Cypress ผ่านเสมอก่อนที่จะออกไปใช้งานจริง .
เมื่อย้อนกลับไปที่ runCypress.sh
เราจำได้ว่าสคริปต์นั้นทริกเกอร์ไปป์ไลน์ที่สองให้ทำงานโดยเรียกไฟล์ triggerCypress.yml
ด้วยค่าตัวแปรสภาพแวดล้อมที่กำหนด ไฟล์ triggerCypress.yml
จะหน้าตาประมาณนี้ คุณจะสังเกตเห็นขั้นตอน "ทริกเกอร์" และการแก้ไขค่าในข้อความบิลด์มีประโยชน์สำหรับการดีบักและชื่อขั้นตอนแบบไดนามิก
ไม่ว่าเราจะทริกเกอร์การทดสอบ Cypress เพื่อเรียกใช้จากไปป์ไลน์การปรับใช้ของเราไปยังไปป์ไลน์ทริกเกอร์ที่แยกจากกัน หรือเรียกใช้การทดสอบ Cypress ตามกำหนดเวลาในไปป์ไลน์เฉพาะ เราก็ติดตามและใช้ขั้นตอนเดิมซ้ำในขณะที่เปลี่ยนเฉพาะค่าตัวแปรสภาพแวดล้อมเท่านั้น
ขั้นตอนเหล่านี้เกี่ยวข้องกับ:
- การสร้างอิมเมจ Docker ด้วยแท็กล่าสุดและแท็กเวอร์ชันเฉพาะ
- ดันอิมเมจ Docker ขึ้นไปยังรีจิสตรีส่วนตัวของเรา
- ดึงอิมเมจเดียวกันนั้นลงมาเพื่อรันการทดสอบ Cypress ตามค่าตัวแปรสภาพแวดล้อมของเราในคอนเทนเนอร์ Docker
ขั้นตอนเหล่านี้อธิบายไว้ในไฟล์ pipeline.cypress.yml
.cypress.yml ดังนี้:
เมื่อเราทริกเกอร์การทดสอบ Cypress ให้ทำงาน จะเป็นการเปิดบิลด์ที่แยกต่างหากในไปป์ไลน์ทริกเกอร์ Cypress จากความสำเร็จหรือความล้มเหลวของบิลด์ การทดสอบ Cypress จะบล็อกหรืออนุญาตให้เราปรับใช้กับการผลิตเมื่อเราเปลี่ยนจากการจัดเตรียมเป็นการผลิตสำหรับการสร้างสาขาหลัก
การคลิกขั้นตอน “Triggered cypress/integration/…” จะนำคุณไปยังบิลด์ของไปป์ไลน์ที่ถูกทริกเกอร์ด้วยมุมมองเช่นนี้เพื่อดูว่าการทดสอบดำเนินไปอย่างไร
หากคุณสงสัยว่าส่วน Docker เชื่อมต่อกัน Dockerfile.cypress
และ docker docker-compose.cypress.yml
compose.cypress.yml ของเราใช้ตัวแปรสภาพแวดล้อมที่ส่งออกจากไปป์ไลน์ของเราเพื่อใช้คำสั่ง Cypress ที่เหมาะสมจาก package.json
ของแอปพลิเคชันของเราที่ชี้ไปทางขวา ทดสอบสภาพแวดล้อมและเรียกใช้ไฟล์ข้อมูลจำเพาะที่เลือก ตัวอย่างด้านล่างแสดงแนวทางทั่วไปของเราที่คุณสามารถขยายและปรับปรุงเพื่อให้มีความยืดหยุ่นมากขึ้น
นอกเหนือจากการทดสอบที่รันระหว่างวงจรการรวมและการปรับใช้ตามปกติของเรา เราได้สร้างไปป์ไลน์ Buildkite โดยเฉพาะ ไปป์ไลน์เหล่านี้ทำงานตามกำหนดเวลาสำหรับการทดสอบที่สำคัญกับสภาพแวดล้อมการจัดเตรียมของเรา เพื่อให้แน่ใจว่าบริการฟรอนท์เอนด์และแบ็กเอนด์ของเราทำงานอย่างถูกต้อง เราใช้ขั้นตอนไปป์ไลน์ที่คล้ายกันซ้ำ ปรับค่าตัวแปรสภาพแวดล้อมบางอย่างในการตั้งค่าไปป์ไลน์ Buildkite และตั้งค่ากำหนดการ cron ให้ทำงานตามเวลาที่กำหนด วิธีนี้ช่วยให้เราตรวจพบจุดบกพร่องและปัญหาต่างๆ เกี่ยวกับสภาพแวดล้อมการจัดเตรียมในขณะที่เราติดตามว่าการทดสอบของเราทำงานได้ดีเพียงใด และหากมีสิ่งใดที่ดาวน์สตรีมหรือจากการพุชโค้ดของเราเอง อาจทำให้การทดสอบล้มเหลว
Parallelization
เรายังใช้แฟล็กการขนานเพื่อใช้ประโยชน์จากจำนวนเครื่องของ AWS ที่เราสามารถสร้างได้จากคิวตัวแทนการสร้างของเราที่ทีม Ops ของเราตั้งค่าไว้ ด้วยแฟล็กการทำให้ขนานนี้ Cypress จะแสดงเครื่องจักรจำนวนหนึ่งขึ้นมาโดยอัตโนมัติตามจำนวนที่เราตั้งค่าในคุณสมบัติ "ขนาน" ของ Buildkite
เราสามารถเรียกใช้การทดสอบมากกว่า 200 รายการในเวลาประมาณ 5 นาทีสำหรับหนึ่งในที่เก็บแอปพลิเคชันของเรา
จากนั้นจะเผยแพร่การทดสอบ Cypress ทั้งหมดเพื่อให้ทำงานแบบคู่ขนานกันในเครื่องเหล่านั้น ขณะที่ยังคงบันทึกการทดสอบแต่ละรายการสำหรับการรันบิลด์เฉพาะ สิ่งนี้ช่วยเพิ่มเวลาการทดสอบของเราอย่างมาก!
ต่อไปนี้คือเคล็ดลับบางประการเมื่อทำการทดสอบ Cypress แบบขนาน:
- ทำตามคำแนะนำใน Dashboard Service สำหรับจำนวนเครื่องที่เหมาะสมที่สุด และตั้งค่าจำนวนเครื่องในตัวแปรสภาพแวดล้อมเพื่อความยืดหยุ่นในไปป์ไลน์ของคุณ
- แยกเป็นไฟล์ทดสอบที่มีขนาดเล็กลง โดยเฉพาะอย่างยิ่งการแยกการทดสอบที่ใช้เวลานานออกเป็นส่วนๆ ที่เราสามารถทำให้คู่ขนานกันได้ดีขึ้นในเครื่องต่างๆ
- ตรวจสอบให้แน่ใจว่าการทดสอบ Cypress ของคุณถูกแยกออกและไม่ส่งผลกระทบซึ่งกันและกันหรือพึ่งพาซึ่งกันและกัน เมื่อจัดการกับการอัปเดต สร้าง หรือลบโฟลว์ที่เกี่ยวข้อง ให้ใช้ผู้ใช้และแหล่งข้อมูลแยกกันเพื่อหลีกเลี่ยงการทดสอบที่กระทืบกันและทำงานในสภาวะการแข่งขัน ไฟล์ทดสอบของคุณสามารถทำงานได้ในลำดับใดก็ได้ ดังนั้นตรวจสอบให้แน่ใจว่าไม่มีปัญหาเมื่อเรียกใช้การทดสอบทั้งหมดของคุณ
- สำหรับ Buildkite อย่าลืมส่งผ่านค่าตัวแปรสภาพแวดล้อม Buildkite build ID ลงในตัวเลือก
--ci-build-id
นอกเหนือจากตัวเลือกparallel
เพื่อให้รู้ว่าบิลด์ใดรันรันที่จะเชื่อมโยงเมื่อทำการทดสอบข้ามเครื่องพร้อมกัน
วิธีตรวจสอบ:
ในการเชื่อมต่อการทดสอบ Cypress ของคุณกับผู้ให้บริการ CI เช่น Buildkite คุณจะต้อง:
- สร้างอิมเมจ Docker ด้วยโค้ดแอปพลิเคชันของคุณ โดยใช้อิมเมจพื้นฐานของ Cypress และการพึ่งพาที่จำเป็นในการรันการทดสอบในสภาพแวดล้อม Node กับเบราว์เซอร์บางตัว
- ดันอิมเมจ Docker ของคุณขึ้นไปยังรีจิสตรีด้วยแท็กบางแท็ก
- ดึงภาพเดียวกันลงในขั้นตอนต่อไป
- ทำการทดสอบ Cypress ของคุณในโหมด headless และด้วยปุ่มบันทึกหากคุณใช้บริการ Cypress Dashboard
- ตั้งค่าตัวแปรสภาพแวดล้อมที่แตกต่างกันและเสียบเข้ากับคำสั่งที่คุณเรียกใช้สำหรับ Cypress เพื่อทริกเกอร์การทดสอบ Cypress ที่เลือกกับสภาพแวดล้อมการทดสอบบางอย่างในคอนเทนเนอร์ Docker เหล่านั้น
ขั้นตอนทั่วไปเหล่านี้สามารถนำมาใช้ซ้ำและนำไปใช้กับการทดสอบ Cypress ที่ทำงานตามกำหนดเวลาและกรณีการใช้งานอื่นๆ เช่น การทดสอบทริกเกอร์เพื่อทำงานกับเบราว์เซอร์ที่เลือกนอกเหนือจากไปป์ไลน์การปรับใช้ของคุณ กุญแจสำคัญคือการใช้ประโยชน์จากความสามารถของผู้ให้บริการ CI ของคุณและตั้งค่าคำสั่งของคุณให้ยืดหยุ่นและกำหนดค่าได้ตามค่าตัวแปรสภาพแวดล้อม
ตั้งค่าคำสั่งของคุณให้ยืดหยุ่นและกำหนดค่าได้ตามค่าตัวแปรสภาพแวดล้อม
เมื่อคุณเรียกใช้การทดสอบใน Docker กับผู้ให้บริการ CI ของคุณแล้ว (และหากคุณชำระค่าบริการ Dashboard) คุณจะสามารถใช้ประโยชน์จากการทดสอบแบบขนานในเครื่องหลายเครื่องได้ คุณอาจต้องแก้ไขการทดสอบและทรัพยากรที่มีอยู่เพื่อไม่ให้ต้องพึ่งพาการทดสอบอื่นเพื่อหลีกเลี่ยงการทดสอบใดๆ
เรายังพูดถึงแนวคิดที่คุณสามารถลองใช้เองได้ เช่น การสร้างชุดทดสอบเพื่อตรวจสอบ API แบ็กเอนด์ของคุณ หรือการเรียกใช้การทดสอบเพื่อทำงานกับเบราว์เซอร์ที่คุณเลือก นอกจากนี้ยังมีวิธีอื่นๆ ในการตั้งค่าการผสานรวมอย่างต่อ เนื่อง ในเอกสาร Cypress
นอกจากนี้ สิ่งสำคัญคือต้องรันการทดสอบ Cypress เหล่านี้ระหว่างขั้นตอนการปรับใช้หรือช่วงเวลาที่กำหนดเพื่อให้แน่ใจว่าสภาพแวดล้อมการพัฒนาของคุณทำงานตามที่คาดไว้ตลอดเวลา มีหลายครั้งนับไม่ถ้วนที่การทดสอบ Cypress ของเราพบปัญหาที่เกี่ยวข้องกับบริการแบ็กเอนด์ดาวน์สตรีมที่หยุดทำงานหรือเปลี่ยนแปลงไปในทางใดทางหนึ่ง ซึ่งแสดงให้เห็นในข้อผิดพลาดของแอปพลิเคชันส่วนหน้า โดยเฉพาะอย่างยิ่งพวกเขาช่วยเราจากข้อบกพร่องที่ไม่คาดคิดในหน้าเว็บของเราหลังจากที่เราผลักดันการเปลี่ยนแปลงโค้ด React ใหม่
การรักษาการทดสอบที่ผ่านและการตรวจสอบการทดสอบที่ล้มเหลวนั้นทำงานอย่างขยันขันแข็งในสภาพแวดล้อมการทดสอบของเรา ส่งผลให้ตั๋วสนับสนุนน้อยลงและลูกค้ามีความสุขมากขึ้นในการผลิต การรักษาชุดการทดสอบ Cypress ที่แข็งแรงและเสถียรให้ทำงานเมื่อคุณพุชการเปลี่ยนแปลงโค้ดใหม่ ช่วยเพิ่มความมั่นใจมากขึ้นว่าสิ่งต่างๆ ทำงานได้ดี และเราแนะนำให้คุณและทีมของคุณทำเช่นเดียวกันกับการทดสอบ Cypress ของคุณ
สำหรับแหล่งข้อมูลเพิ่มเติมเกี่ยวกับการทดสอบ Cypress โปรดดูบทความต่อไปนี้:
- สิ่งที่ต้องพิจารณาเมื่อเขียนการทดสอบ E2E
- ภาพรวม 1,000 ฟุตของการเขียนแบบทดสอบ Cypress
- TypeScript ทุกสิ่งในการทดสอบ Cypress ของคุณ
- การจัดการกับกระแสอีเมลในการทดสอบ Cypress
- แนวคิดสำหรับการกำหนดค่า การจัดระเบียบ และการรวมการทดสอบ Cypress ของคุณ