4 คะแนน โดย GN⁺ 2024-04-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

เดโม pgmock — Discord

  • pgmock เป็นเซิร์ฟเวอร์จำลอง PostgreSQL แบบอินเมมโมรีสำหรับการทดสอบแบบ unit และ E2E
  • ไม่มี dependency ภายนอก และทำงานทั้งหมดภายใน WebAssembly ได้ทั้งบน Node.js และในเบราว์เซอร์

การติดตั้ง

  • ติดตั้งได้ด้วยคำสั่ง npm install pgmock
  • หากต้องการรัน pgmock บนเบราว์เซอร์ โปรดดูคำแนะนำโดยละเอียดในส่วนการรองรับเบราว์เซอร์

เริ่มต้นใช้งาน

  • สามารถรันเซิร์ฟเวอร์แบบอินเมมโมรีได้ดังนี้:
    import { PostgresMock } from "pgmock";
    const mock = await PostgresMock.create();
    const connectionString = await mock.listen(5432);
    
  • หากใช้ node-postgres (pg บน npm) จะมีอ็อบเจ็กต์คอนฟิกที่ไม่ต้องใช้พอร์ตและทำงานได้ในเบราว์เซอร์ให้:
    import * as pg from "pg";
    const mock = await PostgresMock.create();
    const client = new pg.Client(mock.getNodePostgresConfig());
    await client.connect();
    console.log(await client.query('SELECT $1::text as message', ['Hello world!']));
    
  • หลังใช้งาน ควรทำลายเซิร์ฟเวอร์จำลองเพื่อคืนทรัพยากร:
    mock.destroy();
    

เอกสารประกอบ

  • ดูรายการเมธอดทั้งหมดที่ใช้ได้และเอกสารของมันได้ในไฟล์ซอร์สของ PostgresMock

การรองรับเบราว์เซอร์

  • pgmock รองรับสภาพแวดล้อมเบราว์เซอร์อย่างสมบูรณ์
  • แม้เว็บแอปจะไม่สามารถ listen บน TCP port ได้ แต่สามารถใช้ PostgresMock.createSocket และคอนฟิกของ node-postgres ได้
  • หาก bundler วิเคราะห์ static import อาจมีคำเตือนในคอนฟิกเริ่มต้นเนื่องจากขาดโมดูล Node.js บางตัวที่เป็นแบบ optional
  • หากต้องการรันแค่ฐานข้อมูลในเบราว์เซอร์ อาจพิจารณา pglite ได้ แต่มีข้อจำกัดด้านความสามารถ
  • pgmock ถูกออกแบบมาโดยมีเป้าหมายให้เทียบเท่ากับสภาพแวดล้อม PostgreSQL สำหรับ production ที่ต้องการในเชิงฟังก์ชันภายในสภาพแวดล้อมการทดสอบ

หลักการทำงาน

  • มีสองแนวทางในการรัน Postgres บน WebAssembly: ฟอร์กให้รองรับ WASM โดยกำเนิด หรือจำลองเซิร์ฟเวอร์ Postgres บนอีมูเลเตอร์ x86
  • แบบแรกมีประสิทธิภาพดีกว่าและใช้หน่วยความจำน้อยกว่า แต่ไม่รองรับโหมดผู้ใช้เดี่ยว (ไม่มีการเชื่อมต่อ) และฟีเจอร์ส่วนขยาย
  • เพื่อหลีกเลี่ยงความต่างระหว่างการทดสอบกับ production และเพราะประสิทธิภาพไม่ใช่ประเด็นหลักในการทดสอบ pgmock จึงใช้แนวทางหลังอยู่ในปัจจุบัน
  • ในระยะกลาง เมื่อ Postgres WASM fork แบบเนทีฟมีความพร้อมมากขึ้น มีแผนจะรองรับทั้งสองทางเลือก และในที่สุดจะสลับไปใช้ native WASM เป็นค่าเริ่มต้น
  • คาดว่าจะไม่มีการเปลี่ยนแปลงใหญ่จำนวนมาก ยกเว้น API ภายใน PostgresMock.subtle
  • pgmock จำลอง network stack ภายใน JavaScript ที่ทำงานเหมือนเครือข่ายจริง ทำให้สามารถจำลองการเชื่อมต่อ TCP ได้แม้บนแพลตฟอร์มที่ไม่อนุญาตการเข้าถึง raw socket จึงให้ความเข้ากันได้ของฟีเจอร์อย่างครบถ้วนภายใน JavaScript runtime ทั้งหมดโดยไม่ต้องพึ่งพา network proxy

อยากมีส่วนร่วมไหม?

  • สามารถมาคุยกับเราได้ในเซิร์ฟเวอร์ Discord

สามารถรันอิมเมจ Docker หรือฐานข้อมูลอื่นได้ไหม?

  • ในทางทฤษฎีทำได้ หากสนใจโปรดติดต่อในเซิร์ฟเวอร์ Discord

คำขอบคุณ

  • ขอบคุณ v86 ซึ่งเป็นอีมูเลเตอร์ x86 ที่ทำให้สิ่งนี้เป็นไปได้
  • ขอบคุณ Supabase และ Snaplet ที่สร้างแนวทางของตนเองในการรัน Postgres ภายใน WebAssembly
  • ขอบคุณ Stackframe ที่จ่ายเงินเดือนระหว่างการสร้าง pgmock

ความเห็นของ GN⁺

  • pgmock เป็นเครื่องมือที่มีประโยชน์สำหรับนักพัฒนาที่ต้องการทดสอบการโต้ตอบกับฐานข้อมูล PostgreSQL โดยสามารถตรวจสอบการทำงานส่วนที่เกี่ยวกับฐานข้อมูลของโค้ดได้โดยไม่ต้องยุ่งยากกับการตั้งค่าและดูแลเซิร์ฟเวอร์ฐานข้อมูลจริง
  • เครื่องมือแบบนี้มีประโยชน์มากในสภาพแวดล้อมการพัฒนาแบบ TDD หรือ CI นักพัฒนาสามารถรันทดสอบได้อย่างรวดเร็วและเห็นผลกระทบจากการเปลี่ยนแปลงโค้ดได้ทันที
  • pgmock ใช้ WebAssembly จึงทำงานได้ทั้งในเบราว์เซอร์และบน Node.js ทำให้รองรับสภาพแวดล้อมการพัฒนาที่หลากหลาย ซึ่งเป็นประโยชน์ต่อทั้งนักพัฒนาฝั่งฟรอนต์เอนด์และแบ็กเอนด์
  • อย่างไรก็ตาม ยังมีคำถามว่า pgmock จะจำลองฟีเจอร์ทั้งหมดของเซิร์ฟเวอร์ PostgreSQL จริงได้สมบูรณ์แค่ไหน โดยเฉพาะในด้านประสิทธิภาพและฟีเจอร์ส่วนขยาย ความต่างจากสภาพแวดล้อมฐานข้อมูลจริงอาจส่งผลต่อผลการทดสอบได้
  • โครงการอื่นที่มีความสามารถคล้ายกัน ได้แก่ Testcontainers และ H2 Database ซึ่งแต่ละตัวมีการทดสอบแบบรวมผ่านคอนเทนเนอร์ Docker และฐานข้อมูลแบบอินเมมโมรีสำหรับแอปพลิเคชัน Java ตามลำดับ

1 ความคิดเห็น

 
GN⁺ 2024-04-08
ความคิดเห็นจาก Hacker News
  • แนะนำ pgmock

    • นักพัฒนาคนหนึ่งได้พัฒนา Postgres เวอร์ชัน in-memory มาหลายเดือน
    • เวอร์ชันนี้มีความเทียบเท่ากับฐานข้อมูลเดิมในเชิงฟังก์ชัน
    • ไม่ต้องใช้ external process หรือ proxy และทำงานได้บนแพลตฟอร์มที่รัน WASM ได้ (เช่น Node.js, เบราว์เซอร์)
    • สามารถสร้างฐานข้อมูลใหม่และ mock data ได้ง่ายราวกับสร้าง JavaScript object
    • ต่างจาก pglite ตรงที่ pgmock รัน x86 emulator ที่บรรจุ Postgres ต้นฉบับไว้ภายใน ส่วน pglite คอมไพล์ Postgres fork ไปเป็น WASM โดยตรง จึงเร็วและเบากว่า แต่รองรับแค่ single-user mode และ extension บางส่วน จึงไม่สามารถเชื่อมต่อด้วย Postgres client ทั่วไปได้
    • ในทางทฤษฎี Docker image ใด ๆ ก็สามารถปรับให้รันบนแพลตฟอร์ม WebAssembly ได้
  • คำถามเกี่ยวกับการรัน Postgres บน RAM disk

    • มีการขอให้อธิบายข้อดีเมื่อเทียบกับการรัน Postgres บน RAM disk โดยเฉพาะความสามารถในการรันในสภาพแวดล้อมเบราว์เซอร์/Node และให้การทดสอบสร้าง/อัปเดต/ทำลายได้
  • การแชร์ประสบการณ์ใช้เซิร์ฟเวอร์ in-memory แทนเซิร์ฟเวอร์จริง

    • ในอดีตเคยใช้เซิร์ฟเวอร์ in-memory ปลอมแบบต่าง ๆ (รวมถึงแบบคัสตอม) สำหรับการทดสอบ แต่ปัจจุบันใช้ Testcontainers เพื่อรันบริการจริง
  • คำถามเกี่ยวกับทรัพย์สินทางปัญญาของโปรเจ็กต์

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

    • แนะนำให้ดัมพ์ข้อมูล production ลบข้อมูลอ่อนไหว และลดตารางที่ไม่จำเป็นอย่างเช่นตารางล็อก เพื่อสร้างสำเนาสำหรับพัฒนา แล้วคัดลอกไปใช้กับ development, QA, E2E ฯลฯ เพื่อให้มี extension, trigger, function, view, index และข้อมูลที่จำเป็นต่อการทดสอบ E2E
  • คำถามเกี่ยวกับที่มาของการพัฒนา pgmock และการผสานเข้ากับ CI

    • มีคำถามถึงแรงจูงใจในการพัฒนาโปรเจ็กต์นี้ และการรัน Postgres ใน Docker container ช้าเกินไปหรือไม่
    • มีการขอคำอธิบายเกี่ยวกับการตั้งค่า CI และ flow การทดสอบ E2E ก่อนและหลังผสาน pgmock
    • มีคำถามว่าการย้ายมาใช้โซลูชันนี้ยากหรือไม่
  • คำถามเปรียบเทียบกับฐานข้อมูล H2

    • มีคำถามเปรียบเทียบระหว่างฐานข้อมูล H2 ในโหมดเข้ากันได้กับ Postgres และ pgmock
  • การแชร์ประสบการณ์ใช้ pgmem

    • มีการแชร์ประสบการณ์ที่เคยทำงานกับ pgmem ในช่วงหลายปีที่ผ่านมาเพื่อวัตถุประสงค์คล้ายกัน
  • คำถามเกี่ยวกับการรองรับ ORM

    • มีคำถามว่าสามารถใช้ ORM อย่าง Sequelize, Prisma, Drizzle ในการทดสอบได้หรือไม่
  • คำถามเกี่ยวกับการใช้งานร่วมกับ Prisma client

    • มีคำถามว่ามีวิธีใช้งานร่วมกับ Prisma client ได้อย่างไร