| <!--{ |
| "Title": "Add a test", |
| "Breadcrumb": true |
| }--> |
| |
| <p> |
| Now that you've gotten your code to a stable place (nicely done, by the way), |
| add a test. Testing your code during development can expose bugs that find |
| their way in as you make changes. In this topic, you add a test for the |
| <code>Hello</code> function. |
| </p> |
| |
| <aside class="Note"> |
| <strong>Note:</strong> This topic is part of a multi-part tutorial that begins |
| with <a href="/doc/tutorial/create-module.html">Create a Go module</a>. |
| </aside> |
| |
| <p> |
| Go's built-in support for unit testing makes it easier to test as you go. |
| Specifically, using naming conventions, Go's <code>testing</code> package, and |
| the <code>go test</code> command, you can quickly write and execute tests. |
| </p> |
| |
| <ol> |
| <li> |
| In the greetings directory, create a file called greetings_test.go. |
| |
| <p> |
| Ending a file's name with _test.go tells the <code>go test</code> command |
| that this file contains test functions. |
| </p> |
| </li> |
| |
| <li> |
| In greetings_test.go, paste the following code and save the file. |
| |
| <pre> |
| package greetings |
| |
| import ( |
| "testing" |
| "regexp" |
| ) |
| |
| // TestHelloName calls greetings.Hello with a name, checking |
| // for a valid return value. |
| func TestHelloName(t *testing.T) { |
| name := "Gladys" |
| want := regexp.MustCompile(`\b`+name+`\b`) |
| msg, err := Hello("Gladys") |
| if !want.MatchString(msg) || err != nil { |
| t.Fatalf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want) |
| } |
| } |
| |
| // TestHelloEmpty calls greetings.Hello with an empty string, |
| // checking for an error. |
| func TestHelloEmpty(t *testing.T) { |
| msg, err := Hello("") |
| if msg != "" || err == nil { |
| t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err) |
| } |
| } |
| </pre |
| > |
| |
| <p> |
| In this code, you: |
| </p> |
| |
| <ul> |
| <li> |
| Implement test functions in the same package as the code you're testing. |
| </li> |
| <li> |
| Create two test functions to test the <code>greetings.Hello</code> |
| function. Test function names have the form <code>Test<em>Name</em></code>, |
| where <em>Name</em> says something about the specific test. Also, test |
| functions take a pointer to the <code>testing</code> package's |
| <a href="https://pkg.go.dev/testing/#T"><code>testing.T</code> |
| type</a> as a parameter. You use this parameter's methods for reporting |
| and logging from your test. |
| </li> |
| <li> |
| Implement two tests: |
| |
| <ul> |
| <li> |
| <code>TestHelloName</code> calls the <code>Hello</code> function, |
| passing a <code>name</code> value with which the function should be |
| able to return a valid response message. If the call returns an |
| error or an unexpected response message (one that doesn't include |
| the name you passed in), you use the <code>t</code> parameter's |
| <a href="https://pkg.go.dev/testing/#T.Fatalf"> |
| <code>Fatalf</code> method</a> to print a message to the console |
| and end execution. |
| </li> |
| <li> |
| <code>TestHelloEmpty</code> calls the <code>Hello</code> function |
| with an empty string. This test is designed to confirm that your |
| error handling works. If the call returns a non-empty string or no |
| error, you use the <code>t</code> parameter's <code>Fatalf</code> |
| method to print a message to the console and end execution. |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| |
| <li> |
| At the command line in the greetings directory, run the |
| <a href="/cmd/go/#hdr-Test_packages" |
| ><code>go test</code> command</a |
| > |
| to execute the test. |
| |
| <p> |
| The <code>go test</code> command executes test functions (whose names |
| begin with <code>Test</code>) in test files (whose names end with |
| _test.go). You can add the <code>-v</code> flag to get verbose output that |
| lists all of the tests and their results. |
| </p> |
| |
| <p> |
| The tests should pass. |
| </p> |
| |
| <pre> |
| $ go test |
| PASS |
| ok example.com/greetings 0.364s |
| |
| $ go test -v |
| === RUN TestHelloName |
| --- PASS: TestHelloName (0.00s) |
| === RUN TestHelloEmpty |
| --- PASS: TestHelloEmpty (0.00s) |
| PASS |
| ok example.com/greetings 0.372s |
| </pre |
| > |
| </li> |
| |
| <li> |
| Break the <code>greetings.Hello</code> function to view a failing test. |
| |
| <p> |
| The <code>TestHelloName</code> test function checks the return value for |
| the name you specified as a <code>Hello</code> function parameter. To view |
| a failing test result, change the <code>greetings.Hello</code> function so |
| that it no longer includes the name. |
| </p> |
| |
| <p> |
| In greetings/greetings.go, paste the following code in place of the |
| <code>Hello</code> function. Note that the highlighted lines change the |
| value that the function returns, as if the <code>name</code> argument had |
| been accidentally removed. |
| </p> |
| |
| <pre> |
| // Hello returns a greeting for the named person. |
| func Hello(name string) (string, error) { |
| // If no name was given, return an error with a message. |
| if name == "" { |
| return name, errors.New("empty name") |
| } |
| // Create a message using a random format. |
| <ins>// message := fmt.Sprintf(randomFormat(), name) |
| message := fmt.Sprint(randomFormat())</ins> |
| return message, nil |
| } |
| </pre> |
| </li> |
| |
| <li> |
| At the command line in the greetings directory, run <code>go test</code> to |
| execute the test. |
| |
| <p> |
| This time, run <code>go test</code> without the <code>-v</code> flag. The |
| output will include results for only the tests that failed, which can be |
| useful when you have a lot of tests. The <code>TestHelloName</code> test |
| should fail -- <code>TestHelloEmpty</code> still passes. |
| </p> |
| |
| <pre> |
| $ go test |
| --- FAIL: TestHelloName (0.00s) |
| greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil |
| FAIL |
| exit status 1 |
| FAIL example.com/greetings 0.182s |
| </pre |
| > |
| </li> |
| </ol> |
| |
| <p> |
| In the next (and last) topic, you'll see how to compile and install your code |
| to run it locally. |
| </p> |
| |
| <p class="Navigation"> |
| <a class="Navigation-prev" href="/doc/tutorial/greetings-multiple-people.html" |
| >< Return greetings for multiple people</a |
| > |
| <a class="Navigation-next" href="/doc/tutorial/compile-install.html" |
| >Compile and install the application ></a |
| > |
| </p> |