การจัดการกับกระแสอีเมลในการทดสอบ Cypress #frontend@twiiosendgrid

เผยแพร่แล้ว: 2020-11-24

Twilio SendGrid ส่งอีเมลจำนวนมาก ในการส่งอีเมลธุรกรรมทั้งหมดของเรา ตั้งแต่การรีเซ็ตรหัสผ่านไปจนถึงการยืนยันอีเมลของบัญชีเพื่อส่งออกอีเมล CSV เราใช้บริการแบ็กเอนด์ของเราเอง

เมื่อเร็วๆ นี้เราได้ผ่านขั้นตอนสำคัญกว่า 3 ล้านล้านอีเมลที่ส่งไป

ในสภาพแวดล้อมการทดสอบของเรา เราส่งอีเมลเพื่อทดสอบกล่องขาเข้าของอีเมลใน เซิร์ฟเวอร์ Squirrelmail ที่โฮสต์เองเพื่อหลีกเลี่ยงการส่งอีเมลทดสอบไปยังผู้ให้บริการกล่องจดหมายอีเมลจริง เช่น Gmail ขั้นตอนสำคัญหลายอย่างกำหนดให้ผู้ใช้ตรวจสอบอีเมล คลิกลิงก์ที่ดำเนินการได้ เปลี่ยนเส้นทางกลับไปที่เว็บแอปพลิเคชัน จากนั้นดำเนินการต่อในหน้าดาวน์โหลดหรือยืนยันความสำเร็จ

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

ก่อนที่เราจะเข้าสู่โพสต์ ต่อไปนี้คือบทความสองสามบทความที่คุณอาจสนใจอ่านก่อน

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

โพสต์นี้ถือว่าคุณรู้จักฟังก์ชัน Cypress บางอย่าง เช่น cy.task() เพื่อเรียกใช้โค้ดตามอำเภอใจที่เรากำหนดในเซิร์ฟเวอร์ Node เพื่อช่วยเราจัดการกับอีเมล นอกจากนี้ หากข้อมูลโค้ดในภายหลังด้วย TypeScript ทำให้เกิดความสับสนเล็กน้อย อาจเข้าใจชัดเจนขึ้นเมื่อเห็นโพสต์บนบล็อกของเราเกี่ยวกับวิธีที่เราพิมพ์การทดสอบ Cypress ของเรา คุณยังคงแก้ไขโค้ดได้ในการทดสอบ Cypress ของคุณเองโดยลบคำจำกัดความของประเภทและใช้ไวยากรณ์เฉพาะ JavaScript

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

เราจะจัดการกับกระแสอีเมลในการทดสอบ Cypress อย่างไร

เพื่อให้เราสามารถทดสอบโฟลว์อีเมลทั้งหมดได้ เราได้สร้างปลั๊กอิน cy.task() เพื่อ:

  • จัดการกับการเชื่อมต่อและการกรองผ่านกล่องจดหมายอีเมลสำหรับอีเมลที่มีหัวเรื่องเฉพาะ
  • กำลังดึงเนื้อหาเนื้อหาของอีเมลที่ตรงกัน
  • การลบอีเมลจากกล่องจดหมายของผู้ใช้โดยไม่ต้องเข้าสู่ระบบผ่าน Squirrelmail UI

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

ก่อนอื่นเราติดตั้งไลบรารีชื่อ "emailjs-imap-client" เพื่อช่วยเราตั้งค่าไคลเอ็นต์ IMAP เพื่อเชื่อมต่อกับกล่องจดหมาย Squirrelmail ของเราผ่านข้อมูลประจำตัวและการกำหนดค่าโฮสต์ เมื่อใช้ไลบรารีนี้ เราได้สรุปสิ่งที่เกี่ยวข้องกับ Squirrelmail ทั้งหมดไว้ในโมดูลที่เรียกว่า squirrelmail.ts ซึ่งเราจะนำเข้าในภายหลังใน plugins/index.ts สำหรับคำจำกัดความฟังก์ชัน cy.task() ของเรา

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


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

นี่คือวิธีที่เราพัฒนาฟังก์ชันสำหรับการรออีเมลที่มีหัวเรื่องเฉพาะ เช่น “การส่งออกกิจกรรมอีเมลของคุณ” หรือ “การยืนยันผู้ส่ง” ที่จะมาถึงในกล่องจดหมายอีเมลของผู้ใช้

จนถึงตอนนี้:

  • เราล้างกล่องจดหมายของผู้ใช้ออกแล้ว
  • การทดสอบทำงานและทริกเกอร์อีเมลที่จะส่งไปยังกล่องจดหมายของผู้ใช้
  • เรารออีเมลมาถึงกล่องจดหมายของผู้ใช้เรียบร้อยแล้ว

ตอนนี้ เราจำเป็นต้องได้รับเนื้อหาเนื้อหาของอีเมลนั้นๆ

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

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

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

สำหรับการแยกวิเคราะห์เนื้อหา HTML ของอีเมลและค้นหาส่วนลิงก์การดำเนินการ เราใช้ไลบรารีอื่นที่เรียกว่า "cheerio" ซึ่งโหลดสตริง HTML และช่วยให้เราเรียกใช้ฟังก์ชันที่คล้ายกับ jQuery เพื่อแยกปุ่มการทำงานหรือลิงก์ที่เราต้องการ เมื่อเราแยกวิเคราะห์ลิงก์แล้ว เราจะส่งคำขอ HTTP ไปยังลิงก์ด้วย cy.request() ตามลิงก์เปลี่ยนเส้นทางกลับไปที่เว็บแอปที่เราควบคุมและเป็นเจ้าของใน superdomain เดียว และดำเนินการยืนยันสถานะความสำเร็จบนหน้าเว็บที่เรา เปลี่ยนเส้นทางไปที่

ในกรณีของคุณ คุณอาจไม่จำเป็นต้องเรียกใช้คำขอ HTTP ที่ลิงก์และทำตามการเปลี่ยนเส้นทางของการตอบกลับ หากลิงก์ของคุณชี้ไปยังตำแหน่งที่ถูกต้องแล้ว หาก URL ของลิงก์ชี้ไปที่เว็บแอปของคุณโดยตรงแล้ว ไม่มีอะไรหยุดคุณจากการดึงเส้นทางของลิงก์และดำเนินการ cy.visit(linkPath) เพื่อเปลี่ยนเส้นทางกลับไปที่แอปของคุณ ในกรณีของลิงก์ Twilio SendGrid ลิงก์อาจดูเหมือน “…sendgrid.net?…” หากคุณมีการติดตามลิงก์สำหรับอีเมลของคุณหรือ “brandedlink.com” หากคุณมีการสร้างแบรนด์ลิงก์ นั่นคือเหตุผลที่เราต้องส่งคำขอ HTTP และดึงเส้นทางการเปลี่ยนเส้นทางเพื่อทำ cy.visit(redirectPath) เนื่องจาก "href" ของลิงก์ในทันทีไม่ตรงกับเว็บแอปของเรา

ด้านล่างนี้คือตัวอย่างการค้นหาลิงก์ด้วย cheerio การขอ HTTP ไปยังลิงก์ และการติดตามการเปลี่ยนเส้นทาง

บทสรุป

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

  • ทำลายอีเมลทั้งหมดที่มีหัวเรื่องเพื่อหลีกเลี่ยงผลบวกปลอมด้วย cy.task(“teardownMatchingEmails”)
  • เข้าสู่ระบบผู้ใช้ผ่าน API จากนั้นดำเนินการตามชุดขั้นตอนผ่าน UI เพื่อสร้างอีเมลนั้นเพื่อส่งไปยังกล่องจดหมายอีเมลของผู้ใช้
  • โพลสำหรับกล่องจดหมายอีเมลของผู้ใช้เพื่อรับอีเมลที่มีหัวเรื่องตรงกันผ่าน cy.task(“awaitEmailInSquirrelmailInbox”)
  • อ่านเนื้อหาในอีเมลที่มีหัวเรื่องตรงกันโดยใช้ cy.task(“squirrelmailSearchBySubject”)
  • แยกวิเคราะห์ลิงก์การดำเนินการที่เหมาะสมกับไลบรารีของ cheerio โดยส่งผ่านสตริง HTML ของเนื้อหาอีเมลและค้นหาองค์ประกอบต่างๆ ด้วยไวยากรณ์ที่เหมือน jQuery
  • ส่งคำขอ HTTP ในลิงก์อีเมลที่แยกวิเคราะห์ผ่าน cy.request(“link”) และทำตามการตอบกลับการเปลี่ยนเส้นทางกลับไปที่เว็บแอป หรือไปที่เส้นทางหากลิงก์นั้นตรงกับ superdomain ของคุณด้วย cy.visit(“emailLinkToWebApp”) .
  • ตรวจสอบว่าสถานะความสำเร็จเกิดขึ้นหรือติดตามด้วยขั้นตอน UI เพิ่มเติมบนเพจที่คุณเป็นเจ้าของ

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

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

  • สิ่งที่ต้องพิจารณาเมื่อเขียนการทดสอบ E2E
  • ภาพรวม 1,000 ฟุตของการเขียนแบบทดสอบ Cypress
  • TypeScript ทุกสิ่งในการทดสอบ Cypress ของคุณ
  • แนวคิดสำหรับการกำหนดค่า การจัดระเบียบ และการรวมการทดสอบ Cypress ของคุณ
  • การรวมการทดสอบ Cypress กับ Docker, Buildkite และ CICD