后端实践--单元测试与性能优化 青训营

简介: 后端实践--单元测试与性能优化 青训营

go单元测试与性能优化

go单元测试与性能优化

这篇博客简单总结go的单元测试和性能优化相关的知识。

1. 单元测试

Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的。编写完代码后只需在命令行执行相应命令即可运行测试代码。

go test -v 显示详细信息。

go test -cover 查看测试覆盖率

go test -cover -coverprofile=xx.out 将测试覆盖率输出到xx.out文件

go tool cover -html=xx.out 使用浏览器分析文件

在包目录中以 _test.go为后缀的源代码属于测试代码。不会被go build编译到可执行文件中。测试代码中主要由三种类型的函数:测试函数、性能基准函数、示例函数。

测试代码方便测试,写完..._test.go文件后,修改源代码后直接执行go test 命令即可!!!go test命令会遍历所有的*_test.go文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。

1. 测试函数

// 如在 add_test.go 文件里
// 格式必须是这样! Test...
func TestAdd1(t *testing.T){
  // ...
}
func TestAdd2(t *testing.T){
  // ...
}
func Test...(t *testing.T){
  // ...
}

类似的测试逻辑写多个测试函数过于臃肿,可以用测试组,就是放在一个函数里。

func TestAdd(t *testing.T){
  // 利用结构体存储多组测试用例
  type testCase struct{
    // 待测试的函数参数
    ...
    // 期望结果
    want []int
  }
  // 初始化一个结构体切片
  testGroup := []testCase{
    testCase{...},
    testCase{...},
    testCase{...},
  }
  // 遍历切片,调用函数得到结果与want进行比较。
}

这样想看一下某一个特定测试用例的结果就比较麻烦,于是又引出子测试:就是把结构体切片换成map。这样还可以单独的只测试某一个测试用例:

go test -run=TestAdd/case1

func TestAdd(t *testing.T){
  // 利用结构体存储多组测试用例
  type testCase struct{
    // 待测试的函数参数
    ...
    // 期望结果
    want []int
  }
  // 初始化一个map
  testGroup := map[string]testCase{
    "case1": testCase{...}, 
    "case1": testCase{...},
    "case1": testCase{...},
  }
  // 遍历map,调用函数得到结果与want进行比较。
}

2. 性能基准函数

go test -bench=Add 执行基准函数

go test -bench=Add -cpu=1 执行基准函数,只使用一个CPU,默认是跑满所有。

go test -bench=Add -benchmem 执行基准函数同时查看内存情况

// 格式  Benchmark...
func BenchmarkAdd(b testing.B){
  // 必须执行 b.N 遍待测试函数
  for i := 0; i < b.N; i++{
    // 执行待测试函数
  }
}

SetupTeardown : 执行测试之前的准备工作和测试之后的恢复工作。

3. 示例函数

比较少用。

// 格式
func ExampleAdd(){
  // ...
}

2. 性能优化pprof

性能测试 pprof,记录快照信息。

需要测试性能时才开启pprof,不需要的时候就关掉,因为测试性能本身会占用很多资源。

性能优化指标:==CPU使用情况、内存使用、==死锁情况....

1. CPU性能分析

// 开始CPU检测
pprof.StartCPUProfile(w io.Writer) 
// 停止检测
pprof.StopCPUProfile()

2. 内存分析

pprof.WriteHeapProfile(w io.Writer)

3. 相关命令

go tool pprof xxx.pprof 分析生成的文件,进入交互模式

而后 top 查看哪些进程占用CPU,占用时间是多少(就和Linuxtop命令类似);list 进程名 查看进程内具体哪一行代码占用CPU时间最长。

以上就是这篇博客的简单内容,后面继续对所学的内容进行简单归纳整理!加油。

1. 单元测试

go test 命令

go test -v 显示详细信息。

go test -cover 查看测试覆盖率

go test -cover -coverprofile=xx.out 将测试覆盖率输出到xx.out文件

go tool cover -html=xx.out 使用浏览器分析文件

在包目录中以 _test.go为后缀的源代码属于测试代码。不会被go build编译到可执行文件中。测试代码中主要由三种类型的函数:测试函数、性能基准函数、示例函数。

测试代码方便测试,写完..._test.go文件后,修改源代码后直接执行go test 命令即可!!!

1. 测试函数

// 如在 add_test.go 文件里
// 格式必须是这样! Test...
func TestAdd1(t *testing.T){
  // ...
}
func TestAdd2(t *testing.T){
  // ...
}
func Test...(t *testing.T){
  // ...
}

类似的测试逻辑写多个测试函数过于臃肿,可以用测试组,就是放在一个函数里。

func TestAdd(t *testing.T){
  // 利用结构体存储多组测试用例
  type testCase struct{
    // 待测试的函数参数
    ...
    // 期望结果
    want []int
  }
  // 初始化一个结构体切片
  testGroup := []testCase{
    testCase{...},
    testCase{...},
    testCase{...},
  }
  // 遍历切片,调用函数得到结果与want进行比较。
}

这样想看一下某一个特定测试用例的结果就比较麻烦,于是又引出子测试:就是把结构体切片换成map。这样还可以单独的只测试某一个测试用例:

go test -run=TestAdd/case1

func TestAdd(t *testing.T){
  // 利用结构体存储多组测试用例
  type testCase struct{
    // 待测试的函数参数
    ...
    // 期望结果
    want []int
  }
  // 初始化一个map
  testGroup := map[string]testCase{
    "case1": testCase{...}, 
    "case1": testCase{...},
    "case1": testCase{...},
  }
  // 遍历map,调用函数得到结果与want进行比较。
}

2. 性能基准函数

go test -bench=Add 执行基准函数

go test -bench=Add -cpu=1 执行基准函数,只使用一个CPU,默认是跑满所有。

go test -bench=Add -benchmem 执行基准函数同时查看内存情况

// 格式  Benchmark...
func BenchmarkAdd(b testing.B){
  // 必须执行 b.N 遍待测试函数
  for i := 0; i < b.N; i++{
    // 执行待测试函数
  }
}

SetupTeardown : 执行测试之前的准备工作和测试之后的恢复工作。

3. 示例函数

比较少用。

// 格式
func ExampleAdd(){
  // ...
}

2. 性能优化pprof

性能测试 pprof,记录快照信息。

需要测试性能时才开启pprof,不需要的时候就关掉,因为测试性能本身会占用很多资源。

性能优化指标:==CPU使用情况、内存使用、==死锁情况....

1. CPU性能分析

// 开始CPU检测
pprof.StartCPUProfile(w io.Writer) 
// 停止检测
pprof.StopCPUProfile()

2. 内存分析

pprof.WriteHeapProfile(w io.Writer)

3. 相关命令

go tool pprof xxx.pprof 分析生成的文件,进入交互模式

而后 top 查看哪些进程占用CPU,占用时间是多少(就和Linuxtop命令类似);list 进程名 查看进程内具体哪一行代码占用CPU时间最长。

以上就是这篇博客的简单内容,后面继续对所学的内容进行简单归纳整理!加油。

相关文章
|
8天前
|
设计模式 存储 安全
深入理解后端开发:从基础到高级实践
在数字化时代,后端开发是构建强大、可靠和高效软件系统的核心。本文将引导读者从基本概念出发,逐步深入到后端开发的高级实践,包括设计模式、性能优化以及安全性考量。通过深入浅出的解释和实例演示,旨在帮助初学者和有经验的开发者巩固知识、拓展视野,并激发对后端开发深层次理解的兴趣。
|
6天前
|
机器学习/深度学习 人工智能 安全
软件测试的艺术:探索与实践
【8月更文挑战第15天】 在数字时代的浪潮中,软件开发的每一步都至关重要。软件测试,作为保障质量的关键一环,不仅需要技术的精湛,更需艺术的触感。本文将深入浅出地探讨软件测试的重要性、基本方法以及面临的挑战,并分享一些实用的测试技巧和最佳实践,旨在帮助读者更好地理解并掌握软件测试的艺术。
|
7天前
|
Java 测试技术 开发者
提高代码质量:深入实践测试驱动开发(TDD)
【8月更文挑战第14天】测试驱动开发是一种强大的软件开发方法,它通过先写测试再编写代码的方式,显著提高了代码质量。通过实践TDD,开发者可以编写出更可靠、更易于维护的代码,并加速开发进程。虽然TDD需要一定的学习和适应过程,但其带来的长期收益是不可估量的。如果你还没有尝试过TDD,现在就开始吧!
|
8天前
|
存储 SQL 缓存
构建高性能后端服务的策略与实践
【8月更文挑战第13天】在数字化时代,后端服务的高效性对于企业至关重要。本文深入探讨了如何通过合理设计、优化数据库操作以及应用缓存技术等策略来提升后端服务性能。同时,也强调了监控和调优的重要性,并指出了团队协作在性能优化中的作用。
23 3
|
7天前
|
安全 Java 数据库
后端开发的艺术与实践
在数字化时代的浪潮中,后端开发如同一位默默无闻的画家,在幕后精心绘制着互联网世界的绚丽多彩。本文将带你走进后端开发的世界,从基础概念到技术选型,再到性能优化和安全防护,一起探索那些隐藏在代码背后的艺术与智慧。
|
8天前
|
存储 测试技术 数据库
探索后端开发:从基础到高级实践
在这篇文章中,我们将一起踏上一段激动人心的旅程,穿越后端开发的广阔天地。无论你是刚踏入这个领域的新手,还是希望巩固和扩展知识的资深开发者,本文都将是你的指南针。我们将从后端开发的基础知识讲起,涵盖语言选择、数据库设计、服务器架构等核心概念。随后,深入探讨高级实践,包括微服务架构、容器化技术以及自动化测试策略。最后,我们将讨论如何保持技术热情,持续学习,并对未来趋势保持敏锐的洞察力。让我们一起解锁后端开发的秘密,构建强大而灵活的系统吧!
|
1天前
|
Kubernetes 数据库 开发者
后端开发中的微服务架构实践
【8月更文挑战第19天】本文将深入探讨微服务架构在后端开发中的应用,包括其设计原则、挑战与解决方案。文章旨在为读者提供一种现代后端开发的新视角,帮助开发者更好地理解并应用微服务架构以提升系统的可维护性、可扩展性和敏捷性。
|
2天前
|
运维 API 持续交付
后端开发中的微服务架构实践
【8月更文挑战第19天】在现代软件工程中,微服务架构作为一种灵活、可扩展的后端解决方案,正逐渐取代传统的单体应用。本文将深入探讨微服务的核心概念、设计原则和实际应用策略,旨在为读者提供一套完整的微服务架构实施指南。
7 0
百万并发连接的实践测试02
百万并发连接的实践测试02
|
5天前
|
网络协议 Ubuntu
百万并发连接的实践测试01
百万并发连接的实践测试01