Solution 2: Code Testing and Profiling
Explore how to write effective test functions in Go to validate code correctness and use profiling techniques to optimize performance. This lesson helps you understand testing key functions and capturing output to ensure your Go applications run reliably.
We'll cover the following...
We'll cover the following...
...
package main
import (
"os"
"testing"
"strings"
)
func TestReadCSVFile(t *testing.T) {
// Create a temporary test CSV file
tmpFile := "/tmp/test.csv"
f, err := os.Create(tmpFile)
if err != nil {
t.Fatal(err)
}
defer f.Close()
// Write test data to the temporary file
testData := "John,Doe,1234567890,123456789\nJane,Smith,9876543210,987654321\n"
_, err = f.WriteString(testData)
if err != nil {
t.Fatal(err)
}
// Call readCSVFile to read the temporary file
err = readCSVFile(tmpFile)
if err != nil {
t.Fatal(err)
}
// Check if data is loaded correctly
if len(data) != 2 {
t.Fatalf("Expected 2 entries, got %d", len(data))
}
// Clean up the temporary file
err = os.Remove(tmpFile)
if err != nil {
t.Fatal(err)
}
}
// A setup function to clear data before tests
func setup() {
data = []Entry{}
index = make(map[string]int)
}
func TestInsert(t *testing.T) {
// Set up the test environment
setup()
// Initialize test data
testEntry := initS("Test", "User", "5551234567")
if testEntry == nil {
t.Fatal("Failed to initialize test entry")
}
// Call insert to insert the test entry
err := insert(testEntry)
if err != nil {
t.Fatal(err)
}
// Check if the test entry was inserted
if len(data) != 1 {
t.Fatalf("Expected 1 entry after insert, got %d", len(data))
}
// Clean up by deleting the test entry
err = deleteEntry("5551234567")
if err != nil {
t.Fatal(err)
}
}
func TestDeleteEntry(t *testing.T) {
// Initialize test data
testEntry := initS("Test", "User", "5551234567")
if testEntry == nil {
t.Fatal("Failed to initialize test entry")
}
// Insert the test entry
err := insert(testEntry)
if err != nil {
t.Fatal(err)
}
// Call deleteEntry to delete the test entry
err = deleteEntry("5551234567")
if err != nil {
t.Fatal(err)
}
// Check if the test entry was deleted
if len(data) != 0 {
t.Fatalf("Expected 0 entries after delete, got %d", len(data))
}
}
func TestSearch(t *testing.T) {
// Initialize test data
testEntry := initS("Test", "User", "5551234567")
if testEntry == nil {
t.Fatal("Failed to initialize test entry")
}
// Insert the test entry
err := insert(testEntry)
if err != nil {
t.Fatal(err)
}
// Call search to find the test entry
result := search("5551234567")
if result == nil {
t.Fatal("Failed to find test entry")
}
// Clean up by deleting the test entry
err = deleteEntry("5551234567")
if err != nil {
t.Fatal(err)
}
}
func TestList(t *testing.T) {
// Set up test data
setup()
testData := []Entry{
{Name: "John", Surname: "Doe", Tel: "1234567890", LastAccess: "123456789"},
{Name: "Jane", Surname: "Smith", Tel: "9876543210", LastAccess: "987654321"},
}
data = append(data, testData...)
// Redirect standard output to capture printed output
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
// Call the list function
list()
// Close the pipe and restore stdout
w.Close()
os.Stdout = oldStdout
// Read the captured output from the pipe
outputBytes := make([]byte, 4096)
n, _ := r.Read(outputBytes)
// Convert the captured output to a string and split it into lines
output := string(outputBytes[:n])
lines := strings.Split(output, "\n")
// Check if the number of lines matches the number of entries in the test data
if len(lines)-1 != len(testData) { // Subtract 1 to account for the final newline
t.Fatalf("Expected %d lines in output, got %d", len(testData), len(lines)-1)
}
}
func TestMatchTel(t *testing.T) {
// Test cases for matchTel
testCases := []struct {
input string
expected bool
}{
{"1234567890", true}, // Valid telephone number
{"9876543210", true}, // Valid telephone number
{"abcd", false}, // Non-digit characters
{"", false}, // Empty string
}
// Run test cases
for _, tc := range testCases {
result := matchTel(tc.input)
if result != tc.expected {
t.Errorf("For input %s, expected %v, but got %v", tc.input, tc.expected, result)
}
}
}phoneBook.go and phoneBook_test.go
...