个人技术总结--单元测试

152201106庄仲华 2024-12-11 23:05:29
这个作业属于哪个课程https://bbs.csdn.net/forums/2401_CS_SE_FZU
这个作业要求在哪里https://bbs.csdn.net/topics/619470310
这个作业的目标个人技术总结
其他参考文献

目录

  • 1.技术概述
  • 2.技术详述
  • 2.1 解析
  • 2.2实际应用
  • 3.遇到的问题
  • 4.总结
  • 参考

1.技术概述

单元测试是测试代码中最小的功能单元的过程。软件测试有助于确保代码质量,是软件开发过程中不可或缺的一部分。软件开发的最佳实践是将软件编写为小型功能单元,然后为每个代码单元编写单元测试。您可以先将单元测试编写为代码。然后,在每次更改软件代码时自动运行该测试代码。这样,如果测试失败,您就能快速隔离出存在漏洞或错误的代码区域。单元测试可以强化模块化思维范式,并提高测试的覆盖率和质量。自动单元测试有助于确保您或您的开发人员有更多时间专注于编码。

2.技术详述

2.1 解析

单元测试有一些广泛接受的准则和最佳实践,目的是确保测试代码具有可读性、可维护性、稳定性,并且能够准确反映被测试的功能。以下是常见的单元测试准则,以及如何在我实践中实现它们。

  1. 单一责任原则(Single Responsibility)
  • 每个单元测试应该专注于一个特定的行为或场景。如果一个测试验证了多个行为或功能,就违反了单一责任原则。
  1. 独立性(Independence)
  • 单元测试应该是独立的,不依赖于其他测试的结果或环境。如果一个测试的执行依赖于其他测试,应该避免这种情况。
  1. 快速性(Speed)
  • 单元测试应该执行迅速,以确保频繁运行时不会增加开发周期。测试应该避免与外部系统(例如数据库、网络、磁盘)交互,除非它们是直接相关的。
  1. 可重复性(Repeatability)
  • 单元测试应该在任何环境中都能够重复运行,结果一致。它不应该依赖于外部状态,或者因为外部因素的变化导致不一致的结果。
  1. 清晰的断言(Clear Assertions)
  • 测试的断言应该清晰并且明确表达测试目标。每个断言应该能够简单地表明预期行为和实际行为的差异。
  1. 小范围的测试(Small Scope)
  • 单元测试的范围应该足够小,只测试一个方法或功能,避免测试过多的代码逻辑。大范围的测试应该拆分为多个小范围的测试。
  1. 不依赖外部服务(No External Dependencies)
  • 单元测试应该避免与外部系统(如数据库、网络、文件系统等)交互。如果测试依赖外部系统,可能会受到网络延迟或系统状态不一致的影响,导致测试结果不稳定。
  1. 易于理解和维护(Readable and Maintainable)
  • 测试代码应该清晰易懂,避免复杂的逻辑。良好的测试代码应该能够清楚地表达测试的意图,让开发人员和测试人员可以轻松理解。
  1. 处理异常情况(Test Edge Cases and Errors)
  • 单元测试不仅需要覆盖正常情况,还需要处理异常情况和边界条件。测试代码应该考虑所有可能的输入和输出情况。
  1. 保持无副作用(No Side Effects)
  • 单元测试应该是“幂等”的,这意味着多次执行同一个测试应该产生相同的结果,且不应修改外部系统的状态。

2.2实际应用

func TestGetFileUrl(t *testing.T) {
    const basePath = "http://test-url"
    const filepath = "/filepath"

    type testCase struct {
        name           string
        expectedResult interface{}
    }

    expectedResult := basePath + utils.UriEncode(filePath) + "?id=newUrl"

    testCases := []testCase{
        {
            name:           "GetFileSuccessfully",
            expectedResult: expectedResult,
        },
    }

    req := &like.GetPopularRank{Filepath: filePath}
    defer mockey.UnPatchAll()

    for _, tc := range testCases {
        mockey.PatchConvey(tc.name, t, func() {
            mockOSSClient := new(oss.Client)
            fileService := NewFileService(context.Background(), mockOSSClient)

            mockey.Mock(oss.GetDownloadUrl).To(func(uri string) (string, error) {
                return expectedResult, nil
            }).Build()

            result, err := fileService.GetFileUrl(req)
            assert.Nil(t, err)
            assert.Equal(t, tc.expectedResult, result)
        })
    }
}

对于handler的测试:
发送请求

func PerformRequest(engine *route.Engine, method, url string, body *Body, headers ...Header) *ResponseRecorder

Hertz提供了此函数用来在没有网络传输的情况下向指定 engine 发送构造好的请求。
接收响应

resp := ut.PerformRequest(router, consts.MethodGet, tc.Url, nil)
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, tc.ExpectedResult, string(resp.Result().Body()))

对测试结果的断言,主要在状态码和响应体(其他如有需要也可以加上ContentType)上

3.遇到的问题

  • mock后报错mock失败: mock时没有依据原函数类型结构来写或没使用Build()
  • mock需要禁用内联和编译优化,但如何禁用内联和编译优化呢?
    命令行:go test -gcflags="all=-l -N" -v ./...
    Goland:在 运行/调试配置 > Go工具实参 对话框中填写 -gcflags="all=-l -N"

4.总结

通过单元测试的学习实践,我意识到单元测试能够帮助我们在早期发现代码中的问题,避免在后期进行大规模的调试。这种“防患于未然”的理念让我在编写代码时更加谨慎,也更加注重代码的健壮性。在实践中,我也遇到了一些挑战。例如,如何确保测试的独立性和可重复性,如何处理测试与实际环境之间的差异等。未来,我计划将这些知识应用到更多的项目中,不仅在单元测试方面,还要结合集成测试和系统测试,制定全面的测试策略。我相信,通过持续的学习和实践,我能够在软件开发中更加游刃有余,编写出更高质量的代码

参考

https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/unit-test/
https://gin-gonic.com/zh-cn/docs/testing/

...全文
82 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

109

社区成员

发帖
与我相关
我的任务
社区描述
202401_CS_SE_FZU
软件工程 高校
社区管理员
  • FZU_SE_TeacherL
  • 言1837
  • 防震水泥
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧