การเดินทางทดสอบ E2E ตอนที่ 2: WebdriverIO ไปยัง Cypress
เผยแพร่แล้ว: 2019-11-21หมายเหตุ: นี่เป็นโพสต์จาก #frontend@twiiosendgrid สำหรับบทความด้านวิศวกรรมอื่นๆ ตรงไปที่บล็อกทางเทคนิค
ในแอปฟรอนท์เอนด์ทั้งหมด เรามีและยังคงมี เป้าหมายต่อไปนี้: ให้วิธีการเขียนการทดสอบอัตโนมัติ E2E (end to end) ที่สอดคล้องกัน ดีบัก บำรุงรักษาได้ และมีคุณค่าสำหรับแอปพลิเคชันส่วนหน้าของเรา และผสานรวมกับ CICD (การผสานแบบต่อเนื่อง) และการใช้งานอย่างต่อเนื่อง)
เพื่อไปให้ถึงสถานะที่เรามีในปัจจุบันซึ่งการทดสอบ E2E หลายร้อยรายการอาจถูกเรียกใช้หรือทำงานตามกำหนดเวลาสำหรับทีมส่วนหน้าทั้งหมดของเราใน SendGrid เราต้องวิจัยและทดสอบด้วยโซลูชันที่เป็นไปได้มากมายตลอดทาง จนกว่าเราจะทำหลักนั้นสำเร็จ เป้าหมาย.
เราพยายามเปิดตัวโซลูชัน Ruby Selenium แบบกำหนดเองของเราซึ่งพัฒนาโดยวิศวกรทดสอบเฉพาะที่เรียกว่า SiteTestUI หรือที่รู้จักว่า STUI ซึ่งทุกทีมสามารถมีส่วนร่วมใน repo เดียวและเรียกใช้การทดสอบข้ามเบราว์เซอร์อัตโนมัติ น่าเศร้าที่มันยอมจำนนต่อการทดสอบที่ช้าและเป็นขุย การเตือนที่ผิดพลาด การขาดบริบทระหว่าง repos และภาษา มีมือมากเกินไปในตะกร้าเดียว ประสบการณ์การดีบักที่เจ็บปวด และใช้เวลากับการบำรุงรักษามากกว่าการให้คุณค่า
จากนั้นเราได้ทดลองกับไลบรารี่อื่นที่น่าสนใจใน WebdriverIO เพื่อเขียนการทดสอบใน JavaScript ที่รวมเข้ากับ repos ของแอปพลิเคชันของแต่ละทีม แม้ว่าวิธีนี้จะแก้ปัญหาบางอย่าง เพิ่มขีดความสามารถในการเป็นเจ้าของทีม และช่วยให้เรารวมการทดสอบกับ Buildkite ซึ่งเป็นผู้ให้บริการ CICD ของเรา เรายังคงมีการทดสอบที่ไม่สม่ำเสมอซึ่งยากต่อการดีบักและเขียนยาก นอกเหนือไปจากการจัดการกับจุดบกพร่องและนิสัยใจคอของ Selenium ที่คล้ายกันทั้งหมด .
เราต้องการหลีกเลี่ยง STUI 2.0 อื่นและเริ่มสำรวจตัวเลือกอื่นๆ หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับบทเรียนที่ได้เรียนรู้และกลยุทธ์ที่ค้นพบระหว่างการย้ายจาก STUI ไปยัง WebdriverIO โปรดดูส่วนที่ 1 ของชุดโพสต์บล็อก
ในส่วนสุดท้ายของบล็อกโพสต์ชุดที่สอง เราจะอธิบายการเดินทางของเราจาก STUI และ WebdriverIO สู่ Cypress และวิธีที่เราดำเนินการย้ายข้อมูลที่คล้ายกันในการตั้งค่าโครงสร้างพื้นฐานโดยรวม การเขียนการทดสอบ E2E ที่จัดระเบียบ การผสานรวมกับไปป์ไลน์ Buildkite และการปรับขนาดเป็น ทีมส่วนหน้าอื่นๆ ในองค์กร
TLDR: เราใช้ Cypress แทน STUI และ WebdriverIO และเราบรรลุเป้าหมายทั้งหมดของเราในการเขียนการทดสอบ E2E อันมีค่าเพื่อรวมเข้ากับ CICD งานและบทเรียนมากมายของเราที่เรียนรู้จาก WebdriverIO และ STUI ได้ดำเนินการอย่างดีถึงวิธีที่เราใช้และรวมการทดสอบ Cypress ในปัจจุบัน
สารบัญ
สำรวจและลงจอดบน Cypress
การเปลี่ยนจาก STUI และ WebdriverIO เป็น Cypress
ขั้นตอนที่ 1: การติดตั้งการพึ่งพาสำหรับ Cypress
ขั้นตอนที่ 2: การกำหนดค่าสภาพแวดล้อมและสคริปต์
First Pass of Environment Configs and Scripts
วิวัฒนาการของการกำหนดค่าสภาพแวดล้อมและสคริปต์
ขั้นตอนที่ 3: การนำการทดสอบ E2E ไปใช้ในเครื่อง
ขั้นตอนที่ 4: เทียบท่าการทดสอบ
ขั้นตอนที่ 5: การผสานรวมกับ CICD
ขั้นตอนที่ 6: เปรียบเทียบ Cypress กับ WebdriverIO/STUI
ขั้นตอนที่ 7: ปรับขนาดไปยังทีมส่วนหน้าอื่น
สิ่งที่เรารอคอยกับ Cypress
การนำ Cypress ไปสู่อนาคต
สำรวจและลงจอดบน Cypress
เมื่อเราค้นหาทางเลือกอื่นแทน WebdriverIO เราพบเครื่องห่อหุ้ม Selenium อื่นๆ เช่น Protractor และ Nightwatch ที่มีคุณลักษณะคล้ายคลึงกันที่ตั้งค่าเป็น WebdriverIO แต่เรารู้สึกว่าน่าจะใช้การตั้งค่าที่ยาวนาน การทดสอบที่ไม่สม่ำเสมอ และการดีบักและการบำรุงรักษาที่ยุ่งยาก
โชคดีที่เราได้พบกับเฟรมเวิร์กการทดสอบ E2E ใหม่ที่เรียกว่า Cypress ซึ่งแสดงการตั้งค่าอย่างรวดเร็ว การทดสอบที่รวดเร็วและสามารถแก้ไขข้อบกพร่องได้ที่ทำงานในเบราว์เซอร์ การร้องขอเลเยอร์เครือข่ายที่สะดุด และที่สำคัญที่สุดคือไม่ใช้ Selenium ภายใต้ประทุน
เราประหลาดใจกับคุณสมบัติที่ยอดเยี่ยม เช่น การบันทึกวิดีโอ Cypress GUI บริการแดชบอร์ดแบบชำระเงิน และการทำให้เป็นคู่ขนานเพื่อทดลองใช้ เราเต็มใจที่จะประนีประนอมกับการสนับสนุนข้ามเบราว์เซอร์เพื่อสนับสนุนการทดสอบอันมีค่าที่ผ่านการทดสอบกับ Chrome อย่างสม่ำเสมอด้วยเครื่องมือต่างๆ ที่เรามีจำหน่ายเพื่อนำไปใช้ ดีบัก และบำรุงรักษาการทดสอบสำหรับนักพัฒนาซอฟต์แวร์และ QA ของเรา
เรายังชื่นชมเฟรมเวิร์กการทดสอบ ไลบรารีการยืนยัน และเครื่องมืออื่นๆ ทั้งหมดที่เลือกให้เรามีวิธีการทดสอบที่เป็นมาตรฐานมากขึ้นในทีมส่วนหน้าทั้งหมดของเรา ด้านล่างนี้ เราได้จัดเตรียมภาพหน้าจอของความแตกต่างระหว่างโซลูชัน เช่น WebdriverIO และ Cypress และหากคุณต้องการดูความแตกต่างเพิ่มเติมระหว่างโซลูชัน Cypress และ Selenium คุณสามารถดูเอกสารเกี่ยวกับวิธีการทำงาน
ด้วยเหตุนี้ เราจึงมุ่งมั่นที่จะทดสอบ Cypress เป็นโซลูชันอื่นสำหรับการเขียนการทดสอบ E2E ที่รวดเร็ว สอดคล้องกัน และแก้ไขจุดบกพร่องได้ เพื่อรวมเข้ากับ Buildkite ระหว่าง CICD ในท้ายที่สุด นอกจากนี้เรายังตั้งเป้าหมายอีกประการหนึ่งในการเปรียบเทียบ Cypress กับโซลูชันที่ใช้ Selenium ก่อนหน้านี้ เพื่อพิจารณาในท้ายที่สุดโดยจุดข้อมูลว่าเราควรมองหาหรือสร้างชุดทดสอบของเรากับ Cypress ต่อไปหรือไม่ เราวางแผนที่จะแปลงการทดสอบ WebdriverIO ที่มีอยู่และการทดสอบที่มีลำดับความสำคัญสูงอื่น ๆ ที่ยังคงอยู่ใน STUI ไปเป็นการทดสอบ Cypress และเปรียบเทียบประสบการณ์ของนักพัฒนา ความเร็ว ความเสถียร เวลารันการทดสอบ และการบำรุงรักษาการทดสอบ
การเปลี่ยนจาก STUI และ WebdriverIO เป็น Cypress
เมื่อเปลี่ยนจาก STUI และ WebdriverIO เป็น Cypress เราจัดการอย่างเป็นระบบโดยใช้กลยุทธ์ระดับสูงแบบเดียวกับที่เราใช้เมื่อเราพยายามย้ายจาก STUI เป็น WebdriverIO ใน repos ของแอปพลิเคชันส่วนหน้า สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่เราดำเนินการตามขั้นตอนดังกล่าวสำหรับ WebdriverIO ให้เสร็จสิ้น โปรดดูส่วนที่ 1 ของชุดโพสต์บล็อก ขั้นตอนทั่วไปในการเปลี่ยนไปใช้ Cypress มีดังต่อไปนี้:
- การติดตั้งและตั้งค่าการพึ่งพาเพื่อเชื่อมต่อกับ Cypress
- การสร้างการกำหนดค่าสภาพแวดล้อมและคำสั่งสคริปต์
- การนำการทดสอบ E2E ไปใช้ที่ผ่านในพื้นที่เทียบกับสภาพแวดล้อมที่แตกต่างกัน
- เทียบท่าการทดสอบ
- การรวมการทดสอบ Dockerized กับ Buildkite ผู้ให้บริการ CICD ของเรา
เพื่อให้บรรลุเป้าหมายรองของเรา เรายังได้เพิ่มขั้นตอนเพิ่มเติมเพื่อเปรียบเทียบ Cypress กับโซลูชัน Selenium รุ่นก่อน ๆ และในท้ายที่สุดเพื่อปรับขนาด Cypress ในทีมส่วนหน้าทั้งหมดในองค์กร:
6. การเปรียบเทียบ Cypress ในแง่ของประสบการณ์ของนักพัฒนา ความเร็ว และความเสถียรของการทดสอบกับ WebdriverIO และ STUI
7. ขยายไปยังทีมส่วนหน้าอื่น ๆ
ขั้นตอนที่ 1: การติดตั้งการพึ่งพาสำหรับ Cypress
ในการเริ่มต้นใช้งาน Cypress อย่างรวดเร็ว สิ่งที่เราต้องทำคือ `npm install cypress` ลงในโปรเจ็กต์ของเรา และเริ่มใช้งาน Cypress เป็นครั้งแรก เพื่อให้มีการจัดวางไฟล์การกำหนดค่า `cypress.json' และโฟลเดอร์ cypress
โดยอัตโนมัติ พร้อมชุดติดตั้งเริ่มต้น การทดสอบ และไฟล์การตั้งค่าอื่นๆ สำหรับคำสั่งและปลั๊กอิน เราชื่นชมที่ Cypress มาพร้อมกับ Mocha ในฐานะผู้ทำการทดสอบ Chai สำหรับการยืนยัน และ Chai-jQuery และ Sinon-Chai สำหรับการยืนยันที่จะใช้และเชื่อมโยงออกไป เราไม่ต้องใช้เวลามากในการค้นคว้าเกี่ยวกับสิ่งที่ผู้ทำการทดสอบ ผู้รายงาน การยืนยัน และไลบรารีบริการที่จะติดตั้งและใช้งานอีกต่อไป เมื่อเทียบกับตอนที่เราเริ่มต้นกับ WebdriverIO หรือ STUI เราทำการทดสอบที่สร้างขึ้นบางส่วนทันทีด้วย Cypress GUI และสำรวจคุณสมบัติการดีบักมากมายที่เรามีอยู่ เช่น การดีบักการเดินทางข้ามเวลา สนามเด็กเล่นตัวเลือก วิดีโอที่บันทึกไว้ ภาพหน้าจอ บันทึกคำสั่ง เครื่องมือสำหรับนักพัฒนาเบราว์เซอร์ ฯลฯ
นอกจากนี้เรายังตั้งค่าในภายหลังด้วย Eslint และ TypeScript สำหรับการตรวจสอบประเภทสแตติกเพิ่มเติมและกฎการจัดรูปแบบที่จะปฏิบัติตามเมื่อยืนยันรหัสทดสอบ Cypress ใหม่ ตอนแรกเรามีปัญหาบางอย่างจากการรองรับ TypeScript และไฟล์บางไฟล์ต้องเป็นไฟล์ JavaScript เช่นเดียวกับที่อยู่ตรงกลางไฟล์ปลั๊กอิน แต่โดยส่วนใหญ่ เราสามารถพิมพ์ตรวจสอบไฟล์ส่วนใหญ่ของเราสำหรับการทดสอบ ออบเจ็กต์หน้า และคำสั่งของเรา
นี่คือตัวอย่างโครงสร้างโฟลเดอร์ที่ทีมส่วนหน้าของเราติดตามเพื่อรวมออบเจ็กต์ของเพจ ปลั๊กอิน และคำสั่ง:
ขั้นตอนที่ 2: การกำหนดค่าสภาพแวดล้อมและสคริปต์
หลังจากติดตั้งและตั้งค่า Cypress ให้ทำงานภายในได้อย่างรวดเร็ว เราต้องการวิธีสำหรับการทดสอบ Cypress ของเราในการทำงานด้วยการตั้งค่าที่แตกต่างกันสำหรับแต่ละสภาพแวดล้อม และต้องการสนับสนุนกรณีการใช้งานเดียวกันกับที่คำสั่ง WebdriverIO ของเราอนุญาตให้เราทำได้ ต่อไปนี้คือรายการที่แสดงกรณีการใช้งานส่วนใหญ่ว่าเราต้องการดำเนินการทดสอบเหล่านี้อย่างไร และเหตุใดเราจึงต้องการสนับสนุนการทดสอบเหล่านี้:
- เทียบกับ เซิร์ฟเวอร์ Webpack dev ที่ทำงานบน localhost (เช่น http://localhost:8000) และเซิร์ฟเวอร์ dev นั้นจะชี้ไปที่ API สภาพแวดล้อมบางอย่าง (เช่น https://testing.api.com หรือ https://staging.api com) เช่น การทดสอบหรือการแสดงละคร
ทำไม? บางครั้ง เราจำเป็นต้องทำการเปลี่ยนแปลงในเว็บแอปในพื้นที่ของเรา เช่น การเพิ่มตัวเลือกเฉพาะสำหรับการทดสอบของเราเพื่อโต้ตอบกับองค์ประกอบต่างๆ ในลักษณะที่มีประสิทธิภาพมากขึ้น หรือเรากำลังดำเนินการพัฒนาคุณลักษณะใหม่และจำเป็นต้องปรับและตรวจสอบการทดสอบระบบอัตโนมัติที่มีอยู่ จะส่งผ่านภายในเครื่องเทียบกับการเปลี่ยนแปลงรหัสใหม่ของเรา เมื่อใดก็ตามที่รหัสของแอปพลิเคชันเปลี่ยนไปและเรายังไม่ได้ผลักดันสภาพแวดล้อมที่ปรับใช้ เราใช้คำสั่งนี้เพื่อเรียกใช้การทดสอบกับเว็บแอปในพื้นที่ของเรา - เทียบกับ แอปที่ปรับใช้สำหรับสภาพแวดล้อมบางอย่าง (เช่น https://testing.app.com หรือ https://staging.app.com) เช่น การทดสอบหรือการแสดงละคร
ทำไม? ในบางครั้ง โค้ดของแอปพลิเคชันไม่เปลี่ยนแปลง แต่เราอาจต้องแก้ไขโค้ดทดสอบเพื่อแก้ไขความไม่แน่นอน หรือเรารู้สึกมั่นใจมากพอที่จะเพิ่มหรือลบการทดสอบทั้งหมดโดยไม่ทำการเปลี่ยนแปลงส่วนหน้า เราใช้คำสั่งนี้อย่างหนักเพื่ออัปเดตหรือดีบักการทดสอบในเครื่องกับแอปที่ปรับใช้เพื่อจำลองวิธีการทดสอบของเราใน CICD อย่างใกล้ชิดยิ่งขึ้น - ทำงาน ในคอนเทนเนอร์ Docker กับแอปที่ปรับใช้สำหรับสภาพแวดล้อมบางอย่าง เช่น การทดสอบหรือการแสดงละคร
ทำไม? สิ่งนี้มีไว้สำหรับ CICD เพื่อให้เราสามารถเรียกใช้การทดสอบ E2E เพื่อเรียกใช้ในคอนเทนเนอร์ Docker เทียบกับแอปที่ปรับใช้การจัดเตรียม และตรวจสอบให้แน่ใจว่าผ่านก่อนที่จะปรับใช้โค้ดกับการใช้งานจริง หรือในการทดสอบตามกำหนดเวลาในไปป์ไลน์เฉพาะ เมื่อตั้งค่าคำสั่งเหล่านี้ในขั้นต้น เราได้ดำเนินการทดลองและข้อผิดพลาดจำนวนมากเพื่อหมุนคอนเทนเนอร์ Docker ด้วยค่าตัวแปรสภาพแวดล้อมที่แตกต่างกัน และทดสอบเพื่อดูการทดสอบที่เหมาะสมที่ดำเนินการได้สำเร็จก่อนที่จะเชื่อมต่อกับ Buildkite ผู้ให้บริการ CICD ของเรา
First Pass of Environment Configs and Scripts
เมื่อเราทดลองกับการตั้งค่า Cypress ครั้งแรก เราทำใน repo ที่ครอบคลุม https://app.sendgrid.com ซึ่งเป็นเว็บแอปที่มีหน้าคุณลักษณะ เช่น การตรวจสอบผู้ส่ง กิจกรรมอีเมล และการตรวจสอบอีเมล และเราแชร์อย่างหลีกเลี่ยงไม่ได้ การค้นพบและการเรียนรู้ของเรากับทีมงานที่อยู่เบื้องหลังแอปเว็บแคมเปญการตลาดของเรา ซึ่งครอบคลุมโดเมน https://mc.sendgrid.com เราต้องการเรียกใช้การทดสอบ E2E กับสภาพแวดล้อมการจัดเตรียมของเรา และใช้อินเทอร์เฟซบรรทัดคำสั่งของ Cypress และตัวเลือกต่างๆ เช่น --env
--config
ให้กรณีการใช้งานของเราสำเร็จ
เพื่อเรียกใช้การทดสอบ Cypress กับเว็บแอปในเครื่องที่พูด http://127.0.0.1:8000
หรือเทียบกับ URL ของแอปการแสดงละครที่ปรับใช้ เราได้ปรับการตั้งค่าสถานะ baseUrl
ในคำสั่งและเพิ่มตัวแปรสภาพแวดล้อมเพิ่มเติม เช่น testEnv
เพื่อช่วย โหลดข้อมูลการทดสอบเฉพาะของการแข่งขันหรือสภาพแวดล้อมในการทดสอบ Cypress ของเรา ตัวอย่างเช่น คีย์ API ที่ใช้ ผู้ใช้ที่สร้าง และทรัพยากรอื่นๆ อาจแตกต่างกันไปตามสภาพแวดล้อม เราใช้ testEnv
เพื่อสลับการติดตั้งเหล่านั้นหรือเพิ่มตรรกะแบบมีเงื่อนไขพิเศษ หากฟีเจอร์บางอย่างไม่ได้รับการสนับสนุนในสภาพแวดล้อมหรือการตั้งค่าการทดสอบที่แตกต่างกัน และเราจะเข้าถึงสภาพแวดล้อมผ่านการโทร เช่น Cypress.env(“testEnv”)
ในข้อกำหนดของเรา
จากนั้นเราจัดระเบียบคำสั่งของเรา cypress:open:*
เพื่อแสดงการเปิด Cypress GUI เพื่อให้เราเลือกการทดสอบของเราเพื่อเรียกใช้ผ่าน UI เมื่อเราพัฒนาในเครื่อง และ cypress:run:*
เพื่อแสดงถึงการดำเนินการทดสอบในโหมด headless ซึ่งได้รับการปรับแต่งมากขึ้น สำหรับการทำงานในคอนเทนเนอร์ Docker ระหว่าง CICD สิ่งที่เกิดขึ้นหลังจาก open
หรือ run
จะเป็นสภาพแวดล้อม ดังนั้นคำสั่งของเราจะอ่านได้ง่ายเช่น npm run cypress:open:localhost:staging
เพื่อเปิด GUI และรันการทดสอบกับเซิร์ฟเวอร์ Webpack dev ในเครื่องที่ชี้ไปที่ staging API หรือ npm run cypress:run:staging
เพื่อรันการทดสอบในโหมด headless กับแอพ staging และ API ที่ปรับใช้ สคริปต์ package.json
Cypress ออกมาเป็นดังนี้:
วิวัฒนาการของการกำหนดค่าสภาพแวดล้อมและสคริปต์
ในโครงการอื่น เราได้พัฒนาคำสั่งและการกำหนดค่า Cypress เพื่อใช้ประโยชน์จากตรรกะของโหนดในไฟล์ cypress/plugins/index.js
เพื่อให้มีไฟล์ cypress.json
ฐานและไฟล์การกำหนดค่าแยกต่างหากที่จะอ่านตามตัวแปรสภาพแวดล้อมที่เรียกว่า configFile
เพื่อโหลดไฟล์การกำหนดค่าเฉพาะ ไฟล์คอนฟิกูเรชันที่โหลดจะถูกรวมเข้ากับไฟล์ฐานเพื่อชี้ไปที่ staging หรือเซิร์ฟเวอร์แบ็กเอนด์จำลองในที่สุด
ในกรณีที่คุณสงสัยเพิ่มเติมเกี่ยวกับเซิร์ฟเวอร์จำลองแบ็กเอนด์ เราได้พัฒนาเซิร์ฟเวอร์ Express ที่มีจุดปลายแบ็กเอนด์เพียงแค่ส่งคืนการตอบสนองที่แตกต่างกันของข้อมูล JSON แบบคงที่และรหัสสถานะ (เช่น 200, 4XX, 5XX) ขึ้นอยู่กับพารามิเตอร์การสืบค้นที่ส่งผ่านในคำขอ สิ่งนี้ปลดบล็อกส่วนหน้าเพื่อพัฒนาโฟลว์เพจต่อไปด้วยการเรียกเครือข่ายจริงไปยังเซิร์ฟเวอร์แบ็กเอนด์จำลองพร้อมการตอบสนองที่จำลองว่า API จริงจะมีลักษณะอย่างไรเมื่อพร้อมใช้งานในอนาคต นอกจากนี้เรายังสามารถจำลองระดับความสำเร็จและการตอบสนองข้อผิดพลาดต่างๆ ได้อย่างง่ายดายสำหรับสถานะ UI ต่างๆ ของเรา ซึ่งอาจเป็นเรื่องยากที่จะทำซ้ำในการผลิต และเนื่องจากเราจะทำการเรียกเครือข่ายแบบกำหนด การทดสอบ Cypress ของเราจึงไม่ค่อยมีปัญหาในการเปิดเครือข่ายเดียวกัน คำขอและการตอบสนองทุกครั้ง
เรามีไฟล์ cypress.json
พื้นฐานที่รวมคุณสมบัติที่ใช้ร่วมกันสำหรับการหมดเวลาทั่วไป รหัสโปรเจ็กต์เพื่อเชื่อมต่อกับ Cypress Dashboard Service ซึ่งเราจะพูดถึงในภายหลัง และการตั้งค่าอื่นๆ ดังที่แสดงด้านล่าง:
เราได้สร้างโฟลเดอร์การกำหนด config
ในโฟลเดอร์ cypress
เพื่อเก็บไฟล์การกำหนดค่าแต่ละไฟล์ของเรา เช่น localhostMock.json
เพื่อเรียกใช้เซิร์ฟเวอร์ Webpack dev ในพื้นที่ของเรากับเซิร์ฟเวอร์จำลอง API ในเครื่องหรือ staging.json
เพื่อทำงานกับแอปการแสดงละครและ API ที่ปรับใช้ ไฟล์คอนฟิกูเรชันเหล่านี้ที่จะกระจายและรวมเข้ากับคอนฟิกูเรชันพื้นฐานมีลักษณะดังนี้:
ไฟล์การกำหนดค่า CICD มีไฟล์ JSON ที่ง่ายกว่า เนื่องจากเราจำเป็นต้องตั้งค่าตัวแปรสภาพแวดล้อมแบบไดนามิกเพื่อพิจารณา URL ฐานส่วนหน้าของบริการ Docker ที่แตกต่างกันและโฮสต์ API เซิร์ฟเวอร์จำลองที่เราจะเจาะลึกในภายหลัง
ในไฟล์ cypress/plugins/index.js
ของเรา เราได้เพิ่มตรรกะเพื่ออ่านตัวแปรสภาพแวดล้อมที่เรียกว่า configFile
ซึ่งตั้งค่าจากคำสั่ง Cypress ที่จะอ่านไฟล์ที่เกี่ยวข้องในโฟลเดอร์ config
และรวมเข้ากับ cypress.json
ฐาน เช่นด้านล่าง:
ในการเขียนคำสั่ง Cypress ที่สมเหตุสมผลด้วยตัวแปรสภาพแวดล้อมที่กำหนดไว้สำหรับกรณีการใช้งานของเรา เราจึงใช้ประโยชน์จาก Makefile
ที่มีลักษณะดังต่อไปนี้:
ด้วยคำสั่งเหล่านั้นที่จัดวางอย่างเรียบร้อยใน Makefile เราสามารถทำสิ่งต่างๆ ได้อย่างรวดเร็ว เช่น make cypress_open_staging
หรือ make cypress_run_staging
ในสคริปต์ npm ของ `package.json`
ก่อนหน้านี้ เราเคยวางคำสั่งบางอย่างในบรรทัดยาวๆ หนึ่งบรรทัด ซึ่งแก้ไขได้ยากโดยไม่มีข้อผิดพลาด โชคดีที่ Makefile ช่วยกระจายสิ่งต่าง ๆ ได้ดีขึ้นมากด้วยการแก้ไขตัวแปรสภาพแวดล้อมที่อ่านได้ในคำสั่ง Cypress ในหลายบรรทัด เราสามารถตั้งค่าหรือส่งออกตัวแปรสภาพแวดล้อมได้อย่างรวดเร็ว เช่น configFile
ที่จะโหลดไฟล์การกำหนดค่าสภาพแวดล้อม, BASE_URL
เพื่อเยี่ยมชมหน้าเว็บของเรา, API_HOST
สำหรับสภาพแวดล้อมแบ็กเอนด์ที่แตกต่างกัน หรือ SPECS
เพื่อกำหนดการทดสอบที่จะเรียกใช้ก่อนที่เราจะเริ่มต้นคำสั่ง Makefile ใดๆ
เรายังใช้คำสั่ง Makefile สำหรับสคริปต์ npm ที่มีความยาวอื่นๆ และคำสั่ง Docker เช่น การสร้างเนื้อหา Webpack การติดตั้งการพึ่งพา หรือการรันคำสั่งร่วมกับผู้อื่น ในที่สุด เราจะแปลคำสั่ง Makefile บางคำสั่งลงในส่วนสคริปต์ package.json
แม้ว่าจะไม่จำเป็นถ้ามีคนต้องการใช้เฉพาะ Makefile และมันจะมีลักษณะดังนี้:
เราตั้งใจละทิ้งคำสั่ง Cypress CICD จำนวนมากเนื่องจากไม่ใช่คำสั่งที่จะใช้ในการพัฒนาแบบวันต่อวันและทำให้ package.json
มีความคล่องตัวมากขึ้น สิ่งสำคัญที่สุดคือเราสามารถเห็นคำสั่ง Cypress ทั้งหมดที่เกี่ยวข้องกับเซิร์ฟเวอร์จำลองและเซิร์ฟเวอร์ Webpack dev ภายในทันที เทียบกับสภาพแวดล้อมการแสดงละครและคำสั่งใด "เปิด" GUI มากกว่า "ทำงาน" ในโหมดหัวขาด
ขั้นตอนที่ 3: การนำการทดสอบ E2E ไปใช้ในเครื่อง
เมื่อเราเริ่มใช้การทดสอบ E2E กับ Cypress เราอ้างอิงการทดสอบที่มีอยู่ของเราจาก WebdriverIO และ STUI เพื่อแปลงและเพิ่มการทดสอบใหม่กว่าสำหรับคุณสมบัติที่มีลำดับความสำคัญสูงอื่น ๆ ตั้งแต่การตรวจสุขภาพอย่างง่ายไปจนถึงการไหลของเส้นทางแห่งความสุขที่ซับซ้อน การแปลออบเจ็กต์เพจที่มีอยู่และไฟล์ทดสอบจาก WebdriverIO หรือ STUI เป็นออบเจ็กต์เพจและข้อกำหนดที่เทียบเท่าใน Cypress พิสูจน์แล้วว่าเป็นเรื่องง่าย อันที่จริงมันส่งผลให้โค้ดสะอาดขึ้นกว่าเดิมมาก โดยไม่มีการรอองค์ประกอบที่ชัดเจนและความสามารถในการเชื่อมโยงของการยืนยันและคำสั่ง Cypress อื่นๆ ได้ดีขึ้น
ตัวอย่างเช่น ขั้นตอนทั่วไปของการทดสอบยังคงเหมือนเดิมจากมุมมองของผู้ใช้ปลายทาง ดังนั้นงานการแปลงจึงเกี่ยวข้องกับการแมป WebdriverIO หรือ STUI API กับ Cypress API ด้วยวิธีต่อไปนี้:
- คำสั่งจำนวนมากปรากฏขึ้นและทำงานคล้ายกับจุดที่เราเกือบจะเพียงแค่แทนที่
$
หรือbrowser
ด้วยcy
หรือCypress
ievisiting หน้าผ่าน$(“.button”).click()
ไปยังcy.get(“.button”).click()
,browser.url()
ถึงcy.visit()
หรือ$(“.input”).setValue()
ถึงcy.get(“.input”).type()
- การใช้
$
หรือ$$
มักจะกลายเป็นcy.get(...)
หรือcy.contains(...)
เช่น$$(“.multiple-elements-selector”)
หรือ$(“.single-element-selector”)
เปลี่ยนเป็นcy.get(“.any-element-selector”)
,cy.contains(“text”)
หรือcy.contains(“.any-selector”)
- การลบ
$(“.selector”).waitForVisible(timeoutInMs)
,$(“.selector”).waitUntil(...)
หรือ$(“.selector”).waitForExist()
ออกเพื่อให้ Cypress เป็นค่าเริ่มต้น จัดการกับการลองใหม่และการดึงข้อมูลองค์ประกอบซ้ำแล้วซ้ำอีกด้วยcy.get('.selector')
และcy.contains(textInElement)
หากเราต้องการการหมดเวลานานกว่าค่าเริ่มต้น เราจะใช้cy.get('.selector', { timeout: longTimeoutInMs })
ทั้งหมด จากนั้นหลังจากดึงองค์ประกอบแล้ว เราจะเชื่อมโยงคำสั่งการดำเนินการถัดไปเพื่อทำบางสิ่งกับองค์ประกอบ เช่นcy.get(“.selector”).click()
- คำสั่งที่กำหนดเองกับเบราว์เซอร์
addCommand('customCommand, () => {})` turned into `Cypress.Commands.add('customCommand', () => {})
และทำ `cy.customCommand()` - การร้องขอเครือข่ายสำหรับการตั้งค่าหรือการแยกส่วนผ่าน API โดยใช้ไลบรารีที่เรียกว่า
node-fetch
และห่อในbrowser.call(() => return fetch(...))
และ/หรือbrowser.waitUntil(...)
นำไปสู่ ทำการร้องขอ HTTP ในเซิร์ฟเวอร์ Cypress Node ผ่านcy.request(endpoint)
หรือปลั๊กอินที่กำหนดเองที่เรากำหนดและทำการเรียกเช่นcy.task(taskToHitAPIOrService)
- ก่อนหน้านี้เมื่อเราต้องรอให้คำขอเครือข่ายที่สำคัญอาจเสร็จสิ้นโดยไม่มีการเปลี่ยนแปลง UI ที่โดดเด่น บางครั้งเราต้องหันไปใช้
browser.pause(timeoutInMs)
แต่ด้วย Cypress เราปรับปรุงด้วยฟังก์ชันการทำงานที่ติดขัดของเครือข่ายและสามารถรับฟังได้ และรอให้คำขอเฉพาะเสร็จสิ้นด้วยcy.server()
,cy.route(“method”, “/endpoint/we/are/waiting/for).as(“endpoint”)`, and `cy.wait(“@endpoint”)
ก่อนเริ่มการดำเนินการที่จะทริกเกอร์คำขอ
หลังจากแปลไวยากรณ์และคำสั่ง WebdriverIO จำนวนมากไปยังคำสั่ง Cypress เราได้นำแนวคิดเดียวกันกับการมีออบเจ็กต์เพจพื้นฐานสำหรับการทำงานที่ใช้ร่วมกันทั่วไปและออบเจ็กต์เพจเพิ่มเติมสำหรับแต่ละเพจที่เราต้องการสำหรับการทดสอบ นี่คือตัวอย่างของออบเจ็กต์หน้าฐานที่มีฟังก์ชัน open()
ร่วมกันที่จะแชร์ในทุกหน้า
ออบเจ็กต์เพจแบบขยายจะเพิ่ม getters สำหรับตัวเลือกองค์ประกอบ ใช้ฟังก์ชัน open()
ด้วยเส้นทางของเพจ และจัดเตรียมฟังก์ชันตัวช่วยตามที่แสดงด้านล่าง
ออบเจ็กต์หน้าที่ขยายจริงของเรายังใช้ออบเจ็กต์แมปอย่างง่ายเพื่อรักษาตัวเลือกองค์ประกอบ CSS ทั้งหมดของเราไว้ในที่เดียวที่เราจะเสียบเข้ากับส่วนประกอบ React ของเราเป็นแอตทริบิวต์ข้อมูล อ้างอิงในการทดสอบหน่วย และใช้เป็นตัวเลือกของเราในออบเจ็กต์หน้า Cypress นอกจากนี้ คลาสอ็อบเจ็กต์เพจของเราในบางครั้งนั้นแตกต่างกันไปในการใช้ประโยชน์จากคอนสตรัคเตอร์คลาส ถ้าบอกว่าออบเจกต์ของเพจถูกใช้ซ้ำสำหรับเพจที่มีลักษณะและการทำงานที่คล้ายกันจำนวนมาก เช่น เพจการปราบปราม และเราจะส่งผ่านอาร์กิวเมนต์เพื่อเปลี่ยนเส้นทางหรือคุณสมบัติเฉพาะ
ตามหมายเหตุด้านข้าง ทีมไม่จำเป็นต้องใช้ออบเจ็กต์ของเพจ แต่เราชื่นชมความสอดคล้องของรูปแบบในการรักษาฟังก์ชันการทำงานของเพจและการอ้างอิงตัวเลือกองค์ประกอบ DOM ร่วมกับโครงสร้างคลาสออบเจ็กต์มาตรฐานเพื่อแบ่งปันการทำงานทั่วไปในทุกหน้า ทีมอื่นๆ ชอบที่จะสร้างไฟล์ต่างๆ มากมายโดยใช้ฟังก์ชันยูทิลิตี้เพียงเล็กน้อย และไม่ใช้คลาส ES6 แต่สิ่งสำคัญที่ต้องทำคือการจัดเตรียมวิธีที่จัดระเบียบและคาดการณ์ได้ เพื่อสรุปทุกอย่าง และเขียนการทดสอบเพื่อประสิทธิภาพและการบำรุงรักษาของนักพัฒนาที่ดีขึ้น
เราปฏิบัติตามกลยุทธ์การทดสอบทั่วไปแบบเดียวกับที่ใช้กับการทดสอบ WebdriverIO รุ่นเก่าของเรา โดยพยายามตั้งค่าการทดสอบผ่าน API ให้ได้มากที่สุด เราต้องการหลีกเลี่ยงการสร้างสถานะการตั้งค่าของเราผ่าน UI เพื่อไม่ให้เกิดความเหลื่อมล้ำและเสียเวลาสำหรับส่วนที่เราไม่ได้ตั้งเป้าที่จะทดสอบ การทดสอบส่วนใหญ่เกี่ยวข้องกับกลยุทธ์นี้:
- การตั้งค่าหรือการแยกส่วนผ่าน API – หากเราจำเป็นต้องทดสอบการสร้างเอนทิตีผ่าน UI เราจะตรวจสอบให้แน่ใจว่าได้ลบเอนทิตีผ่าน API ก่อน ไม่ว่าการทดสอบครั้งก่อนจะจบลงด้วยความสำเร็จหรือล้มเหลวอย่างไร การทดสอบจำเป็นต้องได้รับการตั้งค่าอย่างเหมาะสมหรือแยกส่วนผ่าน API เพื่อให้แน่ใจว่าการทดสอบทำงานในลักษณะที่สอดคล้องกันและเริ่มต้นด้วยเงื่อนไขที่ถูกต้อง
- การเข้าสู่ระบบผู้ใช้ทดสอบเฉพาะผ่าน API – เราได้สร้างผู้ใช้ทดสอบเฉพาะต่อหน้าหรือต่อการทดสอบระบบอัตโนมัติ ดังนั้นการทดสอบของเราจะถูกแยกออกและไม่เหยียบย่ำทรัพยากรของกันและกันเมื่อทำงานพร้อมกัน เราทำการร้องขอเดียวกันกับหน้าเข้าสู่ระบบของเราผ่าน API และเก็บคุกกี้ก่อนเริ่มการทดสอบ เพื่อให้เราสามารถไปที่หน้าตรวจสอบสิทธิ์โดยตรง และเริ่มขั้นตอนการทดสอบจริง
- ขั้นตอนอัตโนมัติจากมุมมองของผู้ใช้ปลายทาง – หลังจากลงชื่อเข้าใช้ผู้ใช้ผ่าน API เราไปที่หน้าโดยตรงและทำให้ขั้นตอนที่ผู้ใช้ปลายทางดำเนินการโดยอัตโนมัติเพื่อสิ้นสุดโฟลว์ฟีเจอร์และตรวจสอบว่าผู้ใช้เห็นและโต้ตอบกับสิ่งที่ถูกต้อง ระหว่างทาง.
เพื่อรีเซ็ตการทดสอบกลับสู่สถานะเดิมที่คาดไว้ เราจะลงชื่อเข้าใช้ผู้ใช้ทดสอบโดยเฉพาะผ่าน API ด้วยคำสั่ง cy.login
สากล ตั้งค่าคุกกี้เพื่อให้ผู้ใช้อยู่ในระบบ ทำการเรียก API ที่จำเป็นเพื่อส่งคืน ผู้ใช้ไปยังสถานะเริ่มต้นที่ต้องการผ่านการ cy.request(“endpoint”)
หรือ cy.task(“pluginAction”)
และไปที่หน้าตรวจสอบสิทธิ์ที่เราพยายามทดสอบโดยตรง จากนั้น เราจะดำเนินการตามขั้นตอนโดยอัตโนมัติเพื่อให้ขั้นตอนคุณลักษณะผู้ใช้บรรลุผลตามที่แสดงในรูปแบบการทดสอบด้านล่าง
จำคำสั่งที่กำหนดเองที่เราพูดถึงสำหรับการเข้าสู่ระบบ cy.login()
และออกจากระบบ cy.logout()
ได้หรือไม่ เราปรับใช้พวกมันอย่างง่ายดายใน Cypress ด้วยวิธีนี้ ดังนั้นการทดสอบทั้งหมดของเราจะเข้าสู่ระบบผู้ใช้ผ่าน API ในลักษณะเดียวกัน
นอกจากนี้ เราต้องการทำให้เป็นอัตโนมัติและยืนยันขั้นตอนที่ซับซ้อนบางอย่างเกี่ยวกับอีเมลที่เราไม่สามารถทำได้ดีมาก่อนด้วย WebdriverIO หรือ STUI ตัวอย่างบางส่วน ได้แก่ การส่งออกกิจกรรมอีเมลเป็น CSV การทำตามขั้นตอนการส่งไปยังเพื่อนร่วมงานสำหรับการตรวจสอบสิทธิ์ผู้ส่ง หรือการส่งออกผลการตรวจสอบอีเมลเป็น CSV Cypress ป้องกันไม่ให้เข้าถึง superdomains หลายรายการในการทดสอบครั้งเดียว ดังนั้นการนำทางไปยังไคลเอนต์อีเมลผ่าน UI ที่เราไม่ได้เป็นเจ้าของนั้นไม่สม่ำเสมอและไม่ใช่ตัวเลือก
เราได้พัฒนาปลั๊กอิน Cypress ผ่านคำสั่ง cy.task(“pluginAction”)
เพื่อใช้ไลบรารีบางตัวภายในเซิร์ฟเวอร์ Cypress Node เพื่อเชื่อมต่อกับไคลเอนต์/กล่องจดหมาย IMAP ของอีเมลทดสอบ เช่น SquirrelMail เพื่อตรวจสอบอีเมลที่ตรงกันในกล่องจดหมายหลังจากแจ้งการดำเนินการ ใน UI และสำหรับการติดตามลิงก์เปลี่ยนเส้นทางจากอีเมลเหล่านั้นกลับไปยังโดเมนเว็บแอปของเรา เพื่อตรวจสอบหน้าดาวน์โหลดบางหน้าที่ปรากฏขึ้นและดำเนินการตามขั้นตอนของลูกค้าทั้งหมดอย่างมีประสิทธิภาพ เราใช้ปลั๊กอินที่จะรอให้อีเมลมาถึงกล่องขาเข้า SquirrelMail ตามหัวเรื่อง ลบอีเมล ส่งอีเมล ทริกเกอร์เหตุการณ์อีเมล บริการแบ็กเอนด์โพล และทำการตั้งค่าและการแยกส่วนที่มีประโยชน์มากขึ้นผ่าน API เพื่อให้การทดสอบของเราใช้งานได้
เพื่อให้ข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับสิ่งที่เราทดสอบกับ Cypress จริง ๆ เราจึงได้กล่าวถึงกรณีที่มีมูลค่าสูงมากมาย เช่น:
- ตรวจสุขภาพสำหรับหน้าเว็บทั้งหมดของเรา ที่รู้จักในชื่อการเดินทางของแอป – เราต้องการให้แน่ใจว่าหน้าเว็บที่โหลดด้วยเนื้อหาบางอย่างทำให้บางครั้งบริการแบ็กเอนด์หรือฟรอนท์เอนด์โฮสติ้งจะหยุดทำงาน เรายังแนะนำให้ทำการทดสอบเหล่านี้ก่อนเพื่อสร้างความจำของกล้ามเนื้อจิตของการสร้างออบเจ็กต์หน้าด้วยตัวเลือกและฟังก์ชันตัวช่วย และรับการทดสอบการทำงานที่รวดเร็วและทำงานกับสภาพแวดล้อม
- การดำเนินการ CRUD บนเพจ – เราจะรีเซ็ตการทดสอบตามนั้นผ่าน API เสมอ จากนั้นจึงทดสอบเฉพาะการสร้าง อ่าน อัปเดต หรือลบใน UI ตัวอย่างเช่น หากเราทดสอบว่าสามารถสร้างการพิสูจน์ตัวตนโดเมนผ่าน UI ได้ ไม่ว่าการทดสอบครั้งสุดท้ายจะจบลงอย่างไร เราจำเป็นต้องตรวจสอบให้แน่ใจว่าโดเมนที่เราจะสร้างผ่าน UI นั้นถูกลบผ่าน API ในตอนแรกก่อนดำเนินการต่อ ด้วยขั้นตอน UI อัตโนมัติเพื่อสร้างโดเมนและหลีกเลี่ยงการชนกัน หากเราทดสอบว่าสามารถลบการระงับผ่าน UI ได้ เราต้องแน่ใจว่าได้สร้างการระงับผ่าน API ก่อนแล้วจึงดำเนินการตามขั้นตอน
- ทดสอบตัวกรองการค้นหาบนหน้าเว็บ เราทดสอบการตั้งค่าตัวกรองการค้นหาขั้นสูงจำนวนมากด้วยกิจกรรมอีเมล และไปที่หน้าด้วยพารามิเตอร์การค้นหาเพื่อให้แน่ใจว่าตัวกรองได้รับการเติมข้อมูลอัตโนมัติ เรายังเพิ่มข้อมูลผ่าน API สำหรับการตรวจสอบอีเมล และเริ่มต้นตัวกรองการค้นหาต่างๆ อีกครั้ง และตรวจสอบตารางที่ตรงกับตัวกรองการค้นหาในหน้านั้น
- การ เข้าถึงของผู้ใช้ที่แตกต่างกัน – ที่ Twilio SendGrid เรามีบัญชีหลักที่สามารถมีเพื่อนร่วมทีมที่มีขอบเขตหรือสิทธิ์การเข้าถึงที่แตกต่างกัน หรือผู้ใช้ย่อยที่อยู่ภายใต้พวกเขา ซึ่งมีระดับการเข้าถึงที่แตกต่างกันและทำงานค่อนข้างคล้ายกับบัญชีหลัก เพื่อนร่วมทีมที่มีสิทธิ์การเข้าถึงแบบอ่านอย่างเดียวและระดับผู้ดูแลระบบสำหรับบางเพจและผู้ใช้ย่อยจะเห็นหรือไม่เห็นบางสิ่งบนเพจ และทำให้ง่ายต่อการเข้าสู่ระบบอัตโนมัติในประเภทผู้ใช้เหล่านั้น และตรวจสอบสิ่งที่พวกเขาเห็นหรือไม่เห็นในการทดสอบ Cypress
- แพ็คเกจผู้ใช้ที่แตกต่างกัน – ผู้ใช้ของเรายังสามารถแตกต่างกันไปตามประเภทของแพ็คเกจแบบฟรีและแบบชำระเงิน เช่น Essentials, Pro และ Premier และแพ็คเกจเหล่านั้นสามารถดูหรือไม่เห็นบางสิ่งบนเพจได้เช่นกัน เราจะเข้าสู่ระบบผู้ใช้ด้วยแพ็คเกจที่แตกต่างกัน และตรวจสอบคุณสมบัติ คัดลอก หรือหน้าที่ผู้ใช้เข้าถึงได้ในการทดสอบ Cypress อย่างรวดเร็ว
ขั้นตอนที่ 4: เทียบท่าการทดสอบ
เมื่อดำเนินการขั้นตอนไปป์ไลน์ Buildkite แต่ละรายการบนเครื่อง AWS ใหม่ในคลาวด์ เราไม่สามารถเรียก npm run cypress:run:staging
ได้ง่ายๆ เพราะเครื่องเหล่านั้นไม่มี Node, เบราว์เซอร์, โค้ดแอปพลิเคชันของเรา หรือการขึ้นต่อกันอื่นๆ เพื่อเรียกใช้ Cypress การทดสอบ เมื่อเราตั้งค่า WebdriverIO มาก่อน เราจำเป็นต้องประกอบสามบริการที่แยกจากกันในไฟล์ Docker Compose เพื่อให้บริการ Selenium, Chrome และรหัสแอปพลิเคชันทำงานร่วมกันเพื่อให้การทดสอบทำงาน
ด้วย Cypress มันตรงไปตรงมามากขึ้นเพราะเราต้องการเพียงอิมเมจ Docker ของ cypress/base
เพื่อตั้งค่าสภาพแวดล้อมใน Dockerfile
และมีเพียงบริการเดียวในไฟล์ docker-compose.yml
-compose.yml ที่มีรหัสแอปพลิเคชันของเราเพื่อเรียกใช้ Cypress การทดสอบ เราจะพูดถึงวิธีหนึ่งในการทำเช่นนั้น เนื่องจากมีอิมเมจ Cypress Docker อื่นๆ ให้ใช้และวิธีอื่นๆ ในการตั้งค่าการทดสอบ Cypress ใน Docker เราขอแนะนำให้คุณดูเอกสาร Cypress สำหรับทางเลือกอื่น
เพื่อให้บริการกับแอปพลิเคชันทั้งหมดของเราและรหัสทดสอบที่จำเป็นในการทดสอบ Cypress เราได้สร้าง Dockerfile
ชื่อ Dockerfile.cypress
และติดตั้ง node_modules
ทั้งหมดและคัดลอกโค้ดไปยังไดเร็กทอรีการทำงานของอิมเมจในสภาพแวดล้อมของโหนด บริการ cypress
Docker Compose จะใช้สิ่งนี้ และเราตั้งค่า Dockerfile
สำเร็จด้วยวิธีต่อไปนี้:
ด้วย Dockerfile.cypress
นี้ เราสามารถรวม Cypress เพื่อเรียกใช้ข้อมูลจำเพาะที่เลือกกับ API สภาพแวดล้อมบางอย่างและแอปที่ปรับใช้ผ่านบริการ Docker Compose ที่เรียกว่า cypress
สิ่งที่เราต้องทำคือสอดแทรกตัวแปรสภาพแวดล้อมบางอย่าง เช่น SPECS
และ BASE_URL
เพื่อเรียกใช้การทดสอบ Cypress ที่เลือกกับ URL พื้นฐานบางอย่างผ่านคำ npm run cypress:run:cicd:staging
ซึ่งมีลักษณะดังนี้ ”cypress:run:cicd:staging”: “cypress run --record --key --config baseUrl=$BASE_URL --env testEnv=staging”
ตัวแปรสภาพแวดล้อมเหล่านี้จะได้รับการตั้งค่าผ่านไฟล์การตั้งค่า/การกำหนดค่าของไปป์ไลน์ Buildkite หรือส่งออกแบบไดนามิกเมื่อเรียกใช้การทดสอบ Cypress เพื่อเรียกใช้จากไปป์ไลน์การปรับใช้ของเรา ตัวอย่างไฟล์ docker-compose.cypress.yml
มีลักษณะดังนี้:
ยังมีอีกสองสามสิ่งที่ต้องสังเกต ตัวอย่างเช่น คุณสามารถดูตัวแปรสภาพแวดล้อม VERSION
ซึ่งช่วยให้เราอ้างอิงอิมเมจ Docker ที่ติดแท็กเฉพาะได้ เราจะสาธิตในภายหลังว่าเราแท็กอิมเมจ Docker อย่างไร จากนั้นดึงอิมเมจ Docker เดียวกันสำหรับบิลด์นั้นเพื่อทำงานกับโค้ดที่ถูกต้องสำหรับการทดสอบ Cypress
นอกจากนี้ คุณจะสังเกตเห็นว่า BUILDKITE_BUILD_ID
ถูกส่งผ่านไป ซึ่งมาฟรีพร้อมกับตัวแปรสภาพแวดล้อม Buildkite อื่นๆ สำหรับทุกบิลด์ที่เราเริ่มต้น และแฟล็ก ci-build-id
สิ่งนี้ทำให้คุณสมบัติการขนานของ Cypress ทำงานได้ และเมื่อเราตั้งค่าจำนวนเครื่องที่กำหนดสำหรับการทดสอบ Cypress มันจะรู้วิธีหมุนเครื่องเหล่านั้นโดยอัตโนมัติและแยกการทดสอบของเราเพื่อรันบนโหนดเครื่องทั้งหมดเพื่อเพิ่มประสิทธิภาพและเร่งการทดสอบของเรา เวลาทำงาน
ในที่สุด เรายังใช้ประโยชน์จากการติดตั้งไดรฟ์ข้อมูลและคุณลักษณะสิ่งประดิษฐ์ของ Buildkite เราอัปโหลดวิดีโอและภาพหน้าจอเพื่อให้เข้าถึงได้โดยตรงผ่านแท็บ "สิ่งประดิษฐ์" ของ Buildkite UI ในกรณีที่บันทึกการทดสอบที่จ่ายสำหรับเดือนนั้นหมดหรือไม่สามารถเข้าถึงบริการแดชบอร์ดได้ เมื่อใดก็ตามที่มีการเรียกใช้คำสั่ง Cypress “run” ในโหมด headless จะมีเอาต์พุตในโฟลเดอร์ cypress/videos
และ cypress/screenshots
ให้ตรวจสอบในเครื่อง และเราเพียงแค่เมานต์โฟลเดอร์เหล่านั้นและอัปโหลดไปยัง Buildkite เพื่อให้เราปลอดภัย
ขั้นตอนที่ 5: การผสานรวมกับ CICD
เมื่อเราได้รับการทดสอบ Cypress เพื่อเรียกใช้ได้สำเร็จในคอนเทนเนอร์ Docker กับสภาพแวดล้อมที่แตกต่างกัน เราก็เริ่มผสานรวมกับ Buildkite ผู้ให้บริการ CICD ของเรา Buildkite มีวิธีดำเนินการตามขั้นตอนในไฟล์ .yml
บนเครื่อง AWS ของเราด้วยสคริปต์ Bash และตัวแปรสภาพแวดล้อมที่ตั้งค่าไว้ในโค้ดหรือผ่านการตั้งค่าไปป์ไลน์ Buildkite ของ repo ใน UI ของเว็บ Buildkite ยังอนุญาตให้เราทริกเกอร์ไปป์ไลน์การทดสอบนี้จากไพพ์ไลน์การปรับใช้หลักของเราด้วยตัวแปรสภาพแวดล้อมที่ส่งออก และเราจะนำขั้นตอนการทดสอบเหล่านี้มาใช้ซ้ำสำหรับไพพ์ไลน์การทดสอบแบบแยกอื่น ๆ ซึ่งจะทำงานตามกำหนดเวลาสำหรับ QA ของเราในการตรวจสอบและดู
ในระดับสูง การทดสอบ Buildkite ไปป์ไลน์สำหรับ Cypress และไปป์ไลน์ WebdriverIO ก่อนหน้าของเราได้แชร์ขั้นตอนที่คล้ายกันต่อไปนี้:
- ตั้งค่าอิมเมจ Docker สร้าง แท็ก และพุชอิมเมจ Docker ที่จำเป็นสำหรับการทดสอบจนถึงรีจิสทรี เพื่อให้เราสามารถดึงมันออกมาในขั้นตอนต่อไป
- เรียกใช้การทดสอบตามการกำหนดค่าตัวแปรสภาพแวดล้อม ดึงอิมเมจ Docker ที่ติดแท็กสำหรับบิลด์เฉพาะและรันคำสั่งที่เหมาะสมกับสภาพแวดล้อมที่ปรับใช้เพื่อรันชุดทดสอบที่เลือกจากตัวแปรสภาพแวดล้อมที่ตั้งไว้
ต่อไปนี้คือตัวอย่างไฟล์ pipeline.cypress.yml
.cypress.yml ที่แสดงการตั้งค่าอิมเมจ Docker ในขั้นตอน “Build Cypress Docker Image” และรันการทดสอบในขั้นตอน “เรียกใช้การทดสอบ Cypress”:
สิ่งหนึ่งที่ควรสังเกตคือขั้นตอนแรก "สร้าง Cypress Docker Image" และวิธีตั้งค่าอิมเมจ Docker สำหรับการทดสอบ มันใช้คำสั่งบิลด์ Docker Compose เพื่อ build
บริการ cypress
ด้วยรหัสทดสอบแอปพลิเคชันทั้งหมดและแท็กด้วยตัวแปรสภาพแวดล้อม latest
และ ${VERSION}
เพื่อให้เราสามารถดึงรูปภาพเดียวกันนั้นลงมาด้วยแท็กที่เหมาะสมสำหรับบิลด์นี้ใน ขั้นตอนในอนาคต แต่ละขั้นตอนอาจดำเนินการบนเครื่องอื่นใน AWS Cloud ที่ใดที่หนึ่ง ดังนั้นแท็กจึงระบุรูปภาพสำหรับการเรียกใช้ Buildkite ที่เฉพาะเจาะจงได้โดยไม่ซ้ำกัน หลังจากติดแท็กรูปภาพแล้ว เราได้เพิ่มรูปภาพที่ติดแท็กเวอร์ชันล่าสุดไปยังรีจิสทรี Docker ส่วนตัวของเราเพื่อนำกลับมาใช้ใหม่
ในขั้นตอน “เรียกใช้การทดสอบ Cypress” เราดึงรูปภาพที่เราสร้าง แท็ก และผลักลงในขั้นตอนแรก และเริ่มบริการ Cypress เพื่อดำเนินการทดสอบ ตามตัวแปรสภาพแวดล้อม เช่น SPECS
และ BASE_URL
เราจะเรียกใช้ไฟล์ทดสอบเฉพาะกับสภาพแวดล้อมแอปที่ปรับใช้สำหรับบิลด์ Buildkite เฉพาะนี้ ตัวแปรสภาพแวดล้อมเหล่านี้จะถูกตั้งค่าผ่านการตั้งค่าไปป์ไลน์ Buildkite หรือจะถูกทริกเกอร์แบบไดนามิกจากสคริปต์ทุบตีที่จะแยกวิเคราะห์ฟิลด์เลือก Buildkite เพื่อกำหนดว่าชุดการทดสอบใดที่จะทำงานและเทียบกับสภาพแวดล้อมใด
เมื่อเราเลือกการทดสอบที่จะเรียกใช้ระหว่างไพพ์ไลน์ Buildkite CICD ของเรา และทริกเกอร์ไปป์ไลน์การทดสอบที่ทริกเกอร์โดยเฉพาะด้วยตัวแปรสภาพแวดล้อมที่ส่งออกบางอย่าง เราจะทำตาม pipeline.cypress.yml
ตอนในไฟล์ไพพ์ไลน์.cypress.yml เพื่อให้เกิดขึ้น ตัวอย่างของการทริกเกอร์การทดสอบหลังจากปรับใช้โค้ดใหม่กับสภาพแวดล้อมของสาขาคุณลักษณะจากไพพ์ไลน์การปรับใช้จะมีลักษณะดังนี้:
การทดสอบที่ทริกเกอร์จะทำงานในไปป์ไลน์แยกกัน และหลังจากติดตามลิงก์ “รุ่น #639” จะนำเราไปยังขั้นตอนการสร้างสำหรับการทดสอบที่ทริกเกอร์ดังด้านล่าง:
การนำไฟล์ pipeline.cypress.yml
ไลน์.cypress.yml เดิมกลับมาใช้ใหม่สำหรับไปป์ไลน์ Cypress Buildkite ที่ทำงานตามกำหนดเวลา เรามีบิลด์ เช่น ไฟล์ที่รัน "P1" ซึ่งเป็นการทดสอบ E2E ที่มีลำดับความสำคัญสูงสุด ดังแสดงในรูปภาพด้านล่าง:
สิ่งที่เราต้องทำคือตั้งค่าตัวแปรสภาพแวดล้อมที่เหมาะสมสำหรับสิ่งต่าง ๆ เช่นข้อมูลจำเพาะที่จะเรียกใช้และสภาพแวดล้อมแบ็กเอนด์ใดที่จะโจมตีในการตั้งค่าของไปป์ไลน์ Buildkite จากนั้น เราสามารถกำหนดค่าบิลด์ตามกำหนดการของ Cron ซึ่งอยู่ในการตั้งค่าไปป์ไลน์ด้วย ให้เริ่มต้นทุก ๆ ชั่วโมงตามที่กำหนดและเราพร้อมแล้วที่จะไป We would then create many other separate pipelines for specific feature pages as needed to run on a schedule in a similar way and we would only vary the Cron schedule and environment variables while once again uploading the same `pipeline.cypress.yml` file to execute.
In each of those “Run Cypress tests” steps, we can see the console output with a link to the recorded test run in the paid Dashboard Service, the central place to manage your team's test recordings, billing, and other Cypress stats. Following the Dashboard Service link would take us to a results view for developers and QAs to take a look at the console output, screenshots, video recordings, and other metadata if required such as this:
Step 6: Comparing Cypress vs. WebdriverIO/STUI
After diving into our own custom Ruby Selenium solution in STUI, WebdriverIO, and finally Cypress tests, we recorded our tradeoffs between Cypress and Selenium wrapper solutions.
ข้อดี
- It's not another Selenium wrapper – Our previous solutions came with a lot of Selenium quirks, bugs, and crashes to work around and resolve, whereas Cypress arrived without the same baggage and troubles to deal with in allowing us full access to the browser.
- More resilient selectors – We no longer had to explicitly wait for everything like in WebdriverIO with all the
$(.selector).waitForVisible()
calls and now rely oncy.get(...)
and cy.contains(...)
commands with their default timeout. It will automatically keep on retrying to retrieve the DOM elements and if the test demanded a longer timeout, it is also configurable per command. With less worrying about the waiting logic, our tests became way more readable and easier to chain. - Vastly improved developer experience – Cypress provides a large toolkit with better and more extensive documentation for assertions, commands, and setup. We loved the options of using the Cypress GUI, running in headless mode, executing in the command-line, and chaining more intuitive Cypress commands.
- Significantly better developer efficiency and debugging – When running the Cypress GUI, one has access to all of the browser console to see some helpful output, time travel debug and pause at certain commands in the command log to see before and after screenshots, inspect the DOM with the selector playground, and discern right away at which command the test failed. In WebdriverIO or STUI we struggled with observing the tests run over and over in a browser and then the console errors would not point us toward and would sometimes even lead us astray from where the test really failed in the code. When we opted to run the Cypress tests in headless mode, we got console errors, screenshots, and video recordings. With WebdriverIO we only had some screenshots and confusing console errors. These benefits resulted in us cranking out E2E tests much faster and with less overall time spent wondering why things went wrong. We recorded it took less developers and often around 2 to 3 times less days to write the same level of complicated tests with Cypress than with WebdriverIO or STUI.
- Network stubbing and mocking – With WebdriverIO or STUI, there was no such thing as network stubbing or mocking in comparison to Cypress. Now we can have endpoints return certain values or we can wait for certain endpoints to finish through
cy.server()
andcy.route()
. - Less time to set up locally – With WebdriverIO or STUI, there was a lot of time spent up front researching which reporters, test runners, assertions, and services to use, but with Cypress, it came bundled with everything and started working after just doing an
npm install cypress.
- Less time to set up with Docker – There are a bunch of ways to set up WebdriverIO with Selenium, browser, and application images that took us considerably more time and frustration to figure out in comparison to Cypress's Docker images to use right out of the gate.
- Parallelization with various CICD providers – We were able to configure our Buildkite pipelines to spin up a certain number of AWS machines to run our Cypress tests in parallel to dramatically speed up the overall test run time and uncover any flakiness in tests using the same resources. The Dashboard Service would also recommend to us the optimal number of machines to spin up in parallel for the best test run times.
- Paid Dashboard Service – When we run our Cypress tests in a Docker container in a Buildkite pipeline during CICD, our tests are recorded and stored for us to look at within the past month through a paid Dashboard Service. We have a parent organization for billing and separate projects for each frontend application to check out console output, screenshots, and recordings of all of our test runs.
- Tests are way more consistent and maintainable – Tests passed way more consistently with Cypress in comparison to WebdriverIO and STUI where the tests kept on failing so much to the point where they were often ignored. Cypress tests failing more often signaled actual issues and bugs to look into or suggested better ways to refactor our tests to be less flaky. With WebdriverIO and STUI, we wasted a lot more time in maintaining those tests to be somewhat useful, whereas with Cypress, we would every now and then adjust the tests in response to changes in the backend services or minor changes in the UI.
- Tests are faster – Builds passed way more consistently and overall test run times would be around 2 to 3 times faster when run serially without parallelization. We used to have overall test runs that would take hours with STUI and around 40 minutes with WebdriverIO, but now with way more tests and with the help of parallelization across many machine nodes, we can run over 200 tests in under 5 minutes .
- Room to grow with added features in the future – With a steady open-source presence and dedicated Cypress team working towards releasing way more features and improvements to the Cypress infrastructure, we viewed Cypress as a safer bet to invest in rather than STUI, which would require us to engineer and solve a lot of the headaches ourselves, and WebdriverIO, which appeared to feel more stagnant in new features added but with the same baggage as other Selenium wrappers.
ข้อเสีย
- Lack of cross-browser support – As of this writing, we can only run our tests against Chrome. With WebdriverIO, we could run tests against Chrome, Firefox, Safari, and Opera. STUI also provided some cross-browser testing, though in a much limited form since we created a custom in-house solution
- Cannot integrate with some third-party services – With WebdriverIO, we had the option to integrate with services like BrowserStack and Sauce Labs for cross-browser and device testing. However, with Cypress there are no such third-party integrations but there are some plugins with services like Applitools for visual regression testing available. STUI, on the other hand, also had some small integrations with TestRail , but as a compromise, we log out the TestRail links in our Cypress tests so we can refer back to them if we needed to.
- Requires workarounds to test with iframes – There are some issues around handling iframes with Cypress. We ended up creating a global Cypress command to wrap how to deal with retrieving an iframe's contents as there is no specific API to deal with iframes like how WebdriverIO does.
To summarize our STUI, WebdriverIO, and Cypress comparison, we analyzed the overall developer experience (related to tools, writing tests, debugging, API, documentation, etc.), test run times, test passing rates, and maintenance as displayed in this table:
Following our analysis of the pros and cons of Cypress versus our previous solutions, it was pretty clear Cypress would be our best bet to accomplish our goal of writing fast, valuable, maintainable, and debuggable E2E tests we could integrate with CICD.
Though Cypress lacked features such as cross-browser testing and other integrations with third-party services that we could have had with STUI or WebdriverIO, we most importantly need tests that work more often than not and with the right tools to confidently fix broken ones. If we ever needed cross-browser testing or other integrations we could always still circle back and use our knowledge from our trials and experiences with WebdriverIO and STUI to still run a subset of tests with those frameworks.
We finally presented our findings to the rest of the frontend organization, engineering management, architects, and product. Upon demoing the Cypress test tools and showcasing our results between WebdriverIO/STUI and Cypress, we eventually received approval to standardize and adopt Cypress as our E2E testing library of choice for our frontend teams.
Step 7: Scaling to Other Frontend Teams
After successfully proving that using Cypress was the way to go for our use cases, we then focused on scaling it across all of our frontend teams' repos. We shared lessons learned and patterns of how to get up and running, how to write consistent, maintainable Cypress tests, and of how to hook those tests up during CICD or in scheduled Cypress Buildkite pipelines.
To promote greater visibility of test runs and gain access to a private monthly history of recordings, we established our own organization to be under one billing method to pay for the Dashboard Service with a certain recorded test run limit and maximum number of users in the organization to suit our needs.
Once we set up an umbrella organization, we invited developers and QAs from different frontend teams and each team would install Cypress, open up the Cypress GUI, and inspect the “Runs” and “Settings” tab to get the “Project ID” to place in their `cypress.json` configuration and “Record Key” to provide in their command options to start recording tests to the Dashboard Service. Finally, upon successfully setting up the project and recording tests to the Dashboard Service for the first time, logging into the Dashboard Service would show that team's repo under the “Projects” tab like this:
When we clicked a project like “mako”, we then had access to all of the test runs for that team's repo with quick access to console output, screenshots, and video recordings per test run upon clicking each row as shown below:
For more insights into our integration, we set up many separate dedicated test pipelines to run specific, crucial page tests on a schedule like say every couple hours to once per day. We also added functionality in our main Buildkite CICD deploy pipeline to select and trigger some tests against our feature branch environment and staging environment.
อย่างที่คาดไว้ สิ่งนี้เกิดขึ้นอย่างรวดเร็วผ่านการดำเนินการทดสอบที่บันทึกไว้สำหรับเดือนนั้น โดยเฉพาะอย่างยิ่งเนื่องจากมีหลายทีมที่ร่วมสนับสนุนและเรียกใช้การทดสอบในรูปแบบต่างๆ จากประสบการณ์ เราขอแนะนำให้คำนึงถึงจำนวนการทดสอบที่รันตามกำหนดเวลา ความถี่ในการเรียกใช้การทดสอบเหล่านั้น และการทดสอบใดที่เรียกใช้ระหว่าง CICD อาจมีการทดสอบซ้ำซ้อนและพื้นที่อื่นๆ ที่ประหยัดกว่า เช่น การโทรกลับความถี่ของการทดสอบตามกำหนดเวลา หรืออาจกำจัดบางส่วนทั้งหมดสำหรับการทริกเกอร์การทดสอบระหว่าง CICD เท่านั้น
กฎเดียวกันของการประหยัดจะใช้กับการเพิ่มผู้ใช้ ในขณะที่เราเน้นให้เข้าถึงเฉพาะนักพัฒนาและ QA ในทีมส่วนหน้าที่จะใช้บริการแดชบอร์ดอย่างหนัก แทนที่จะเป็นผู้บริหารระดับสูงและบุคคลอื่นนอกทีมเหล่านั้นเพื่อเติมเต็มจุดที่จำกัดเหล่านั้น
สิ่งที่เรารอคอยกับ Cypress
ดังที่เราได้กล่าวไว้ก่อนหน้านี้ Cypress ได้แสดงให้เห็นถึงคำมั่นสัญญาและศักยภาพมากมายสำหรับการเติบโตในชุมชนโอเพ่นซอร์ส และด้วยทีมงานเฉพาะที่รับผิดชอบในการนำเสนอคุณสมบัติที่เป็นประโยชน์มากขึ้นสำหรับเราเพื่อใช้กับการทดสอบ E2E ของเรา ข้อเสียมากมายที่เราเน้นกำลังได้รับการแก้ไขและเราหวังว่าจะได้รับสิ่งต่าง ๆ เช่น:
- การสนับสนุนข้ามเบราว์เซอร์ - นี่เป็นเรื่องใหญ่เพราะการผลักดันให้เรากลับมาใช้ Cypress เป็นจำนวนมากนั้นมาจากการใช้งาน Chrome เท่านั้นเมื่อเปรียบเทียบกับโซลูชันที่ใช้ Selenium ซึ่งสนับสนุนเบราว์เซอร์เช่น Firefox, Chrome และ Safari โชคดีที่การทดสอบที่เชื่อถือได้ บำรุงรักษาได้ และดีบักได้นั้นชนะสำหรับองค์กรของเรา และเราหวังว่าจะเพิ่มชุดทดสอบของเราด้วยการทดสอบข้ามเบราว์เซอร์เพิ่มเติมในอนาคตเมื่อทีม Cypress เผยแพร่การสนับสนุนข้ามเบราว์เซอร์ดังกล่าว
- การ เขียนเลเยอร์เครือข่ายใหม่ – นี่เป็นเรื่องใหญ่เช่นกัน เนื่องจากเรามักจะใช้ Fetch API อย่างหนักในพื้นที่ React ที่ใหม่กว่าของเรา และในพื้นที่แอปพลิเคชัน Backbone/Marionette ที่เก่ากว่า เรายังคงใช้ jQuery AJAX และการเรียกใช้ XHR ตามปกติ เราสามารถดึงข้อมูลหรือฟังคำขอในพื้นที่ XHR ได้อย่างง่ายดาย แต่ต้องทำวิธีแก้ปัญหาเฉพาะหน้าด้วยการดึงข้อมูล polyfills เพื่อให้ได้ผลเช่นเดียวกัน การเขียนเลเยอร์เครือข่ายใหม่น่าจะช่วยบรรเทาความเจ็บปวดเหล่านั้นได้
- การปรับปรุงส่วนเพิ่มของบริการแดชบอร์ด – เราได้เห็นการเปลี่ยนแปลง UI ใหม่บางอย่างในบริการแดชบอร์ดเมื่อเร็วๆ นี้ และเราหวังว่าจะยังคงเห็นการเติบโตด้วยการแสดงภาพสถิติและการแจกแจงข้อมูลที่เป็นประโยชน์มากขึ้น เรายังใช้คุณสมบัติการขนานกันอย่างหนัก และตรวจสอบการบันทึกการทดสอบที่ล้มเหลวของเราใน Dashboard Service บ่อยครั้ง ดังนั้นการปรับปรุงเลย์เอาต์และ/หรือคุณสมบัติซ้ำๆ จะเป็นการดีที่จะได้เห็น
การนำ Cypress ไปสู่อนาคต
สำหรับองค์กรของเรา เราให้ความสำคัญกับประสิทธิภาพของนักพัฒนา การดีบัก และความเสถียรของการทดสอบ Cypress เมื่อทำงานภายใต้เบราว์เซอร์ Chrome เราทำการทดสอบที่มีคุณค่าและสม่ำเสมอโดยมีการบำรุงรักษาน้อยลงและมีเครื่องมือมากมายในการพัฒนาการทดสอบใหม่และแก้ไขการทดสอบที่มีอยู่
โดยรวมแล้ว เอกสารประกอบ, API และเครื่องมือที่เรามีอยู่นั้นมีมากกว่าข้อเสียใดๆ หลังจากประสบกับ Cypress GUI และบริการแดชบอร์ดแบบชำระเงินแล้ว เราไม่ต้องการกลับไปที่ WebdriverIO หรือโซลูชัน Ruby Selenium แบบกำหนดเองของเราอย่างแน่นอน
เราเชื่อมต่อการทดสอบของเรากับ Buildkite และบรรลุเป้าหมายใน การจัดหาวิธีเขียนการทดสอบอัตโนมัติ E2E ที่สอดคล้องกัน แก้จุดบกพร่อง บำรุงรักษา และมีค่าสำหรับแอปพลิเคชันส่วนหน้าของเราเพื่อผสานรวมกับ CICD เราพิสูจน์ด้วยหลักฐานกับทีมส่วนหน้าที่เหลือ วิศวกรระดับสูง และเจ้าของผลิตภัณฑ์ถึงประโยชน์ของการใช้ Cypress และปล่อย WebdriverIO และ STUI
การทดสอบหลายร้อยครั้งในภายหลังในทีมส่วนหน้าใน Twilio SendGrid และเราตรวจพบข้อบกพร่องมากมายในสภาพแวดล้อมการแสดงละครของเรา และสามารถแก้ไขการทดสอบที่ไม่สม่ำเสมอในด้านของเราได้อย่างรวดเร็วด้วยความมั่นใจมากกว่าที่เคยเป็นมา นักพัฒนาและ QA ไม่กลัวที่จะเขียนการทดสอบ E2E อีกต่อไป แต่ตอนนี้ตั้งตารอที่จะเขียนมันสำหรับฟีเจอร์ใหม่ทุกรายการที่เราเปิดตัว หรือสำหรับฟีเจอร์ที่เก่ากว่าทุกรายการที่อาจมีความครอบคลุมมากขึ้น