| <!--{ | |
| "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.Errorf(`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.Errorf(`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="/pkg/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="/pkg/testing/#T.Errorf"> | |
| <code>Errorf</code> method</a> to print a message to the console. | |
| </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 | |
| <a href="/pkg/testing/#T.Errorf"><code>Errorf | |
| </code> method</a> to print a message to the console. | |
| </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> |