Web3 & DApp Development Fundamentals · Lekcja

Testowanie revertów i zdarzeń

Asercja zachowania

Lekcja 2 z 413 kroki

Testowanie revertów i zdarzeń to bezpłatna lekcja Web3 & DApp Development Fundamentals na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Web3 & DApp Development Fundamentals, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Web3 & DApp Development Fundamentals zawiera 4 lekcji w sumie.

Reverty i zdarzenia

Oprócz wartości zwracanych kontrakty komunikują się za pomocą revertów (transakcji, które kończą się niepowodzeniem i cofają stan) oraz zdarzeń (logów emitowanych po pomyślnym wykonaniu).

Dobre testy sprawdzają oba aspekty: czy prawidłowe działania emitują właściwe zdarzenia oraz czy nieprawidłowe działania kończą się revertem z właściwym powodem.

Matchery Hardhat Chai

Toolbox dodaje specjalne matchery Chai dla Ethereum, dostępne po ich zaimportowaniu (Toolbox robi to automatycznie):

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

Sprawdzanie reverta

Aby sprawdzić, czy transakcja kończy się niepowodzeniem, opakuj wywołanie (bez wcześniejszego użycia await) i użyj revertedWith:

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

Łańcuch znaków musi dokładnie odpowiadać komunikatowi require z kontraktu.

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

Reverty z własnymi błędami

Nowoczesny Solidity używa oszczędnych pod względem gazu własnych błędów. Sprawdzaj je za pomocą revertedWithCustomError:

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

Przekazujesz instancję kontraktu, aby matcher mógł zdekodować błąd z ABI.

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

Sprawdzanie argumentów błędu

Własne błędy mogą zawierać dane. Połącz withArgs, aby sprawdzić wartości:

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

Potwierdza to, że kontrakt wykonał revert dokładnie z oczekiwanego powodu.

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

Sprawdzanie zdarzenia

Użyj .to.emit, aby sprawdzić, czy transakcja wyemitowała zdarzenie:

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

Przekazujesz kontrakt i nazwę zdarzenia. Potwierdza to, że log został utworzony.

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

Sprawdzanie argumentów zdarzenia

Połącz emit z withArgs, aby zweryfikować dane zdarzenia:

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

Gwarantuje to, że pola from, to i amount mają dokładnie poprawne wartości.

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

Sprawdzanie zmian salda

W przypadku transferów ETH funkcja changeEtherBalance sprawdza zmianę netto salda konta:

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

W przypadku transferów ERC-20 dostępna jest również funkcja changeTokenBalance.

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

Cofnięcie bez uzasadnienia

Niektóre niepowodzenia nie zawierają komunikatu — na przykład paniki spowodowane niedomiarem arytmetycznym lub zwykłe revert(). W takich przypadkach należy użyć ogólnego sprawdzenia:

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

W przypadku kodów paniki należy użyć funkcji revertedWithPanic.

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

Dlaczego to ma znaczenie

Testowanie cofnięć i zdarzeń obejmuje negatywne oraz obserwowalne ścieżki działania kontraktu:

  • Cofnięcia potwierdzają, że zabezpieczenia (kontrola dostępu, sprawdzanie salda) rzeczywiście blokują nieprawidłowe dane wejściowe.
  • Zdarzenia potwierdzają, że systemy off-chain otrzymają właściwe powiadomienia.

Pominięcie tych testów pozostawia niebezpieczne luki w pokryciu.

Sprawdzanie, czy stan się nie zmienił

Po cofnięciu warto potwierdzić, że stan pozostał niezmieniony, ponieważ cofnięcia wycofują wszystkie zmiany:

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

To dodatkowo potwierdza, że zabezpieczenie rzeczywiście ochroniło stan.

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

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

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat asercji cofnięć i zdarzeń.

Podsumowanie

Nauczyli się Państwo sprawdzać działanie wykraczające poza wartości zwracane.

  • revertedWith sprawdza komunikaty wymagań, a revertedWithCustomError — błędy niestandardowe.
  • withArgs precyzyjnie weryfikuje argumenty błędów lub zdarzeń.
  • .to.emit potwierdza, że zdarzenia zostały wyemitowane.
  • changeEtherBalance / changeTokenBalance sprawdzają zmiany netto salda.
  • Używaj .to.be.reverted w przypadku niepowodzeń bez ciągu uzasadnienia.
Bezpłatny start

Ucz się Web3 & DApp Development Fundamentals dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
29
Lekcje
105

Często zadawane pytania

Czy lekcja „Testowanie revertów i zdarzeń” jest bezpłatna?

Tak — pełny tekst „Testowanie revertów i zdarzeń” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Web3 & DApp Development Fundamentals, przejdź na CoddyKit PRO. Kurs Web3 & DApp Development Fundamentals zawiera 4 lekcji w sumie.

Co nauczysz się w „Testowanie revertów i zdarzeń”?

Asercja zachowania Ćwiczysz Web3 & DApp Development Fundamentals z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Web3 & DApp Development Fundamentals?

Nie wymagamy żadnego doświadczenia. Web3 & DApp Development Fundamentals w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Testowanie revertów i zdarzeń”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Web3 & DApp Development Fundamentals?

Tak. Każda lekcja Web3 & DApp Development Fundamentals zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pisanie testów
  2. Testowanie revertów i zdarzeń
  3. Pokrycie i raporty gas
  4. Fixtures
← Powrót do Web3 & DApp Development Fundamentals