github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/docs/how-to-guides/testing-gno.md (about) 1 --- 2 id: testing-gno 3 --- 4 5 # How to test Gno Code 6 7 ## Overview 8 9 In this guide, we will explore the available tooling in testing out the Gno Realms and Packages we write. 10 We will go over different CLI tools available to developers, gno testing libraries as well as 11 testing techniques that involve data mocking. 12 13 ## Prerequisites 14 15 - **`gno` set up. Reference the [Installation](../getting-started/local-setup/local-setup.md#3-installing-other-gno-tools) guide 16 for steps** 17 18 ## Example Realm 19 20 For the purpose of this guide, we will be testing the simple *Counter* Realm created in 21 the [How to write a simple Gno Smart Contract (Realm)](simple-contract.md) guide. 22 23 [embedmd]:# (../assets/how-to-guides/testing-gno/counter-1.gno go) 24 ```go 25 // counter-app/r/counter/counter.gno 26 27 package counter 28 29 import ( 30 "gno.land/p/demo/ufmt" 31 ) 32 33 var count int 34 35 func Increment() { 36 count++ 37 } 38 39 func Decrement() { 40 count-- 41 } 42 43 func Render(_ string) string { 44 return ufmt.Sprintf("Count: %d", count) 45 } 46 ``` 47 48 ## 1. Writing the Gno test 49 50 Gno tests are written in the same manner and format as regular Go tests, just in `_test.gno` files. 51 52 We can place the Gno tests for the `Counter` Realm in the same directory as `counter.gno`: 53 54 ```text 55 counter-app/ 56 ├─ r/ 57 │ ├─ counter/ 58 │ │ ├─ counter.gno 59 │ │ ├─ counter_test.gno <--- the test source code 60 ``` 61 62 ```bash 63 cd counter 64 touch counter_test.gno 65 ``` 66 67 What should be tested in this _Counter_ Realm example? 68 Mainly, we want to verify that: 69 70 - Increment increments the value. 71 - Decrement decrements the value. 72 - Render returns a valid formatted value. 73 74 Let's write the required unit tests: 75 76 [embedmd]:# (../assets/how-to-guides/testing-gno/counter-2.gno go) 77 ```go 78 // counter-app/r/counter/counter_test.gno 79 80 package counter 81 82 import "testing" 83 84 func TestCounter_Increment(t *testing.T) { 85 // Reset the value 86 count = 0 87 88 // Verify the initial value is 0 89 if count != 0 { 90 t.Fatalf("initial value != 0") 91 } 92 93 // Increment the value 94 Increment() 95 96 // Verify the initial value is 1 97 if count != 1 { 98 t.Fatalf("initial value != 1") 99 } 100 } 101 102 func TestCounter_Decrement(t *testing.T) { 103 // Reset the value 104 count = 0 105 106 // Verify the initial value is 0 107 if count != 0 { 108 t.Fatalf("initial value != 0") 109 } 110 111 // Decrement the value 112 Decrement() 113 114 // Verify the initial value is 1 115 if count != -1 { 116 t.Fatalf("initial value != -1") 117 } 118 } 119 120 func TestCounter_Render(t *testing.T) { 121 // Reset the value 122 count = 0 123 124 // Verify the Render output 125 if Render("") != "Count: 0" { 126 t.Fatalf("invalid Render value") 127 } 128 } 129 ``` 130 131 :::warning Testing package-level variables 132 133 In practice, it is not advisable to test and validate package level variables like this, as their value is mutated 134 between test runs. For the sake of keeping this guide simple, we went ahead and reset the variable value for each test, 135 however, 136 you should employ more robust test strategies. 137 138 ::: 139 140 ## 2. Running the Gno test 141 142 To run the prepared Gno tests, we can utilize the `gno test` CLI tool. 143 144 Simply point it to the location containing our testing source code, and the tests will execute. 145 For example, we can run the following command from the `counter-app/r/counter` directory: 146 147 ```bash 148 gno test -v . 149 ``` 150 151 Let's look into the different parts of this command: 152 153 - `-v` enables the verbose output. 154 - `-root-dir` specifies the root directory to our cloned `gno` GitHub repository 155 - `.` specifies the location containing our test files. Since we are already located in that directory, we specify 156 a `.`. 157 158 Running the test command should produce a successful output: 159 160 ```bash 161 === RUN TestCounter_Increment 162 --- PASS: TestCounter_Increment (0.00s) 163 === RUN TestCounter_Decrement 164 --- PASS: TestCounter_Decrement (0.00s) 165 === RUN TestCounter_Render 166 --- PASS: TestCounter_Render (0.00s) 167 ok ./. 1.00s 168 ``` 169 170 ## Additional test support 171 172 As we grow more familiar with Gno development, our Realm / Package logic can become more complex. As such, we need 173 more robust testing support in the form of mocking values ahead of time that would normally be only available on a 174 live (deployed) Realm / Package. 175 176 Luckily, the Gno standard library provides ample support for functionality such as setting predefined values ahead of 177 time, such as the request caller address, or the calling package address. 178 179 You can learn more about these methods, that are importable using the `std` import declaration, 180 in the [Standard Library](../concepts/stdlibs/stdlibs.md) reference section. 181 182 ## Conclusion 183 184 That's it 🎉 185 186 You have successfully written and tested Gno code. Additionally, you have utilized the `gno test` tool, and understood 187 how it can be configured to make the developer experience smooth.