Membangun kepercayaan lewat testing: unit & integration test kontrak dengan Foundry dan Hardhat, testing frontend DApp dengan Playwright, penggunaan Anvil dengan fork mainnet, util testing wagmi, dan simulasi wallet di E2E

Setelah di episode 16-18 kalian memperluas dan mengamankan DApp, pada episode ini kita memasang jangkar kualitas: testing. Kontrak tidak bisa "di-patch" setelah di-deploy, dan frontend DApp penuh alur async yang mudah rusak — jadi pengujian bukan pilihan.
Mengapa episode ini penting? Karena perbedaan developer amatir dan profesional terlihat di sini: developer pro tidak men-deploy kontrak yang belum dites, dan tidak merilis frontend yang alur transaksinya belum teruji end-to-end. Episode ini memberi workflow lengkapnya.
Foundry (forge test) adalah standar modern testing Solidity — cepat dan menulis test dalam Solidity itu sendiri.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.36;
import {Test} from "forge-std/Test.sol";
import {MyToken} from "../src/MyToken.sol";
contract MyTokenTest is Test {
MyToken public token;
function setUp() public {
token = new MyToken();
}
function testTotalSupply() public view {
assertEq(token.totalSupply(), 0);
}
function testMintIncreasesSupply() public {
token.mint(address(this), 100);
assertEq(token.totalSupply(), 100);
}
}Jalankan dengan:
forge testFoundry menyediakan cheatcode seperti vm.prank, vm.deal, dan vm.warp untuk mensimulasikan address, saldo, dan waktu — penting untuk menguji kontrol akses dan batas waktu.
Untuk tim Node.js, Hardhat memakai Mocha/Chai. Prinsipnya sama — hanya bahasa test-nya TypeScript:
import { expect } from "chai"
import { ethers } from "hardhat"
describe("MyToken", function () {
it("mint menambah total supply", async function () {
const Token = await ethers.getContractFactory("MyToken")
const token = await Token.deploy()
await token.mint(owner.address, 100)
expect(await token.totalSupply()).to.equal(100)
})
})Untuk frontend, kita butuh environment yang mirip produksi tapi aman. Anvil (dari Foundry) menyediakannya:
anvilFork mainnet = memakai state Ethereum nyata di node lokal. Berguna untuk menguji interaksi dengan protokol yang sudah ada (misalnya swap di Uniswap) tanpa aset sungguhan:
anvil --fork-url $RPC_URL_MAINNETDengan fork, kontrak mainnet (USDC, Uniswap, dsb.) sudah tersedia di node lokal — kalian bisa menguji alur kompleks secara realistis.
Frontend DApp diuji dua level: unit/component dan E2E.
Playwright tidak punya MetaMask — solusinya adalah menyuntikkan wallet palsu ke halaman lewat window.ethereum (injected provider). Library seperti viem createTestClient + inject ke window.ethereum memungkinkan ini:
import { test, expect } from "@playwright/test"
test("transfer token menampilkan konfirmasi", async ({ page }) => {
await page.goto("/")
await page.getByRole("button", { name: "Connect" }).click()
await expect(page.getByText(/0x/)).toBeVisible()
await page.getByPlaceholder("0x...").fill("0xReceiver...")
await page.getByPlaceholder("0.01").fill("1")
await page.getByRole("button", { name: "Transfer" }).click()
await expect(page.getByText("Transfer berhasil!")).toBeVisible()
})Untuk alur yang butuh konfirmasi MetaMask sungguhan, ada ekstensi Playwright MetaMask (synpress) — tetapi untuk sebagian besar kasus, injected mock wallet sudah cukup dan jauh lebih stabil.
wagmi menyediakan util untuk menguji hook dan komponen tanpa wallet nyata:
import { createConfig, WagmiProvider } from "wagmi"
import { http } from "viem"
import { sepolia } from "wagmi/chains"
const testConfig = createConfig({
chains: [sepolia],
transports: { [sepolia.id]: http("http://127.0.0.1:8545") },
})Gabungkan dengan QueryClientProvider (episode 9) dan Testing Library untuk komponen test yang deterministik.
Tip
Workflow QA lengkap yang direkomendasikan: forge test untuk kontrak → anvil (fork mainnet) sebagai environment → Playwright + injected wallet untuk E2E → CI menjalankan semuanya. Ini persis yang dilakukan tim produksi — dan akan menyelamatkan kalian dari bug "tidak muncul sampai di produksi".
Rangkuman yang sudah kalian pelajari di episode 19:
anvil --fork-url untuk fork mainnet.window.ethereum.createConfig ke anvil + QueryClientProvider.Inti yang harus dibawa pulang:
Di episode 20 selanjutnya, kita melihat 2026 trends: RWA, AI agents & tokenization — tokenisasi aset dunia nyata (RWA) yang sudah melampaui $12 miliar di Ethereum, AI agents on-chain dengan agent wallets, decentralized inference, dan settlement stablecoin senilai triliunan dolar. Sampai jumpa di episode 20!