Testowanie revertów i zdarzeń
Asercja zachowania
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.
revertedWithsprawdza komunikaty wymagań, arevertedWithCustomError— błędy niestandardowe.withArgsprecyzyjnie weryfikuje argumenty błędów lub zdarzeń..to.emitpotwierdza, że zdarzenia zostały wyemitowane.changeEtherBalance/changeTokenBalancesprawdzają zmiany netto salda.- Używaj
.to.be.revertedw przypadku niepowodzeń bez ciągu uzasadnienia.
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
- Pisanie testów
- Testowanie revertów i zdarzeń
- Pokrycie i raporty gas
- Fixtures