Web3 & DApp Development Fundamentals · บทเรียน

การทดสอบการย้อนกลับและเหตุการณ์

ยืนยันพฤติกรรม

บทเรียน 2 จาก 413 ขั้นตอน

การทดสอบการย้อนกลับและเหตุการณ์ เป็นบทเรียน Web3 & DApp Development Fundamentals ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Web3 & DApp Development Fundamentals และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Web3 & DApp Development Fundamentals มีบทเรียนทั้งหมด 4 บทเรียน

การย้อนกลับและเหตุการณ์

นอกเหนือจากค่าที่ส่งคืน สัญญายังสื่อสารผ่านการย้อนกลับ (ธุรกรรมที่ล้มเหลวและยกเลิกสถานะ) และเหตุการณ์ (บันทึกที่ส่งออกเมื่อสำเร็จ)

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

ตัวตรวจสอบ Chai ของ Hardhat

Toolbox เพิ่มตัวตรวจสอบ Chai พิเศษสำหรับ Ethereum ซึ่งพร้อมใช้หลังจากนำเข้า (Toolbox จัดการให้โดยอัตโนมัติ):

  • .to.be.revertedWith(...)
  • .to.be.revertedWithCustomError(...)
  • .to.emit(...)
  • .to.changeEtherBalance(...)

ตรวจสอบการย้อนกลับ

หากต้องการตรวจสอบว่าธุรกรรมล้มเหลว ให้ครอบการเรียกใช้ไว้ (โดยยังไม่ใช้ await กับการเรียกนั้นก่อน) แล้วใช้ revertedWith:

await expect( token.connect(alice).withdraw() ).to.be.revertedWith("Not the owner");

สตริงต้องตรงกับข้อความ require ของสัญญาทุกประการ

await expect(
  token.connect(alice).withdraw()
).to.be.revertedWith("Not the owner");

การย้อนกลับด้วยข้อผิดพลาดกำหนดเอง

Solidity สมัยใหม่ใช้ข้อผิดพลาดกำหนดเองที่ประหยัดแก๊ส ตรวจสอบยืนยันด้วย revertedWithCustomError:

await expect( vault.connect(alice).withdraw() ).to.be.revertedWithCustomError(vault, "Unauthorized");

คุณต้องส่งอินสแตนซ์ของสัญญา เพื่อให้ตัวตรวจสอบสามารถถอดรหัสข้อผิดพลาดจาก ABI ได้

await expect(
  vault.connect(alice).withdraw()
).to.be.revertedWithCustomError(vault, "Unauthorized");

ตรวจสอบอาร์กิวเมนต์ของข้อผิดพลาด

ข้อผิดพลาดกำหนดเองสามารถพกพาข้อมูลได้ ให้ต่อ withArgs เพื่อยืนยันค่าดังกล่าว:

await expect( vault.withdraw(amount) ).to.be.revertedWithCustomError(vault, "InsufficientBalance") .withArgs(amount, balance);

วิธีนี้ยืนยันได้ว่าสัญญาย้อนกลับด้วยเหตุผลที่คุณคาดหวังไว้อย่างตรงจุด

await expect(
  vault.withdraw(amount)
).to.be.revertedWithCustomError(vault, "InsufficientBalance")
  .withArgs(amount, balance);

ตรวจสอบเหตุการณ์

ใช้ .to.emit เพื่อตรวจสอบยืนยันว่าธุรกรรมส่งออกเหตุการณ์:

await expect(token.transfer(bob.address, 100)) .to.emit(token, "Transfer");

คุณต้องส่งสัญญาและชื่อเหตุการณ์ วิธีนี้ยืนยันว่ามีการสร้างบันทึกแล้ว

await expect(token.transfer(bob.address, 100))
  .to.emit(token, "Transfer");

ตรวจสอบอาร์กิวเมนต์ของเหตุการณ์

ใช้ emit ร่วมกับ withArgs เพื่อตรวจสอบข้อมูลของเหตุการณ์:

await expect(token.transfer(bob.address, 100)) .to.emit(token, "Transfer") .withArgs(owner.address, bob.address, 100);

วิธีนี้ช่วยยืนยันว่าฟิลด์ผู้ส่ง ผู้รับ และจำนวนเงินถูกต้องตรงกันทุกประการ

await expect(token.transfer(bob.address, 100))
  .to.emit(token, "Transfer")
  .withArgs(owner.address, bob.address, 100);

ตรวจสอบการเปลี่ยนแปลงยอดคงเหลือ

สำหรับการโอน ETH, changeEtherBalance จะตรวจสอบการเปลี่ยนแปลงสุทธิของบัญชี:

await expect( () => vault.connect(alice).withdraw() ).to.changeEtherBalance(alice, ethers.parseEther("1"));

นอกจากนี้ยังมี changeTokenBalance สำหรับการโอน ERC-20 ด้วย

await expect(
  () => vault.connect(alice).withdraw()
).to.changeEtherBalance(alice, ethers.parseEther("1"));

ย้อนกลับโดยไม่มีเหตุผล

ความล้มเหลวบางกรณีไม่มีข้อความ — เช่น การตื่นตระหนกจากจำนวนเลขคณิตลดต่ำกว่าขอบเขต หรือ revert() แบบธรรมดา ให้ตรวจสอบกรณีเหล่านี้แบบทั่วไป:

await expect(token.transfer(bob.address, 999999)) .to.be.reverted;

สำหรับรหัสการตื่นตระหนกโดยเฉพาะ ให้ใช้ revertedWithPanic

await expect(token.transfer(bob.address, 999999))
  .to.be.reverted;

เหตุใดเรื่องนี้จึงสำคัญ

การทดสอบการย้อนกลับและเหตุการณ์ครอบคลุมเส้นทางการทำงานของสัญญาที่ เป็นด้านลบและสังเกตได้:

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

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

ตรวจสอบว่าสถานะไม่มีการเปลี่ยนแปลง

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

await expect( vault.connect(alice).withdraw() ).to.be.revertedWithCustomError(vault, "Unauthorized"); expect(await vault.balance()).to.equal(initial);

การตรวจสอบซ้ำนี้ยืนยันว่าการป้องกันสามารถปกป้องสถานะได้จริง

await expect(
  vault.connect(alice).withdraw()
).to.be.revertedWithCustomError(vault, "Unauthorized");

expect(await vault.balance()).to.equal(initial);

ตรวจสอบความเข้าใจอย่างรวดเร็ว

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

สรุปทบทวน

คุณได้เรียนรู้วิธีตรวจสอบพฤติกรรมที่นอกเหนือจากค่าที่ส่งกลับ

  • revertedWith ตรวจสอบข้อความจากข้อกำหนด ส่วน revertedWithCustomError ตรวจสอบข้อผิดพลาดแบบกำหนดเอง
  • withArgs ตรวจสอบอาร์กิวเมนต์ของข้อผิดพลาดหรือเหตุการณ์ได้อย่างแม่นยำ
  • .to.emit ยืนยันว่าเหตุการณ์ถูกส่งออกมา
  • changeEtherBalance / changeTokenBalance ตรวจสอบการเปลี่ยนแปลงยอดคงเหลือสุทธิ
  • ใช้ .to.be.reverted สำหรับความล้มเหลวที่ไม่มีสตริงเหตุผล
เริ่มต้นได้ฟรี

เรียนรู้ Web3 & DApp Development Fundamentals ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
29
บทเรียน
105

คำถามที่พบบ่อย

บทเรียน “การทดสอบการย้อนกลับและเหตุการณ์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การทดสอบการย้อนกลับและเหตุการณ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Web3 & DApp Development Fundamentals ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Web3 & DApp Development Fundamentals มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การทดสอบการย้อนกลับและเหตุการณ์”

ยืนยันพฤติกรรม คุณปฏิบัติ Web3 & DApp Development Fundamentals ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Web3 & DApp Development Fundamentals หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Web3 & DApp Development Fundamentals บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การทดสอบการย้อนกลับและเหตุการณ์” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน Web3 & DApp Development Fundamentals นี้ได้ไหม

ได้ บทเรียน Web3 & DApp Development Fundamentals ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเขียนการทดสอบ
  2. การทดสอบการย้อนกลับและเหตุการณ์
  3. ความครอบคลุมและรายงานแก๊ส
  4. ฟิกซ์เจอร์
← กลับไปที่ Web3 & DApp Development Fundamentals