Belajar Web3 - Testing & QA DApp
Series/Belajar Web3/Episode 19
Episode 19 of 23

Belajar Web3 - Testing & QA DApp

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

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

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.

Testing Kontrak: Foundry

Foundry (forge test) adalah standar modern testing Solidity — cepat dan menulis test dalam Solidity itu sendiri.

test/MyToken.t.sol
// 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:

Jalankan test Foundry
forge test

Foundry menyediakan cheatcode seperti vm.prank, vm.deal, dan vm.warp untuk mensimulasikan address, saldo, dan waktu — penting untuk menguji kontrol akses dan batas waktu.

Testing Kontrak: Hardhat

Untuk tim Node.js, Hardhat memakai Mocha/Chai. Prinsipnya sama — hanya bahasa test-nya TypeScript:

Test Hardhat (konsep)
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)
  })
})

Anvil: Node Lokal untuk QA

Untuk frontend, kita butuh environment yang mirip produksi tapi aman. Anvil (dari Foundry) menyediakannya:

Anvil biasa (state kosong)
anvil

Fork Mainnet

Fork 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 mainnet
anvil --fork-url $RPC_URL_MAINNET

Dengan fork, kontrak mainnet (USDC, Uniswap, dsb.) sudah tersedia di node lokal — kalian bisa menguji alur kompleks secara realistis.

Testing Frontend: Playwright + wagmi

Frontend DApp diuji dua level: unit/component dan E2E.

Simulasi Wallet di 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:

tests/dapp.spec.ts
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.

Util Testing wagmi

wagmi menyediakan util untuk menguji hook dan komponen tanpa wallet nyata:

Bungkus komponen dengan config test
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".

Ringkasan Konsep

Rangkuman yang sudah kalian pelajari di episode 19:

  • Kontrak: forge test (Solidity) atau Hardhat (Mocha/Chai).
  • Anvil untuk node lokal; anvil --fork-url untuk fork mainnet.
  • Frontend E2E dengan Playwright + injected wallet via window.ethereum.
  • wagmi test utils: createConfig ke anvil + QueryClientProvider.

Penutup

Inti yang harus dibawa pulang:

  • Kontrak yang tidak dites adalah bom waktu; kontrak yang diaudit tanpa test juga tidak aman.
  • Fork mainnet memberi lingkungan realistis tanpa risiko.
  • Otomasikan QA di CI — testing manual tidak akan konsisten.

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!

Belajar Web3 - Testing & QA DApp | Belajar Web3