1 TDD learning
1.1 about TDD
concept
Test-driven Development, English full name test-driven Development, referred to as TDD, is a new Development method different from the traditional software Development process. It requires that you write test code before you write the code for a feature, and then only write the code for the feature that makes the test pass, and the test drives the development.
TDD three principles
- You are not allowed to write any production code except to pass a unit test.
- You are only allowed to write just enough to fail in a unit test.
- You can only write production code that passes one unit test at a time, no more.
refactoring
Code refactoring refers to making any change to software code to increase readability or simplify structure without affecting the output.
1.2 About benchmarking
What is a benchmark
Benchmarking measures the performance of an application under a fixed workload. In Go, a Benchmark function is written like a normal test function, but prefixes it with a parameter of type * testing.b. The * testing.b parameter provides a method similar to * testing.t, with additional methods related to performance measurement. It also provides an integer N that specifies the number of cycles the operation is executed.
Benchmarking versus stress testing
Benchmarking can be thought of as a stress test for a system. Benchmarking is simple, straightforward, and easy to test without concern for business logic. The data can be generated by tools and does not require authenticity. Stress testing generally considers business logic and requires real data.
The role of benchmarking
For most Web applications, the bottleneck of the whole system lies in the database; The reason is simple: other factors in Web applications, such as network bandwidth, load balancing nodes, application servers (including CPU, memory, disk lights, connection count, etc.), and caching, can easily be improved by horizontal scaling (commonly known as adding machines). As for MySQL, due to the requirement of data consistency, it cannot disperse the pressure of writing data to the database by adding machines. Although it can be alleviated by pre-caching (Redis, etc.), read-write separation, and separate libraries and tables, it is too limited compared to the horizontal scaling of other components of the system.
The function of a database benchmark is to analyze the performance of the database under the current configuration (including hardware configuration, OS configuration, and database configuration), find out the performance threshold of MySQL, and adjust the configuration according to the actual system requirements.
1.3 Complete the “Iteration” tutorial
Writing tests first
package iteration import "testing" func TestRepeat(t *testing.T) { repeated := Repeat("a") expected := "aaaaa" if repeated ! = expected { t.Errorf("expected '%q' but got '%q'", expected, repeated) } }Copy the code
Try to run the tests
Let failed tests run with minimal code
package iteration
func Repeat(character string) string {
return ""
}
Copy the code
Results:
Write implementations that pass tests
package iteration
func Repeat(character string) string {
var repeated string
for i := 0; i < 5; i++ {
repeated = repeated + character
}
return repeated
}
Copy the code
Results:
refactoring
Modify code for standardization, simplicity, readability, etc. :
const repeatCount = 5
func Repeat(character string) string {
var repeated string
for i := 0; i < repeatCount; i++ {
repeated += character
}
return repeated
}
Copy the code
The benchmark
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
Repeat("a")
}
}
Copy the code
It is worth noting that Goland can quickly generate test code:Results:
Complete the exercises in the “Iteration” chapter
Modify the test code so that the caller can specify how many times the character is repeated, and then fix the code
Modify the test code:Then run the test:You can see that you need to modify the production code to pass the unit tests:Pass the test:
Write an ExampleRepeat to complete your function documentation
The requirements are met.
Look at the strings package. Find functions that you think might be useful, and write some tests on them.
Test the Count function
Test code:
s := "go mod init github.com/Winszheng"
fmt.Printf("test1: %d\n", strings.Count(s, "s"))
fmt.Printf("test2: %d\n", strings.Count(s, "g"))
Copy the code
Results:
3 Select sort TDD practice report
Writing tests first
func TestSelectSort(t *testing.T) { initial := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1} SelectSort(initial) expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i:=0; i<10; i++ { if initial[i]! =expected[i] { t.Errorf("expected %v but get %v\n", expected, initial) } } }Copy the code
Try to run the tests
Let failed tests run with minimal code
func SelectSort(arr []int) ([]int) {
return arr
}
Copy the code
Results:
Write code that passes tests
Code:
func SelectSort(arr []int) ([]int) {
for i := 0; i < len(arr)-1; i++ {
min := i
for j := i+1; j < len(arr); j++ {
if arr[j] < arr[min] {
min = j
}
}
arr[min], arr[i] = arr[i], arr[min]
}
return arr
}
Copy the code
Results:
refactoring
Refactoring like the tutorial:
func SelectSort(arr []int) ([]int) {
len := len(arr)
for i := 0; i < len - 1; i++ {
min := i
for j := i+1; j < len; j++ {
if arr[j] < arr[min] {
min = j
}
}
arr[min], arr[i] = arr[i], arr[min]
}
return arr
}
Copy the code
The benchmark
func Benchmark(b *testing.B) {
for i := 0; i < b.N; i++ {
initial := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
SelectSort(initial)
}
}
Copy the code
Run the benchmark:
4 reference
Test-Driven Development(TDD) in Go
The benchmark
How do I write goDoc