Skip to content

Commit

Permalink
feat: add test for hardhat testing tutorial (#35)
Browse files Browse the repository at this point in the history
* feat: add test for hardhat testing tutorial

* fix: cleanup

* fix: move dependencies to dev

* fix: address feedback & remove old plugin

* fix: wait longer for node
  • Loading branch information
sarahschwartz authored Jul 25, 2024
1 parent 3227a18 commit 3737777
Show file tree
Hide file tree
Showing 16 changed files with 531 additions and 52 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/playwright.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Playwright Tests

on:
pull_request:

jobs:
test-tutorials:
timeout-minutes: 20
runs-on: ubuntu-latest
strategy:
matrix:
tutorial:
- "tests/how-to-test-contracts.spec.ts"

steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- name: Install Dependencies
run: bun install --frozen-lockfile
- uses: actions/setup-node@v4
- name: Install Playwright Browsers
run: bun playwright install chromium --with-deps
- name: Run test for ${{ matrix.tutorial }}
run: bun test:github ${{ matrix.tutorial }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ logs
.DS_Store
.fleet
.idea
tests-output
test-results
playwright-report

# Local env files
.env
Expand Down
Binary file modified bun.lockb
Binary file not shown.
151 changes: 100 additions & 51 deletions content/tutorials/how-to-test-contracts/10.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,69 @@ description: Learn how to test your smart contracts locally using era-test-node

This tutorial provides a step-by-step guide on testing smart contracts using the `hardhat-chai-matchers` plugin
in conjunction with the **ZKsync Era Test Node** on your local machine.
To facilitate this process of running tests on the **ZKsync Era Test Node**, you'll also utilize the `hardhat-zksync-node` plugin.
To facilitate this process of running tests on the **ZKsync Era Test Node**, you'll also utilize the `hardhat-zksync` plugin.

## Prerequisites

- Node.js installed (version 14.x or later)
- Either yarn or npm installed
- Initialized Hardhat TypeScript project

## Era-test-node plugin

In this tutorial, the contract functionality is tested using the [ZKsync Era Test Node](https://docs.zksync.io/build/test-and-debug/in-memory-node).
To start local node we use the `hardhat-zksync-node` plugin to integrate this functionality within the Hardhat project.
To start local node we use the `hardhat-zksync` plugin to integrate this functionality within the Hardhat project.

::callout{icon="i-heroicons-exclamation-triangle"}
During the alpha phase, ZKsync Era Test Nodes are currently undergoing development, wherein certain functionalities might not be fully supported or operational.
::

### Installation

To install the `hardhat-zksync-node` plugin and additional necessary packages, execute the following command:
First, initialize a new Hardhat TypeScript project:

<span id="initialize-hardhat-project" data-name="runCommand"></span>

```bash
npx hardhat init
```

Select the `Create a TypeScript project` option and install the sample project's dependencies: `hardhat` and `@nomicfoundation/hardhat-toolbox`.

To install the `hardhat-zksync` plugin, execute the following command:

<span id="install-hh-zksync" data-name="runCommand" data-command-folder="tests-output/hardhat-project"></span>

::code-group

```bash [npm]
npm i -D @matterlabs/hardhat-zksync-node
npm i -D @matterlabs/hardhat-zksync
```

```bash [yarn]
yarn add -D @matterlabs/hardhat-zksync-node
yarn add -D @matterlabs/hardhat-zksync
```

::

Once installed, add the plugin at the top of your `hardhat.config.ts` file.

<span id="import-zksync-config" data-name="modifyFile" data-filepath="tests-output/hardhat-project/hardhat.config.ts"
data-at-line="3"></span>

```ts [hardhat.config.ts]
import "@matterlabs/hardhat-zksync-node";
import "@matterlabs/hardhat-zksync";
```

### Starting the ZKsync Era Test Node

You can now safely run the **ZKsync Era Test Node** with the following command:

<span id="run-hh-node" data-name="runCommand" data-command-folder="tests-output/hardhat-project" data-pre-command="bun pm2 start '<COMMAND>' --name hh-zknode"></span>

::code-group

```bash [npm]
npm hardhat node-zksync
```bash [npx]
npx hardhat node-zksync
```

```bash [yarn]
Expand All @@ -61,6 +77,10 @@ yarn hardhat node-zksync

::

<span id="wait-for-hh-node" data-name="wait" data-timeout="6000"></span>

<span id="test-hh-node" data-name="checkIfBalanceIsZero" data-network-url="http://127.0.0.1:8011" data-address="0xe2b8Cb53a43a56d4d2AB6131C81Bd76B86D3AFe5"></span>

::callout{icon="i-heroicons-exclamation-circle"}
We'll want to verify the correctness of our installations and test if we can run a **ZKsync Era Test Node**,
without further use of this command in the tutorial.
Expand All @@ -78,14 +98,22 @@ You should see output similar to this:
09:04:44 INFO ========================================
```

Since we've confirmed that the **ZKsync Era Test Node** is functioning properly with the help of the `hardhat-zksync-node` plugin,
Since we've confirmed that the **ZKsync Era Test Node** is functioning properly with the help of the `hardhat-zksync` plugin,
we can shut it down and continue with the tutorial.

### Integration with Hardhat

To enable the usage of ZKsync Era Test Node in Hardhat, add the `zksync:true` option to the hardhat network in the `hardhat.config.ts` file:
To enable the usage of ZKsync Era Test Node in Hardhat,
add the `zksync:true` option to the hardhat network in the `hardhat.config.ts` file
and the `latest` version of `zksolc`:

```json
<span id="zksync-hh-network" data-name="modifyFile" data-filepath="tests-output/hardhat-project/hardhat.config.ts"
data-at-line="7"></span>

```ts
zksolc: {
version: "latest",
},
networks: {
hardhat: {
zksync: true,
Expand All @@ -100,34 +128,69 @@ it's necessary to use the `hardhat-chai-matchers` plugin.

In the root directory of your project, execute this command:

<span id="install-chai-ethers" data-name="runCommand" data-command-folder="tests-output/hardhat-project" data-pre-command="<COMMAND>"></span>

::code-group

```bash [npm]
npm i -D @nomicfoundation/hardhat-chai-matchers [email protected] @nomiclabs/hardhat-ethers
npm i -D @nomicfoundation/hardhat-chai-matchers [email protected]
```

```bash [yarn]
yarn add -D @nomicfoundation/hardhat-chai-matchers [email protected] @nomiclabs/hardhat-ethers
yarn add -D @nomicfoundation/hardhat-chai-matchers [email protected]
```

::

After installing it, add the plugin at the top of your `hardhat.config.ts` file:

<span id="import-chai-matchers" data-name="modifyFile" data-filepath="tests-output/hardhat-project/hardhat.config.ts"
data-at-line="4"></span>

```ts [hardhat.config.ts]
import "@nomicfoundation/hardhat-chai-matchers"
import "@nomicfoundation/hardhat-chai-matchers";
```

With the previous steps completed, your `hardhat.config.ts` file should now be properly configured to include settings for local testing.

<span id="compare-config" data-name="compareToFile" data-filepath="tests-output/hardhat-project/hardhat.config.ts"></span>

```ts [hardhat.config.ts]
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@matterlabs/hardhat-zksync";
import "@nomicfoundation/hardhat-chai-matchers";

const config: HardhatUserConfig = {
solidity: "0.8.24",
zksolc: {
version: "latest",
},
networks: {
hardhat: {
zksync: true,
},
},
};

export default config;
```

## Smart contract example

To set up the environment for using chai matchers and writing tests, you'll need to create some contracts.
Follow these steps:

1. Navigate to the root of your project.
1. Create a folder named **contracts**.
1. Inside the **contracts** folder, create a file named **Greeter.sol**.
Inside the **contracts** folder, rename the example contract file to **Greeter.sol**.

<span id="rename-greeter-file" data-name="runCommand" data-command-folder="tests-output/hardhat-project"></span>

```bash
mv contracts/Lock.sol contracts/Greeter.sol
```

Now replace the example contract in **Greeter.sol** with the new `Greeter` contract below:

Now we should add some code to the new **Greeter.sol** file:
<span id="create-greeter-contract" data-name="writeToFile" data-filepath="tests-output/hardhat-project/contracts/Greeter.sol"></span>

```solidity [Greeter.sol]
// SPDX-License-Identifier: MIT
Expand Down Expand Up @@ -156,44 +219,26 @@ contract Greeter {

## Write Test Cases

With the previous steps completed, your `hardhat.config.ts` file should now be properly configured to include settings for local testing.
Now you can create a test with the `hardhat-chai-matchers` plugin:

```ts [hardhat.config.ts]
import { HardhatUserConfig } from "hardhat/config";
Inside the `/test` folder, rename the example test file to `test.ts`.

import "@matterlabs/hardhat-zksync"
import "@nomicfoundation/hardhat-chai-matchers";
<span id="rename-test-file" data-name="runCommand" data-command-folder="tests-output/hardhat-project"></span>

const config: HardhatUserConfig = {
zksolc: {
version: "latest",
},
solidity: "0.8.19",
networks: {
hardhat: {
zksync: true,
},
},
};
export default config;
```bash
mv test/Lock.ts test/test.ts
```

Here are the steps to create test cases with the `hardhat-chai-matchers` plugin:

1. Navigate to your project's root directory.
1. Create a new folder named `/test`.
1. Inside the `/test` folder, create a file named `test.ts`.

Once you've completed these steps, you'll be ready to write your tests using the `hardhat-chai-matchers` plugin.
Replace the old test with this example showcasing the functionalities of the contract:

Here's a brief example showcasing the functionalities of the contract:
<span id="create-test" data-name="writeToFile" data-filepath="tests-output/hardhat-project/test/test.ts"></span>

```typescript
import * as hre from "hardhat";
import { expect } from "chai";
import { Wallet, Provider, Contract } from "zksync-ethers";
import { Deployer } from "@matterlabs/hardhat-zksync";
import { ZkSyncArtifact } from "@matterlabs/hardhat-zksync/src/types";
import { ZkSyncArtifact } from "@matterlabs/hardhat-zksync-deploy/src/types";

const RICH_PRIVATE_KEY = "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110";

Expand Down Expand Up @@ -239,14 +284,16 @@ describe("Greeter", function () {

Execute the following command in your terminal to run the tests:

<span id="run-test" data-name="runCommand" data-command-folder="tests-output/hardhat-project"></span>

::code-group

```bash [yarn]
yarn hardhat test
```bash [npx]
npx hardhat test
```

```bash [npm]
npm hardhat test
```bash [yarn]
yarn hardhat test
```

::
Expand All @@ -257,12 +304,14 @@ However, if you prefer to compile manually, simply run the following command `np

::

The `hardhat-zksync-node` plugin overrides the default behavior of the Hardhat `test` task.
The `hardhat-zksync` plugin overrides the default behavior of the Hardhat `test` task.
It starts the **ZKsync Era Test Node** before running tests, executes the tests,
and then automatically shuts down the node after the test cases are completed.

Additionally, the plugin generates a log file named `era_test_node.log`,
which indicates the node's activity and transactions made during the tests.
Whenever you re-run the `test` command, the content of `era_test_node.log` is refreshed.

This setup ensures that your tests are executed against a controlled environment,
mimicking the behavior of a live network but in a local sandboxed context.
It's a common practice to ensure that smart contracts behave
Expand Down
1 change: 1 addition & 0 deletions cspell-config/cspell-zksync.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ zkcast
ZKEVM
zkevm
zkforge
zknode
zkout
zksolc
zkstack
Expand Down
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"lint:eslint": "eslint .",
"lint:prettier": "prettier --check .",
"fix:prettier": "prettier --write .",
"test:github": "playwright test",
"test:local": "playwright test --headed",
"prepare": "node .husky/install.mjs",
"postinstall": "nuxt prepare",
"ci:check": "bun run lint:eslint && bun run lint:prettier && bun run lint:spelling && bun run lint:markdown",
Expand All @@ -38,15 +40,20 @@
"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@playwright/test": "^1.45.2",
"@vue/test-utils": "^2.4.5",
"cspell": "^8.7.0",
"eslint": "^8.57.0",
"ethers": "^6.13.1",
"hardhat": "^2.22.6",
"husky": "^9.0.11",
"lint-staged": "^15.2.4",
"markdownlint": "^0.34.0",
"markdownlint-cli2": "^0.13.0",
"pm2": "^5.4.2",
"prettier": "^3.2.5",
"prettier-eslint": "^16.3.0",
"prettier-plugin-tailwindcss": "^0.5.14"
"prettier-plugin-tailwindcss": "^0.5.14",
"zksync-ethers": "^6.11.0"
}
}
Loading

0 comments on commit 3737777

Please sign in to comment.