Elapsed | Time | Activity |
---|---|---|
0:00 | 0:05 | Why / Objectives |
0:05 | 0:20 | Overview |
0:25 | 0:30 | In Class Activity I |
0:55 | 0:10 | BREAK |
1:05 | 0:30 | In Class Activity II |
1:35 | 0:20 | Lab Time |
1:55 | 0:05 | Wrap Up |
Performance is an important factor in your applications! Today's lesson focuses on tools and techniques that help you find broken, slow, or inefficient code faster than ever. Benchmarking and testing are techniques that yield the kind of code that impresses peers and colleagues alike!
- Identify and describe testing and benchmarking techniques that speed up your project.
- Define
benchmark test
andtable test
and describe how they can be used together to improve the code quality of your project. - Implement benchmarking and testing via two in-class mini-tutorials.
- Explore how to incorporate benchmarking and testing in your MakeUtility project.
(noun) Table-Driven Test
A complete test case with inputs and expected results. Sometimes, additional information such as a test name may be included to make the test output easily readable.
If you ever find yourself using copy and paste when writing a test, think about whether refactoring into a table-driven test or pulling the copied code out into a helper function might be a better option.
Example of a basic table-driven test:
func TestDivision(t *testing.T) {
tests := []struct{
x float64
y float64
result float64
err error
}{
{ x: 1.0, y: 2.0, result: 0.5, err: nil },
{ x: -1.0, y: 2.0, result: -0.5, err: nil},
{ x: 1.0, y: 0.0, result: 0.0, err: ErrZeroDivision},
}
for _, test := range tests {
result, err := divide(test.x, test.y)
assert.IsType(t, test.err, err)
assert.Equal(t, test.result, result)
}
}
Example with named test cases:
tests := map[string]struct {
number int
smsErr error
err error
}{
"successful": {0132423444, nil, nil},
"propagates error": {0132423444, sampleErr, sampleErr},
}
(noun) Benchmark Test
A test designed or used to establish a point of comparison for the performance or effectiveness of something, especially computer hardware or software.
func BenchmarkFoo(b *testing.B) {
for i := 0; i < b.N; i++ {
// TODO: Perform the operation we're analyzing.
}
}
- Create a new GitHub repo and clone it locally.
- Complete the Introduction to Testing in Go mini-tutorial.
- Commit and push your code to GitHub.
- Using the same repository as earlier, complete the Introduction to Benchmarking Your Go Programs mini-tutorial.
- Commit and push your code to GitHub.
- Slack the link to the class channel to indicate that you've completed both tutorials.
- What is a golden file? How could a developer incorporate a golden file into their existing projects?
- What is mocking? What data structures complement mocking? How could a developer implement mocking to create more accurate test scenarios?
- What are test fixtures? How could you use Golang to automatically load test fixtures?
- Should you use the
_test
package in your project? Why or why not?
Consider how you can practically apply the techniques discussed in class today to improve the code quality and performance of your MakeUtility project!
- Beautifully Simple Benchmarking in Go: Read this first, then dive deep with the next link!
- Writing Table Driven Tests in Go: A short introduction to the mechanics and syntax of writing a table driven test in Go.
- How to Write Benchmarks in Go: Continues the series on the
testing
package linked above. - Practical Go Benchmarks: This collection of practical performance benchmarks of Go packages and algorithms aims to help developers write fast and efficient programs.
- Analyzing the Performance of Go Functions with Benchmarks: Compares the performance metrics of three different merging techniques with
n
channels in Go. - go-gophers/gophers: Gophers is a tool for API testing. It covers unit testing of individual components, functional testing of broader scenarios, and generation of up-to-date examples for documentation from testing scenarios.