@@ -35,69 +35,38 @@ expected when changes are made.
35
35
Automated tests don't fully replace manually testing your smart contract but
36
36
it's an important tool to ensuring your contract will work as expected.
37
37
38
- ## Let's add some tests
38
+ ## Let's Get Started
39
39
40
- ### First configure hardhat for testing
40
+ ### Setting up our project
41
41
42
- <ContentCallout emoji = " 💡" size = " md" variant = " info" >
43
- We'll depend on ` hardhat ` as our project framework and will use its testing
44
- features. Your project is already hardhat-based so you should be all set to
45
- continue. However if you're unsure on how to setup the initial hardhat
46
- project, refer to Lesson 2 and search for ` npx hardhat ` in the "Create your
47
- project" section.
48
- </ContentCallout >
42
+ If you have an existing project from your previous work on the TierNFT lesson,
43
+ you have all the Hardhat dependencies installed in order to run our testing
44
+ suite.
45
+
46
+ Otherwise, let's create a new Hardhat project, copy in the contract and jump
47
+ into some testing!
48
+
49
+ 1 . Please refer to Lesson 2 and search for ` npx hardhat ` in the "Create your
50
+ project" section to get your project going. After running through that
51
+ section you'll have a working Hardhat project for the next steps.
49
52
50
- Add a line in your ` scripts ` section of ` package.json ` so it looks like this
51
- below. You may already have other scripts' lines so don't get rid of those.
53
+ 2 . Next add a line in your ` scripts ` section of ` package.json ` so it looks like
54
+ this below. You may already have other scripts' lines so don't get rid of
55
+ those. If you already have a ` "test" ` script line, make sure it now has
56
+ ` hardhat test --network hardhat ` . If you have multiple script lines make sure
57
+ the last line does not have a comma at the end, otherwise you'll see an
58
+ error.
52
59
53
60
``` javascript
54
61
" scripts" : {
62
+ " something" : " some other script" ,
55
63
" test" : " hardhat test --network hardhat"
56
64
},
57
65
```
58
66
59
- Next create a ` test ` folder in the root of your project, and add a new file
60
- called ` tier-nft.test.js ` with these lines:
61
-
62
- ``` javascript
63
- const { expect } = require (' chai' )
64
-
65
- describe (' TierNFT' , function () {
66
- it (' placeholder test' )
67
- })
68
- ```
69
-
70
- <ContentCallout emoji = " 💡" size = " md" variant = " info" >
71
- ` expect() ` from the Chai library is used to test various conditions. There are
72
- many examples in this lesson.
73
- </ContentCallout >
74
-
75
- Now with a test file and a command to run the tests, try ` npm test ` and you
76
- should see:
77
-
78
- ``` bash
79
- TierNFT
80
- - placeholder test
81
-
82
-
83
- 0 passing (5ms)
84
- 1 pending
85
- ```
86
-
87
- This now proves:
88
-
89
- - hardhat is running ok
90
- - the tests are found and are running
91
-
92
- ` pending ` means we haven't added the real test yet, so it is neither passing nor
93
- failing. Adding ` pending ` placeholders are a good way to brainstorm and remind
94
- yourself what tests you need to write.
95
-
96
- ## What do we want to test on our TierNFT contract?
97
-
98
- Now that the tools are set up, what should we test?
99
-
100
- Let's look at our contract from Lesson 3:
67
+ 3 . Below is the contract from Lesson 3 we'll be testing. Please copy this code
68
+ into a new file called ` TierNFT.sol ` in a ` contracts ` folder in the root of
69
+ the project.
101
70
102
71
``` solidity
103
72
// SPDX-License-Identifier: MIT
@@ -198,6 +167,11 @@ contract TierNFT is ERC721, Ownable {
198
167
}
199
168
```
200
169
170
+ ## What do we want to test on our TierNFT contract?
171
+
172
+ Now that the tools are set up, let's talk about what we want to test in our
173
+ smart contract. We'll then add create tests.
174
+
201
175
What is the contract trying to do?
202
176
203
177
- it accepts payment and mints NFTs
@@ -212,6 +186,11 @@ We want to test that those functions work in a variety of cases.
212
186
For example, we can test that a mint happens when enough Eth is spent and that a
213
187
mint fails if there is not enough Eth spent.
214
188
189
+ ### Creating our test file
190
+
191
+ Create a ` test ` folder in the root of your project, and add a new file called
192
+ ` tier-nft.test.js ` which will hold our new test code.
193
+
215
194
### Start testing constructor(), mint() and withdraw()
216
195
217
196
Let's start with testing the ` constructor ` and making sure we can set and
@@ -220,6 +199,8 @@ retrieve the NFT name and symbol.
220
199
In addition to these first two tests we'll add setup code that we'll reuse for
221
200
all the other tests too.
222
201
202
+ Please add the following code to your new ` tier-nft.test.js ` file:
203
+
223
204
``` javascript
224
205
const { expect } = require (' chai' )
225
206
@@ -257,6 +238,18 @@ describe('TierNFT', function () {
257
238
})
258
239
```
259
240
241
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
242
+ Before we walk through, let's make sure everything is working correctly. Run
243
+ the tests using ` npm test ` and you should see these two initial tests pass.
244
+ </ContentCallout >
245
+
246
+ Now let's walk through the test code we've pasted in and explain what it does.
247
+
248
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
249
+ ` expect() ` from the Chai library is used to test various conditions. There are
250
+ many examples in this lesson.
251
+ </ContentCallout >
252
+
260
253
At the top we see constants with the name and symbol of the NFT collection:
261
254
262
255
``` javascript
@@ -372,6 +365,12 @@ failure looks like:
372
365
373
366
Here are tests we'll be adding:
374
367
368
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
369
+ In the next sections we'll be continuing to add groups of tests in new ` describe ` sections.
370
+ Where do these go in the file? You have an existing section that starts with ` describe('constructor', async () => { ` .
371
+ Ensure you paste the future ` describe ` sections immediately after where that previous section ends.
372
+ </ContentCallout >
373
+
375
374
``` javascript
376
375
describe (' mint' , async () => {
377
376
it (' should not mint if value is below the minimum tier' , async function () {
@@ -413,6 +412,10 @@ describe('mint', async () => {
413
412
})
414
413
```
415
414
415
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
416
+ Run the tests using ` npm test `
417
+ </ContentCallout >
418
+
416
419
These tests introduce additional code that are helpful when testing contracts.
417
420
418
421
With minting, one needs to pay the right price, we should also see the total
@@ -424,20 +427,19 @@ occurs. If not enough Eth is sent, the contract fails with an error and the
424
427
transaction is reverted as if nothing happened.
425
428
426
429
In this first test we want to ensure our method call is properly reverted when
427
- the proper amount of Eth is not provided. This happens in the
428
- ` await expect().to.be.revertedWith('Not enough value for the minimum Tier') `
429
- line. _ The code calling the contract has been temporarily removed to highlight
430
- what's happening._ We're expecting the call to be reverted when not sending
431
- enough payment, along with a specific error message from the contract.
432
-
433
- And the method inside that ` expect() ` method looks like this:
430
+ the proper amount of Eth is not provided. This happens here:
434
431
435
432
``` javascript
436
- contract .mint ({
437
- value: hre .ethers .utils .parseEther (' 0.001' ),
438
- })
433
+ await expect (
434
+ contract .mint ({
435
+ value: hre .ethers .utils .parseEther (' 0.001' ),
436
+ }),
437
+ ).to .be .revertedWith (' Not enough value for the minimum Tier' )
439
438
```
440
439
440
+ We're expecting the call to be reverted when not sending enough payment, along
441
+ with a specific error message from the contract.
442
+
441
443
Here we're just calling ` mint() ` with a parameter that sets the amount of Eth we
442
444
want to send. In this case ` 0.001 ` Eth is less than our contract minimum of
443
445
` 0.01 ` Eth so this correctly fails. Our test confirms this.
@@ -487,6 +489,10 @@ describe('withdrawal', async () => {
487
489
})
488
490
```
489
491
492
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
493
+ Run the tests using ` npm test `
494
+ </ContentCallout >
495
+
490
496
You'll see similar patterns from the previous ` mint() ` tests. Here are a couple
491
497
of additional highlights:
492
498
@@ -777,6 +783,10 @@ describe('tokenURI and helpers', async () => {
777
783
})
778
784
```
779
785
786
+ <ContentCallout emoji = " 💡" size = " md" variant = " info" >
787
+ Run the tests using ` npm test `
788
+ </ContentCallout >
789
+
780
790
The final test is an example mentioned earlier about adding a test before
781
791
refactoring with helper methods. It checks that the initial ` tokenURI() ` method
782
792
(which returns an encoded Base64 string) returns the right result. It's helpful
0 commit comments