当前位置:   article > 正文

《软件测试52讲》学习笔记(一)_学习软件测试52讲的心得

学习软件测试52讲的心得

因为报了一个课程,记录一些自己觉得有用的东西,课程链接:https://time.geekbang.org/column/article/10150

一、开篇讲述

1、测试工程师要做好测试工作是不容易的,测试工程师也是一个重要的角色

2、原来的测试以功能为主,现在的测试以自动化为主;

3、熟练应用各种测试工具,并且了解这些工具背后的原来,以及根据各个不同的场景选择合适的工具;

4、因地制宜的了解、熟悉新的测试工具或者方法;

二、测试基础知识篇

  • 第一小节 你真的懂测试吗?从“用户登录”测试谈起

1、作为测试工程师,你的目标是要保证系统在各种应用场景下的功能是符合设计要求的,所以你需要考虑的测试用例就需要更多、更全面;

2、等价类划分方法,是将所有可能的输入数据划分成若干个子集,在每个子集中,如果任意一个输入数据对于揭露程序中潜在错误都具有同等效果,那么这样的子集就构成了一个等价类。后续只要从每个等价类中任意选取一个值进行测试,就可以用少量具有代表性的测试输入取得较好的测试覆盖结果。

3、边界值分析方法,是选取输入、输出的边界值进行测试。因为通常大量的软件错误是发生在输入或输出范围的边界上,所以需要对边界值进行重点测试,通常选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。

4、一个质量过硬的软件系统,除了显式功能性需求以外,其他的非功能性需求即隐式功能性需求也是极其关键的。显式功能性需求(Functional requirement)显式功能性需求(Functional requirement)的含义从字面上就可以很好地理解,指的是软件本身需要实现的具体功能;非功能性需求(Non-functional requirement):从软件测试的维度来看,非功能性需求主要涉及安全性、性能以及兼容性三大方面。

5、一个优秀的测试工程师必须具有很宽广的知识面,如果你不能对被测系统的设计有深入的理解、不明白安全攻击的基本原理、没有掌握性能测试的基本设计方法,很难设计出“有的放矢”的测试用例;

6、软件测试的用例设计是不可穷尽的,工程实践中难免受制于时间成本和经济成本,所以优秀的测试工程师需要兼顾缺陷风险和研发成本之间的平衡;


  • 第二小节 如何设计一个“好的”测试用例?

1、好的测试用例就像一张可以捞起全部池塘鱼与渔网,如果网好着,没有捞到鱼那么池塘就是没有鱼;

2、“好的”测试用例一定是一个完备的集合,它能够覆盖所有等价类以及各种边界值,而跟能否发现缺陷无关;

3、一个“好的”测试用例,必须具备以下三个特征:

  • 整体完备性: “好的”测试用例一定是一个完备的整体,是有效测试用例组成的集合,能够完全覆盖测试需求;
  • 等价类划分的准确性: 指的是对于每个等价类都能保证只要其中一个输入测试通过,其他输入也一定测试通过;
  • 等价类集合的完备性: 需要保证所有可能的边界值和边界条件都已经正确识别;

4、三种最常用的测试用例设计方法:

  • 等价类划分方法:我们只要从每个等价类中任意选取一个值进行测试,就可以用少量具有代表性的测试输入取得较好的测试覆盖结果,等价类划分方法的另一个关键点是要找出所有“无效等价类”
  • 边界值分析方法:边界值分析是对等价类划分的补充,你从工程实践经验中可以发现,大量的错误发生在输入输出的边界值上,所以需要对边界值进行重点测试,通常选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据
  • 错误推测方法:错误推测方法是指基于对被测试软件系统设计的理解、过往经验以及个人直觉,推测出软件可能存在的缺陷,从而有针对性地设计测试用例的方法。这个方法强调的是对被测试软件的需求理解以及设计实现的细节把握,当然还有个人的能力

5、如何才能设计出“好的”测试用例?

  • 在真实的工程实践中,不同的软件项目在研发生命周期的各个阶段都会有不同的测试类型:传统软件的开发阶段通常会有单元测试,软件模块集成阶段会有代码级集成测试,打包部署后会有面向终端用户的 GUI 测试;再比如,电商网站的测试会分为服务器端基于 API 的测试、中间件测试、前端 GUI 测试等
  • 对于每一种不同的测试类型,设计出“好的”测试用例的关注点和方法论可能会有很大的差异:有些可能采用黑盒方法,有些可能采用白盒方法,有些还会采用灰盒方法(比如,微服务架构中的测试),所以很难有一套放之四海而皆准的套路
  • 具体设计用例时,把握几点:

          1、从软件功能需求出发,全面地、无遗漏地识别出测试需求是至关重要的,这将直接关系到用例的测试覆盖率

          2、对于识别出的每个测试需求点,需要综合运用等价类划分、边界值分析和错误推测方法来全面地设计测试用例

6、用例设计的其他经验:

  • 只有深入理解被测试软件的架构,你才能设计出“有的放矢”的测试用例集,去发现系统边界以及系统集成上的潜在缺陷
  • 必须深入理解被测软件的设计与实现细节,深入理解软件内部的处理逻辑
  • 需要引入需求覆盖率和代码覆盖率来衡量测试执行的完备性,并以此为依据来找出遗漏的测试点

7、总结

  • 首先,你需要明白,“好的”测试用例一定是一个完备的集合,它能够覆盖所有等价类以及各种边界值,而能否发现软件缺陷并不是衡量测试用例好坏的标准;
  • 其次,设计测试用例的方法有很多种,但综合运用等价类划分、边界值分析和错误推测方法,可以满足绝大多数软件测试用例设计的需求
  • 再次,“好的”测试用例在设计时,需要从软件功能需求出发,全面地、无遗漏地识别出测试需求至关重要
  • 最后,如果想设计一个“好的”测试用例,你必须要深入理解被测软件的架构设计,深入软件内部的处理逻辑,需求覆盖率和代码覆盖率这两个指标可以帮你衡量测试执行的完备性

  • 第三小节 什么是单元测试?如何做好单元测试?

1、单元测试是什么:单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类;

2、如何做好单元测试?要做好单元测试,你首先必须弄清楚单元测试的对象是代码,以及代码的基本特征和产生错误的原因,然后你必须掌握单元测试的基本方法和主要技术手段,比如什么是驱动代码、桩代码和 Mock 代码等,通常包括以下几个方面:

  • 第一,代码的基本特征与产生错误的原因 || 要做到代码功能逻辑正确,必须做到分类正确并且完备无遗漏,同时每个分类的处理逻辑必须正确 || 在实际开发的过程中,开发工程师通常会做以下考虑:

             1、如果要实现正确的功能逻辑,会有哪几种正常的输入;

             2、是否有需要特殊处理的多种边界输入;

            3、各种潜在非法输入的可能性以及如何处理;

  • 第二,单元测试用例详解 || 单元测试的用例是一个“输入数据”和“预计输出”的集合;

2.1.1、对输入数据的见解”:如果你想当然的认为只有被测试函数的输入参数是“输入数据”的话,那就大错特错了

  • 被测试函数的输入参数;
  • 被测试函数内部需要读取的全局静态变量;
  • 被测试函数内部需要读取的成员变量;
  • 函数内部调用子函数获得的数据;
  • 函数内部调用子函数改写的数据;
  • 嵌入式系统中,在中断调用时改写的数据;

2.2.2、对预计输出的见解:如果没有明确的预计输出,那么测试本身就失去了意义。同样地,“预计输出” 绝对不是只有函数返回值这么简单,还应该包括函数执行完成后所改写的所有数据

  • 被测试函数的返回值;
  • 被测试函数的输出参数;
  • 被测试函数所改写的成员变量;
  • 被测试函数所改写的全局变量;
  • 被测试函数中进行的文件更新;
  • 被测试函数中进行的数据库更新;
  • 被测试函数中进行的消息队列更新

 

  • 第三,驱动代码,桩代码和 Mock 代码:驱动代码,桩代码和 Mock 代码,是单元测试中最常出现的三个名词。驱动代码是用来调用被测函数的,而桩代码和 Mock 代码是用来代替被测函数调用的真实代码的

1、驱动代码(Driver)指调用被测函数的代码,在单元测试过程中,驱动模块通常包括调用被测函数前的数据准备、调用被测函数以及验证相关结果三个步骤。驱动代码的结构,通常由单元测试的框架决定;

2、桩代码(Stub)是用来代替真实代码的临时代码。 比如,某个函数 A 的内部实现中调用了一个尚未实现的函数 B,为了对函数 A 的逻辑进行测试,那么就需要模拟一个函数 B,这个模拟的函数 B 的实现就是所谓的桩代码;

3、Mock 代码和桩代码的本质区别是:测试期待结果的验证(Assert and Expectiation);

4、桩代码的应用首先起到了隔离和补齐的作用,使被测代码能够独立编译、链接,并独立运行。同时,桩代码还具有控制被测函数执行路径的作用,编写桩代码通常需要遵守一下三个原则:

  • 桩函数要具有与原函数完全相同的原形,仅仅是内部实现不同,这样测试代码才能正确链接到桩函数;
  • 用于实现隔离和补齐的桩函数比较简单,只需保持原函数的声明,加一个空的实现,目的是通过编译链接;
  • 实现控制功能的桩函数是应用最广泛的,要根据测试用例的需要,输出合适的数据作为被测函数的内部输入;

3、实际项目中如何开展单元测试?

最后我要跟你聊一下,实际软件项目中如何开展单元测试?

3.1、并不是所有的代码都要进行单元测试,通常只有底层模块或者核心模块的测试中才会采用单元测试。

3.2、你需要确定单元测试框架的选型,这和开发语言直接相关。比如,Java 最常用的单元测试框架是 Junit 和 TestNG;C/C++ 最常用的单元测试框架是 CppTest 和 Parasoft C/C++test;框架选型完成后,你还需要对桩代码框架和 Mock 代码框架选型,选型的主要依据是开发所采用的具体技术栈。通常,单元测试框架、桩代码 /Mock 代码的选型工作由开发架构师和测试架构师共同决定。

3.3、为了能够衡量单元测试的代码覆盖率,通常你还需要引入计算代码覆盖率的工具。不同的语言会有不同的代码覆盖率统计工具,比如 Java 的 JaCoCo,JavaScript 的 Istanbul。在后续的文章中,我还会详细为你介绍代码覆盖率的内容。

3.4、最后你需要把单元测试执行、代码覆盖率统计和持续集成流水线做集成,以确保每次代码递交,都会自动触发单元测试,并在单元测试执行过程中自动统计代码覆盖率,最后以“单元测试通过率”和“代码覆盖率”为标准来决定本次代码递交是否能够被接受。

4、总结

4.1、代码要做到功能逻辑正确,必须做到分类正确并且完备无遗漏,同时每个分类的处理逻辑必须正确;

4.2、单元测试是对软件中的最小可测试单元在与软件其他部分相隔离的情况下进行的代码级测试;

4.3、桩代码起到了隔离和补齐的作用,使被测代码能够独立编译、链接,并运行。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/977333
推荐阅读
相关标签
  

闽ICP备14008679号