首页 > 其他分享 >关于单元测试的一些思考

关于单元测试的一些思考

时间:2023-07-14 18:22:21浏览次数:36  
标签:单测 思考 开发人员 Spring 单元测试 关于 测试 编写

单元测试作为软件质量的重要一环,往往在整个开发流程中被大多数开发人员所忽略,本文旨在分析如何写好单元测试并探索一些测试驱动开发的应用。

单元测试原则

在写单元测试前,先要明确什么是单元测试,单元测试的原则是什么?明确这些问题前不妨先参考一下前人总结的单元测试First原则。

v2-5b52200ac224ee0a6781ab11ff3f9bfd_r

在工作过程中经常见到一些无效的单测,通常是启动Spring容器、连接数据库、调用方法,最后控制台输出结果,这种并不能称之为有效的单测。

@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloServiceTest {
 
    @Autowired
    private UserService userService;
    @Test
    public void addUserTest() {
        AddUserRequest addUserRequest = new AddUserRequest("zhangsan", "18865899858");
        ResultDTO<Long> addResult = userService.addUser(addUserRequest);
        System.out.println(addResult);
    }
}

上面使用Spring Boot Test实现了常见的单元测试,尽管在某些情况下使用Spring框架可以方便地进行单元测试,但依赖Spring的单元测试也存在一些潜在的坏处:

  1. 复杂性增加:依赖Spring框架进行单元测试会引入更多的复杂性。Spring本身是一个庞大的框架,包含了许多功能和组件,这可能使得测试用例变得更加复杂和难以理解。
  2. 启动时间延长:由于Spring框架需要初始化和加载各种组件、上下文等,因此依赖它的单元测试通常需要较长的启动时间。这可能导致测试套件的执行变慢,影响开发人员的迭代速度。
  3. 可靠性下降:依赖Spring的单元测试对外部环境和配置有一定的依赖。如果测试运行时的配置与实际生产环境不同,就可能导致测试结果不准确或测试用例无法正确执行。
  4. 难以调试和定位问题:当依赖Spring进行单元测试时,由于框架的封装和复杂性,测试失败或出现问题时定位和调试问题可能会更困难。这会增加调试时间和精力。
  5. 限制可移植性:如果测试依赖于Spring框架的特定功能或组件,那么这些测试可能在没有Spring环境的其他场景中无法运行。这限制了测试的可移植性和共享性。

回归到单元测试的目的,我们需要用单元测试来验证数据库或redis这些系统依赖的操作吗?也许并不是,单元测试更重要是对于我们业务代码逻辑正确与否的测试。单元测试应该专注于被测试单元的逻辑,尽量减少外部依赖,而集成测试和端到端测试则更适合验证整个系统的功能和交互。

单元测试应该尽量避免对Spring的依赖,但在某些情况下,使用Spring测试框架进行集成测试或端到端测试仍然是有意义的。这样的测试可以验证整个系统的交互和集成,并确保各个组件能够正确协同工作。因此,在选择测试策略时,需要根据具体情况进行权衡。

开发人员为什么不愿意写单元测试?

下面总结了一些开发人员不愿意编写单元测试的常见理由:

  1. 时间压力:开发周期紧张,任务繁重,缺乏足够的时间来编写单元测试。
  2. 浪费时间:认为编写单元测试是浪费时间,更愿意将时间用于功能开发。
  3. 公司文化:领导和公司对单元测试的重要性和价值没有充分认知,不重视单元测试。
  4. 项目管理优先:项目管理者关注进度和交付,往往忽视了单元测试所带来的好处。
  5. 不清楚如何编写有效的单元测试:缺乏对编写高质量单元测试的具体要求和实践经验。
  6. 工具和技术的不熟悉:缺乏熟悉和掌握单元测试所需的工具、框架和方法。
  7. 维护成本和持续迭代:单元测试维护成本高,随着需求的变化和系统的迭代,单元测试也需要不断地调整和维护。

许多开发人员对编写单元测试持抵触态度,主要基于以下三个原因:

  1. 主观意愿:某些开发人员可能没有养成编写单元测试的习惯,或者他们认为单元测试是额外的工作,会增加开发时间和精力。这种主观意愿问题可能源于个人偏好、经验不足或对测试价值的理解不够。
  2. 外部环境限制:有时,开发人员可能处于一些客观条件下,使得编写单元测试变得困难或不可行。这可能包括紧迫的项目截止日期、缺乏适当的测试工具或资源,或者组织文化不支持单元测试等。
  3. 缺乏知识和技能:一些开发人员可能不清楚如何编写有效的单元测试,缺乏相关的培训或经验。他们可能不熟悉测试框架、工具或最佳实践,并且不确定如何设计和覆盖各种测试用例。

开发人员不愿意编写单元测试的主要原因,涵盖了主观和客观方面以及技能层面的问题。解决这些原因也许可以帮助我们更好地理解和解决开发人员在编写单元测试方面的挑战,通过培训、资源支持和文化的引导来推动更广泛的单元测试实践。

测试驱动开发(DDD)

测试驱动开发是软件开发过程中的一种方法,其倡导先写测试程序,然后编码实现功能而得名。从实践来看,TDD可能只是一种理想状态,完全遵守TDD原则难度非常大,毕竟完成需求总是第一目的,而且需求总是不断变化的。

边开发边写单测:先写少量功能,紧接着写单测,重复这个过程,直到完成功能的开发

开发后写单测:这种方式往往效果是最差的,已完成的代码往往可测性比较差,而且补单测时很容易顺着当前实现的思路去测试代码,容易忽略实际的逻辑,导致单侧无效,最后开发后补单测往往会导致单测的场景覆盖率比较差。

TDD虽然实践起来比较困难,但是它的思路还是值得我们借鉴,在进行功能设计前就要考虑到代码的可测性,虽然没有提前将单测写完,但是要考量单测的覆盖场景,这样会单测会比较高效。

另一个方面,在分工合作的场景下,特别是在微服务架构中,使用单元测试和模拟(Mock)的方式非常适合验证自己的业务代码是否正确,尤其是当依赖的其他服务接口尚未完成或不稳定时。它允许团队以独立、快速、灵活和可靠的方式开发和测试业务功能,同时降低对其他服务的依赖和耦合。

标签:单测,思考,开发人员,Spring,单元测试,关于,测试,编写
From: https://www.cnblogs.com/wrxiang/p/17554717.html

相关文章

  • 关于x79itx主板的简单测试
    主板某宝的精粤x79itxoem主板,原生x79芯片。问了客服说有一个stat3.0和一个前置usb3.0,好像原生x79不支持usb3.0吧。主板图片:测试配件本次测试并未修改任何bios选项!硬盘:致钛PC005512g、致钛SC001256g内存:三星recc186616g*2CPU:e52660v2显卡:gt6101g电源:惠普拆机320......
  • 单元测试与Mock
    JUnit4以下是JUnit4中一些常用的类和注解的相关API:注解:@Test:标记测试方法。@Before:在每个测试方法之前执行的方法。@After:在每个测试方法之后执行的方法。@BeforeClass:在整个测试类之前执行的静态方法。@AfterClass:在整个测试类之后执行的静态方法。@RunWith:指定自定......
  • 喜欢的诗句摘抄(关于形容人美丽的)
    1.形容人美丽的诗句:众里嫣然通一顾,人间颜色如尘土。---王国维的《蝶恋花·窈窕燕姬年十五》解析:她在人群中回眸一笑,可以让其它女人失去颜色。兰有秀兮菊有芳,怀佳人兮不能忘。---刘彻的《秋风辞》解析:她在人群中回眸一笑,可以让其它女人失去颜色。解析:秀美的是兰花呀,芳香......
  • 【javascript】关于文件下载
    通常在a标签href属性后加上请求下载文件的地址,页面点击即可下载,该种方式是交由浏览器去下载,但是无法监听下载进度若通过AJAX请求,则需要对其进行解析,通常将数据转为blob,然后模拟a标签点击事件,但是此方法如果文件过大,接口调用时超出ajax的timeout时长,会下载失败......
  • 关于scrapy框架的学习
    最近打算参加一个爬虫比赛,特来研究爬虫,在掌握了爬虫的基本实现后,我们需要用一个更高效的方式来写爬虫这个时候便用到了爬虫框架scrapyscrapy是什么?Scrapy是一个应用程序框架,用于对网站进行爬行和提取结构化数据,这些结构化数据可用于各种有用的应用程序,如数据挖掘、信息处......
  • 关于.properties文件使用中文出现乱码问题,及在eclipse和idea中如何查看
    最近修改一个老java项目(使用jdk1.6),发现在eclipse中打开.properties文件,有中文字符的都变成了类似 \u901a\这样的字符,查看文件编码已经是UTF-8,即使用idea打开也是如此,而且idea文件编码是灰色,无法修改;搜索了一番,终于找到了相应的查看方法,其实就是编辑器给你再转回汉字......
  • 你需要知道关于C语言指针的一切
    EverythingyouneedtoknowaboutpointersinC你需要知道关于C语言指针的一切指针的定义指针是内存地址。(嗯,简短的段落。)开始假设你声明一个名为foo的变量。foo;这个变量占用一些内存。在当前主流的Intel处理器上,它占用四个字节的内存(因为int是四个字节宽)。现在......
  • 关于Java类加载器的一些理解
    Java中,每个类都可以获得对应自己类的Class对象,这是因为Object类中有publicfinalnativegetClass()方法,Class对象是由类加载器根据类字节码生成的,是反射机制必不可少的部分。类加载器中,主要的方法有protectedClassloadClass(Stringname,booleanresolve)和protectedClassf......
  • P5044 [IOI2018] meetings 会议 思考--zhengjun
    在NFLS模拟赛上遇到的,赛后订正过的。隔了蛮长时间的,总结一下。首先转化为笛卡尔树上后缀前缀的问题。然后考虑如何转移,发现转移形如\(f(x)=\min\{f(x)+C,kx+b\}\)的形式。可以直接线段树维护每个点的最优直线,在update的时候:如果\(f(x)+C\lekx+b\)恒成立(左右......
  • java单元测试入参数不同出参不同怎么做
    项目方案-Java单元测试入参不同出参不同的处理背景和问题在软件开发过程中,我们经常需要编写单元测试来保证代码的正确性。但是,在某些情况下,相同的测试方法可能会根据不同的输入参数而产生不同的输出结果。这给单元测试的编写带来了一定的挑战,因为我们需要针对不同的参数情况编......