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.