คู่มือ Node.js ในการทำการทดสอบการผสานการทำงานจริง

เผยแพร่แล้ว: 2022-03-11

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

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

คุณรู้ว่าคุณจำเป็นต้องเขียนการทดสอบการรวมระบบ เหตุใดคุณจึงไม่ทำ
ทวีต

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

แม้ว่าเราจะใช้ JavaScript/Node.js สำหรับตัวอย่างโค้ดทั้งหมดในบทความนี้ แนวคิดส่วนใหญ่ที่กล่าวถึงสามารถปรับให้เข้ากับการทดสอบการรวมบนแพลตฟอร์มใดก็ได้

การทดสอบหน่วยเทียบกับการทดสอบการรวม: คุณต้องการทั้งสองอย่าง

การทดสอบหน่วยเน้นที่รหัสหน่วยหนึ่งโดยเฉพาะ บ่อยครั้ง นี่เป็นวิธีการเฉพาะหรือหน้าที่ของส่วนประกอบที่ใหญ่กว่า

การทดสอบเหล่านี้ทำแบบแยกส่วน โดยที่การขึ้นต่อกันภายนอกทั้งหมดมักจะถูกขัดขวางหรือเยาะเย้ย

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

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการทดสอบหน่วยได้ที่นี่

การทดสอบหน่วยใช้เพื่อรักษาโค้ดคุณภาพสูงด้วยการออกแบบที่ดี พวกเขายังช่วยให้เราสามารถครอบคลุมกรณีมุมได้อย่างง่ายดาย

อย่างไรก็ตาม ข้อเสียคือ การทดสอบหน่วยไม่สามารถครอบคลุมการโต้ตอบระหว่างส่วนประกอบได้ นี่คือจุดที่การทดสอบการรวมจะมีประโยชน์

การทดสอบบูรณาการ

หากการทดสอบหน่วยถูกกำหนดโดยการทดสอบหน่วยที่เล็กที่สุดของโค้ดโดยแยกจากกัน การทดสอบการรวมจะตรงกันข้าม

การทดสอบการรวมใช้เพื่อทดสอบหลายหน่วย (ส่วนประกอบ) ที่ใหญ่กว่าในการโต้ตอบ และบางครั้งสามารถขยายได้หลายระบบ

จุดประสงค์ของการทดสอบการรวมคือเพื่อค้นหาจุดบกพร่องในการเชื่อมต่อและการขึ้นต่อกันระหว่างส่วนประกอบต่างๆ เช่น:

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

หากส่วนประกอบที่เรากำลังทดสอบไม่มีตรรกะที่ซับซ้อน (เช่น ส่วนประกอบที่มีความซับซ้อนน้อยที่สุด) การทดสอบการรวมจะมีความสำคัญมากกว่าการทดสอบหน่วย

ในกรณีนี้ การทดสอบหน่วยจะใช้เพื่อบังคับใช้การออกแบบโค้ดที่ดีเป็นหลัก

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

การทดสอบหน่วยและการทดสอบการรวมเป็นเหมือนสองด้านของเหรียญเดียวกัน เหรียญไม่ถูกต้องหากไม่มีทั้งสองอย่าง

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

ตั้งค่า Suite for Integration Tests

แม้ว่าการตั้งค่าชุดทดสอบสำหรับการทดสอบหน่วยจะค่อนข้างตรงไปตรงมา แต่บ่อยครั้งที่การตั้งค่าชุดทดสอบสำหรับการทดสอบการรวมระบบมักมีความท้าทายมากกว่า

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

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

เมื่อมีความจำเป็น อาจนำไปสู่ความท้าทายหลายประการ

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

คำแนะนำในการปฏิบัติตามขณะเขียนแบบทดสอบบูรณาการ

การทดสอบการรวมไม่มีกฎเกณฑ์ที่เข้มงวด เช่น การทดสอบหน่วย อย่างไรก็ตาม มีคำแนะนำทั่วไปบางประการที่ต้องปฏิบัติตามเมื่อเขียนการทดสอบการรวม

การทดสอบซ้ำได้

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

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

การทดสอบการดำเนินการที่เกี่ยวข้อง

ในการทดสอบกรณีที่เป็นไปได้ทั้งหมด การทดสอบหน่วยเป็นตัวเลือกที่ดีกว่ามาก

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

การทดสอบและการยืนยันที่เข้าใจได้

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

ตั้งค่าการทดสอบอย่างง่าย

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

หลีกเลี่ยงการทดสอบรหัสบุคคลที่สาม

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

ปล่อยให้รหัสการผลิตไม่มีรหัสทดสอบ

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

การบันทึกที่เกี่ยวข้อง

การทดสอบที่ล้มเหลวจะไม่มีค่ามากหากไม่มีการบันทึกที่ดี

เมื่อการทดสอบผ่าน ไม่จำเป็นต้องมีการบันทึกเพิ่มเติม แต่เมื่อล้มเหลว การตัดไม้จำนวนมากก็มีความสำคัญ

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

การทดสอบที่ดีนั้นดูสะอาดและเข้าใจได้

การทดสอบอย่างง่ายที่ปฏิบัติตามหลักเกณฑ์ในที่นี้อาจมีลักษณะดังนี้:

 const co = require('co'); const test = require('blue-tape'); const factory = require('factory'); const superTest = require('../utils/super_test'); const testEnvironment = require('../utils/test_environment_preparer'); const path = '/v1/admin/recipes'; test(`API GET ${path}`, co.wrap(function* (t) { yield testEnvironment.prepare(); const recipe1 = yield factory.create('recipe'); const recipe2 = yield factory.create('recipe'); const serverResponse = yield superTest.get(path); t.deepEqual(serverResponse.body, [recipe1, recipe2]); }));

โค้ดด้านบนกำลังทดสอบ API ( GET /v1/admin/recipes ) ที่คาดว่าจะส่งคืนอาร์เรย์ของสูตรที่บันทึกไว้เป็นการตอบกลับ

คุณจะเห็นว่าการทดสอบที่ง่าย ๆ นั้นอาศัยยูทิลิตี้มากมาย นี่เป็นเรื่องปกติสำหรับชุดทดสอบการรวมที่ดี

ส่วนประกอบ Helper ช่วยให้เขียนการทดสอบการรวมที่เข้าใจได้ง่าย

มาดูกันว่าส่วนประกอบใดบ้างที่จำเป็นสำหรับการทดสอบการรวม

ส่วนประกอบตัวช่วย

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

การควบคุมการไหล

หนึ่งในความท้าทายที่ใหญ่ที่สุดในการทดสอบ JavaScript คือโฟลว์แบบอะซิงโครนัส

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

ระหว่างรอการรองรับ async/await อย่างสมบูรณ์ คุณสามารถใช้ไลบรารีที่มีพฤติกรรมคล้ายกันได้ เป้าหมายคือการเขียนโค้ดที่อ่านง่าย สื่อความหมายได้ชัดเจน และสามารถมี async flow ได้

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

อีกวิธีหนึ่งคือใช้ Bluebird Bluebird เป็นไลบรารีสัญญาที่มีคุณลักษณะที่มีประโยชน์มาก เช่น การจัดการอาร์เรย์ ข้อผิดพลาด เวลา ฯลฯ

Co และ Bluebird coroutine ทำงานคล้ายกับ async/await ใน ES7 (รอการแก้ไขก่อนที่จะดำเนินการต่อ) ข้อแตกต่างเพียงอย่างเดียวคือมันจะส่งคืนสัญญาเสมอ ซึ่งมีประโยชน์สำหรับการจัดการข้อผิดพลาด

กรอบการทดสอบ

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

มีกรอบการทดสอบมากมายใน JavaScript ในตัวอย่างของเรา เรากำลังใช้เทป ในความคิดของฉัน Tape ไม่เพียงแต่ตอบสนองความต้องการเหล่านี้เท่านั้น แต่ยังสะอาดกว่าและง่ายกว่ากรอบการทดสอบอื่นๆ เช่น Mocha หรือ Jasmin

เทปจะขึ้นอยู่กับโปรโตคอลการทดสอบทุกอย่าง (TAP)

TAP มีรูปแบบที่หลากหลายสำหรับภาษาการเขียนโปรแกรมส่วนใหญ่

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

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

ห้องสมุดโรงงาน

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

JavaScript มี factory_girl สำหรับสิ่งนี้ - ไลบรารีที่ได้รับแรงบันดาลใจจากอัญมณีที่มีชื่อคล้ายกัน ซึ่งเดิมพัฒนาขึ้นสำหรับ Ruby on Rails

 const factory = require('factory-girl').factory; const User = require('../models/user'); factory.define('user', User, { username: 'Bob', number_of_recipes: 50 }); const user = factory.build('user');

ในการเริ่มต้น ต้องกำหนดโมเดลใหม่ใน factory_girl

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

อีกทางหนึ่ง แทนที่จะกำหนดอ็อบเจ็กต์ที่สร้างอินสแตนซ์ใหม่ สามารถจัดเตรียมฟังก์ชันที่จะส่งคืนอ็อบเจ็กต์หรือสัญญาได้

เมื่อสร้างอินสแตนซ์ใหม่ของโมเดล เราสามารถ:

  • แทนที่ค่าใดๆ ในอินสแตนซ์ที่สร้างขึ้นใหม่
  • ส่งค่าเพิ่มเติมไปยังตัวเลือกฟังก์ชันการสร้าง

มาดูตัวอย่างกัน

 const factory = require('factory-girl').factory; const User = require('../models/user'); factory.define('user', User, (buildOptions) => { return { name: 'Mike', surname: 'Dow', email: buildOptions.email || '[email protected]' } }); const user1 = factory.build('user'); // {"name": "Mike", "surname": "Dow", "email": "[email protected]"} const user2 = factory.build('user', {name: 'John'}, {email: '[email protected]'}); // {"name": "John", "surname": "Dow", "email": "[email protected]"}

กำลังเชื่อมต่อกับ APIs

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

SuperTest คือไลบรารี JavaScript สำหรับการเรียก API โดยไม่ต้องสร้างเซิร์ฟเวอร์ใหม่ที่ทำงานอยู่ มันขึ้นอยู่กับ SuperAgent ซึ่งเป็นไลบรารีสำหรับสร้างคำขอ TCP ด้วยไลบรารีนี้ ไม่จำเป็นต้องสร้างการเชื่อมต่อ TCP ใหม่ เรียก API เกือบจะในทันที

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

 const express = require('express') const request = require('supertest-as-promised'); const app = express(); request(app).get("/recipes").then(res => assert(....));

SuperTest ถูกสร้างขึ้นสำหรับเฟรมเวิร์ก Express.js แต่หากมีการเปลี่ยนแปลงเล็กน้อยก็สามารถนำไปใช้กับเฟรมเวิร์กอื่นๆ ได้เช่นกัน

ยูทิลิตี้อื่นๆ

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

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

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

เพื่อแก้ไขปัญหานี้ เราสามารถใช้การแทรกการพึ่งพา หรือหากนั่นไม่ใช่ตัวเลือก เราสามารถใช้บริการเยาะเย้ยเช่นการเยาะเย้ย

การเยาะเย้ยช่วยเยาะเย้ยโค้ดที่มีการพึ่งพาภายนอก ในการใช้งานอย่างถูกต้อง ควรเรียกการเยาะเย้ยก่อนโหลดการทดสอบหรือโค้ด

 const mockery = require('mockery'); mockery.enable({ warnOnReplace: false, warnOnUnregistered: false }); const mockingStripe = require('lib/services/internal/stripe'); mockery.registerMock('lib/services/internal/stripe', mockingStripe);

ด้วยข้อมูลอ้างอิงใหม่นี้ (ในตัวอย่างนี้ mockingStripe ) การทดสอบของเราจึงจะเยาะเย้ยได้ง่ายขึ้น

 const stubStripeTransfer = sinon.stub(mockingStripe, 'transferAmount'); stubStripeTransfer.returns(Promise.resolve(null));

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

 const sandbox = require('sinon').sandbox.create(); const stubStripeTransfer = sandbox.sinon.stub(mockingStripe, 'transferAmount'); stubStripeTransfer.returns(Promise.resolve(null)); // after the test, or better when starting a new test sandbox.restore();

มีความจำเป็นสำหรับส่วนประกอบอื่น ๆ สำหรับการทำงานเช่น:

  • การล้างฐานข้อมูล (สามารถทำได้ด้วยแบบสอบถามก่อนสร้างลำดับชั้นหนึ่งลำดับชั้น)
  • การตั้งค่าให้เป็นสถานะการทำงาน (sequelize-fixtures)
  • การเยาะเย้ยคำขอ TCP ไปยังบริการบุคคลที่สาม (nock)
  • ใช้การยืนยันที่สมบูรณ์ยิ่งขึ้น (ชัย)
  • คำตอบที่บันทึกไว้จากบุคคลที่สาม (แก้ไขง่าย)

แบบทดสอบที่ไม่ธรรมดา

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

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

รหัสต่อไปนี้แสดงวิธีทดสอบ API ที่สร้างสูตรและส่งอีเมลเป็นผลข้างเคียง

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

 const co = require('co'); const factory = require('factory'); const superTest = require('../utils/super_test'); const basicEnv = require('../utils/basic_test_enivornment'); const path = '/v1/admin/recipes'; basicEnv.test(`API POST ${path}`, co.wrap(function* (t, assert, sandbox) { const chef = yield factory.create('chef'); const body = { chef_id: chef.id, recipe_name: 'cake', Ingredients: ['carrot', 'chocolate', 'biscuit'] }; const stub = sandbox.stub(mockery.emailProvider, 'sendNewEmail').returnsPromise(null); const serverResponse = yield superTest.get(path, body); assert.spies(stub).called(1); assert.statusCode(serverResponse, 201); }));

การทดสอบข้างต้นสามารถทำซ้ำได้เนื่องจากเริ่มต้นด้วยสภาพแวดล้อมที่สะอาดทุกครั้ง

มีขั้นตอนการตั้งค่าที่เรียบง่าย ซึ่งทุกอย่างที่เกี่ยวข้องกับการตั้งค่าจะรวมอยู่ในฟังก์ชัน basicEnv.test

มันทดสอบการกระทำเดียวเท่านั้น - API เดียว และระบุความคาดหวังของการทดสอบอย่างชัดเจนผ่านข้อความยืนยันง่ายๆ นอกจากนี้ การทดสอบนี้ไม่เกี่ยวข้องกับโค้ดของบุคคลที่สามโดยการขัดจังหวะ/เยาะเย้ย

เริ่มเขียนการทดสอบบูรณาการ

เมื่อผลักดันโค้ดใหม่สู่การใช้งานจริง นักพัฒนา (และผู้เข้าร่วมโครงการอื่นๆ ทั้งหมด) ต้องการให้แน่ใจว่าฟีเจอร์ใหม่จะใช้งานได้และฟีเจอร์เก่าจะไม่พัง

การดำเนินการนี้ทำได้ยากมากหากไม่มีการทดสอบ และหากทำได้ไม่ดีอาจนำไปสู่ความยุ่งยาก ความล้าของโครงการ และความล้มเหลวของโครงการในที่สุด

การทดสอบบูรณาการ รวมกับการทดสอบหน่วยเป็นแนวป้องกันแรก

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