首页 > 编程知识 正文

测评基本能力(功能测试需要学什么)

时间:2023-05-05 08:41:40 阅读:85066 作者:172

说到软件测试的4个字符,我想脑海里会浮现集成测试、系统测试、黑匣子测试、白匣子测试等,也许没想到会有单元测试。 对于大学正在学习软件工程的学生来说,你可能听过这四句话。 你可能也听说过工作多年的职场老鸟,但大多没有实际使用过。

大多数开发人员都忙于顺利开发手头的工作,没有将单元测试纳入工作范畴。 他们会说,我连功能开发都忙不过来,没有时间进行单元测试,而且还要写测试代码,那不是重复写代码功能吗? 但是,单元测试真的不值得花时间去做吗? 那是因为你可能不知道单元测试的投入产出比有多高。 简要介绍单元测试能给开发人员带来多少好处。

什么是单元测试

为什么要进行单元测试

不写单元测试的借口

主流的JUnit和TestNG

安卓上的单元测试

总结

什么是单元测试

单元测试本质上也是代码,与普通代码的区别在于它是验证代码正确性的代码。 很容易定义。 单元测试是开发人员编写的用于检测特定条件下目标代码正确性的代码。

软件开发天生复杂,谁也不能打包票说自己写的代码一点问题都没有。 或者不用测试就能保证代码正常工作。 你也许可以在这个执行路径上执行,但出乎意料地还有其他路径。 你一一验证过吗? 因此,为了保证程序的正确性必须严格测试我们的代码。

让我举个简单的例子。 例如,有一个包含add方法的计算系统。 操作是将两个数相加。

公共类计算器{

公共添加(内部注释器)

//只需将两个简单的数相加

返回一个注释者;

}

}

常规方法:编写此方法后,必须编写使用add方法的main函数,以验证add方法的正确性。 首先实例化Calculator类,然后调用add方法传递两个参数,如1和2。

然后,运行这个项目,看看结果是否为3。 3的话,表示我用这个方法写的没有错。 不做测试,可能继续开发后续功能。 否则,返回看看代码哪里错了,重新调试。 在某些情况下,如果肉眼还不知道代码哪里错了,请引入断点进行确认。 在此期间,大部分时间将花在断点、调试和执行上。

单元测试的方法:首先,利用JUnit测试框架(关于这个框架将在后面介绍),如下编写测试代码。

公共类计算器测试{

公共语音测试() throws执行{ }。

计算器计算器=新计算器(;

intsum=计算单元. add (1,2 );

assert.assertequals(3,和);

}

}

这里的CalculatorTest是对应于Calculator的测试类,这里的testAdd对应于add的测试方法,进行测试一般分为三个步骤。

设置。 一般要上new测试的课。 例如,计算器计算器=新计算器();

执行操作。 一般情况下,调用要测试的方法以获得执行结果。 intsum=计算单元. add (1,2 );

验证结果。 验证得到的结果和预期的一样。 assert.assertequals(3,和);

看到Assert这个关键字了吗? 这里可以理解为断言或期待值。 根据条目的值,不是用肉眼验证是否是自己想要的值,而是通过直接判断值是否相等来验证期待输出什么样的值,这样更具有客观性。

以上介绍的只是单元测试的一点点,它能给我们带来什么更多的好处?

为什么要做单元测试

通常,我们无论做什么工作都首先考虑其回报。 写代码就更不用说了。 如果单元测试不怎么起作用,谁也不想写无用的代码,那么单元测试到底能给我们带来什么好处呢? 如下所示。

便于后重构。 单元测试可以保障代码的重构。 重构代码后,如果单元测试全部运行通过,很大程度上表明这次的重构没有引入新的错误。 当然,这是基于完整有效的单元测试覆盖率。

优化设计。 通过创建单元测试,用户可以从调用方的角度观察和思考。 特别是使用TDD驱动开发的开发方式,使用者可以将程序设计为可调用、可测试,并断开软件内的连接。

文档记录。 单元测试是一个宝贵的文档,是展示函数和类如何使用的最佳文档。 此文档是可编译的、可执行的,并且始终与代码同步。

具有回归性。 自动化的单元测试可以避免代码回归,在代码编写完成后,可以随时随地快速运行测试,而不是在设备上部署代码后。 之后,手动覆盖各种执行路径很低效,浪费时间。

等等,我说了这个

么多优点,无非就是良好的接口设计、正确性、可回归、可测试、完善的调用文档、高内聚、低耦合,这些优点已经足以让我们对单元测试重视起来了,但是个人觉得还有更重要的原因。

首先,带来自信。在接手一个新的项目,或者说是参与一个新的项目开发时,往往这种情况是你半途参加进去的,你需要对已有的代码结构进行解读和理解,对于业务的理解,对于代码个中各个模块关系的理解。

如果一开始就理财出错,很可能修改后的代码会引起更多的BUG出现,到那时候又需要修复更多的BUG,改了一个地方,很有可能会莫名其妙地影响另外一个地方,这种现象是很常见的。

还有一种情况,假设你修改的功能没问题,但是需要去测试验证,在测试的时候就需要考虑这个功能点它原有的测试路径有哪些,又需要一一去验证功能路径,以证明本次修改对于已存在的功能点不造成影响。这其中就存在着很大的时间成本,导致效率不高。

那是否存在着这么一种方式,我需要修改我想改动的地方,不需要关心修改完之后它所造成的影响,也不需要关心它的测试回归性,有,此时就是单元测试登场的时候。写单元测试代码,可以让我自己写的代码足够自信,它是经得起考验的。

其次,更快反馈。对于有一定编程经验的开发人员来说,当他拿到一个新需求的时候,首先想到的不是动手 Coding ,而是会先想想代码的结构,有些类,数据结构该是如何,然后才开始敲代码。

如果没有单元测试,一般流程基本是这个模块功能全部写完才开始测试,比如利用 MVP 架构的功能。一般都是开始 Model 模块,然后完善 Presenter 模块,最后写 View 模块,等这几个模块都写完了,再把 APP 跑起来,验证自己写的功能模块是否符合需求,没有符合则继续回去修改代码,这中间需要花费很长的时间才能知道当下自己写的代码是否符合要求,是否正确。

那有没有一种即时反馈的方式呢,有,写单元测试即可,暴躁的热狗写完一个函数,马上就匹配一个单元测试函数,这样即写即测的方式可以保证你当场写的代码马上进行修改,测试通过一个,就表示完成一个小的功能点,最后,把函数组装起来,就是我们想要大的功能点。

最后,节约时间。对于 Android 开发来说,一遍一遍的运行 APP ,然后执行相应的用户操作,看界面是否正确的显示,通过这种方式来测试功能,其实是非常浪费时间,而且效率不高,而用单元测试,可以几乎不用打开 APP 来执行,当然有些需要一些资源文件的是需要 APP 运行条件,绝大部分的功能在单元测试阶段就能验证完毕,那么速度就相对快很多。此外,单元测试还能帮忙减少 BUG ,从而减少调试 BUG 的时间,一些低级犯的错误在单元测试阶段就能避免掉。

不写单元测试借口

很多开发人员不写单元测试,最重要的一个原因是他们并不知道单元测试能够带来什么好处,甚至根本不了解单元测试这个词,那自然就像平行线般与之毫无交集。还有一个比较重要的原因是一些开发人员的编程思想还处在一个相对初级的阶段,开发软件只管实现功能,什么高内聚、低耦合、重构、设计、可测试等认为太过专业,对于这些名词以及意义还不了解,这自然不会考虑使用了。还有一些非思想层面的理由,如下:

单元测试太花时间了。软件开发工作那么忙,代码都写不完哪有时间写单元测试。这可能是开发人员用的最多的借口,从某些方面来说,这不能算借口,因为很多开发人员确实在工作上投入的时间特别多。但真的是这样的吗,你有没有想过,导致加班的原因也许就是花了太多时间在手动测试、调试程序上:或许你没有考虑到灵活性与设计,使得在需求发生变更时你需要花很多时间在复杂的代码堆中完成特定的功能,而这些修改又可能引入新的 BUG ,又将导致你需要进行耗时的手动测试、调试等等,如此反复,代码将变得越来越乱,越来越难以维护,最终导致无休止的加班。

测试不是我的工作。测试确实不是开发人员的工作,但单元测试确实是开发人员的工作,测试包含很多种,而只有单元测试是开发人员的工作范畴。开发人员为应用编写代码,那么自然需要保证代码的正确性,而单元测试正是这种保证代码正确性的白盒测试,也就是在了解代码内部结构逻辑的情况下进行有目的的测试,既然说到了解代码,那么开发者自然是最权威的人。因此,编写单元测试并且为测试人员提交正确的代码进行其他测试是开发人员的职责所在。

代码都编译通过了,还测什么。一般来说,这是一个不会放在嘴上但可能藏在心里的借口。代码编译通过只能说你写的代码符合语法要求,并不代表能保证正确性。

代码原来就没有单元测试,并且难以测试。这个问题基本是接受和维护别人开发的代码,而原来的代码本身就没有单元测试了,再加入如果代码的耦合性较高,那么就更难以为这些代码写单元测试。此时正是你了解代码时候,首先为能够测试的部分添加单元测试,保证这些可测试的部分不会被污染,然后在对代码有足够的了解之后再对代码进行重构,降低代码的耦合性,并且慢慢补充测试用例,使得代码的耦合性、可测试性慢慢建立起来。

主流框架 JUnit 和 TestNG

JUnit 是一个 Java 语言的单元测试框架,它是 xUnit 单元测试架构体系的一个实例,用于编写和运行可重复的测试。它包括以下特性:

用于测试期望结果的断言(Assertion)

用于共享共同测试数据的测试工具

用于方便的组织和运行测试的测试套件

图形和文本的测试运行器

TestNG 是一个测试框架,其灵感来自 JUnit 和 NUnit ,但引入了一些新的功能,使其功能更强大,使用更方便。TestNG 消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。 因为它在很大程度上借鉴了Java注解( JDK5.0 引入的)来定义测试,它也可以显示如何使用这个新功能在真实的Java语言生产环境中。

特点如下:

注解

TestNG 使用 Java 和面向对象的功能

支持综合类测试(例如,默认情况下,不用创建一个新的测试每个测试方法的类的实例)

独立的编译时测试代码和运行时配置/数据信息

灵活的运行时配置

主要介绍“测试组”。当编译测试,只要要求 TestNG 运行所有的“前端”的测试,或“快”,“慢”,“数据库”等

支持依赖测试方法,并行测试,负载测试,局部故障

灵活的插件 API

支持多线程测试

Android 中的单元测试

因为 JUnit 测试框架是基于 Java 语言,当然 Android 开发也是基于 Java 语言,所以在 Android 中我们可以用 Junit4 单元测试框架进行回归测试,但同时,Google 也提供了一个 AndroidJUnit4 测试框架,看名字就知道它是基于 JUnit 4 框架适合在 Android 环境中做单元测试。

那么,AndroidJUnit4 和 Junit4 有什么区别呢?很大一个区别在于:

AndroidJUnit4 测试可以在真机的环境下进行。比如你要测文件读取SD卡,或者操作 SqlLite 数据库,这些条件只有在真机上才有的,此时你用 AndroidJUnit4 框架测试,可以直接跑起来用真实的环境做相应的单元测试。

JUnit4 测试是运行在工程项目中,也就是在编译阶段。此时如果想要模拟 Android 环境,比如我想用 JUnit4 来测试 Activity 类,那么就需要引用第三方库来支持,引用 Mockito 和 Robolectric 框架来模拟 Android 环境进行相应的单元测试。

所以何时用 AndroidJUnit4 和 JUnit4 不同的框架进行单元测试,就看你待测试的方法前置条件是什么,然后做不同的选择。

小结

总的来说,单元测试不是集成测试,单元测试只是测试一个方法单元,不是测试一整个流程。集成测试是一种End To End的系统测试,测试相关模块集成在一起是否能够按照预期工作,一般都是接口或者功能层面的测试,可能会依赖很多系统因素,测试的代码逻辑一般比较复杂,运行时间会比较长,出错之后的修复成本高。

单元测试则是开发者在集成测试之前就已经进行自测过,同时呢,进行单元测试之后,对于某个方法的执行路径组合进行了一一验证,它只关注三个目标:

有明确的返回值。比如对某个函数进行单元测试,验证其返回值是否符合预期结果。

这个函数只改变其对象内部的一些属性或者状态,函数本身没有返回值,就验证它所改变的属性和状态。

一些函数没有返回值,也没有直接改变哪个值的状态,这就需要验证其行为,比如点击事件。

End.

如果对软件测试感兴趣,想了解更多的软件测试知识,请大家关注“51Testing软件测试网”头条号

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。