版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、编写更好的Java单元测试的七个技巧测试是开发的一个非常重要的方面,可以在很大程度上决定一个应用程序的命运。良好的测试可以在早期捕获导致应用程序崩溃的问题,但较差的测试往往总是导致故障和停机。作者:小峰来源:码农网|2016-12-13 10:06收藏分享测试是开发的一个非常重要的方面,可以在很大程度上决定一个应用程序的命运。 良好的测试可以在早期捕获导致应用程序崩溃的问题,但较差的测试往往总是导 致故障和停机。虽然有三种主要类型的软件测试: 单元测试,功能测试和集成测试,但是在这篇 博文中,我们将讨论开发人员级单元测试。 在我深入讲述具体细节之前,让我们 先来回顾一下这三种测试的详细内容。软
2、件开发测试的类型 单元测试用于测试各个代码组件, 并确保代码按照预期的方式工作。 单元测试由开发人员编写和执行。大多数情况下,使用JUnit 或 TestNG 之类的测试框架。测试用例通常是在方法级别写入并通过自动化执行。集成测试检查系统是否作为一个整体而工作。集成测试也由开发人员完成, 但不是测试单个组件,而是旨在跨组件测试。系统由许多单独的组件组成,如代码,数据库, Web 服务器等。集成测试能够发现如组件布线,网络访问,数据库问题等问题。功能测试通过将给定输入的结果与规范进行比较来检查每个功能是否正确实现。通常, 这不是在开发人员级别的。 功能测试由单独的测试团队执行。 测试用例基于规范
3、编写, 并且实际结果与预期结果进行比较。 有若干工具可用于自动化的功能测试,如 Selenium 和 QTP 。如前所述, 单元测试可帮助开发人员确定代码是否正常工作。 在这篇博文中, 我将提供在Java 中单元测试的有用提示。使用框架来用于单元测试Java 提供了若干用于单元测试的框架。 TestNG 和 JUnit 是最流行的测试框架。JUnit 和 TestNG 的一些重要功能:? 易于设置和运行。? 支持注释。? 允许忽略或分组并一起执行某些测试。? 支持参数化测试,即通过在运行时指定不同的值来运行单元测试。? 通过与构建工具,如 Ant , Maven 和 Gradle 集成来支持自
4、动化的测试执行。EasyMock 是一个模拟框架,是单元测试框架,如 JUnit 和 TestNG 的补充。EasyMock 本身不是一个完整的框架。 它只是添加了创建模拟对象以便于测试的能力。例如,我们想要测试的一个方法可以调用从数据库获取数据的 DAO 类。在这种情况下, EasyMock 可用于创建返回硬编码数据的 MockDAO 。这使我们能够轻松地测试我们意向的方法,而不必担心数据库访问。谨慎使用测试驱动开发!测试驱动开发 ( TDD ) 是一个软件开发过程, 在这过程中, 在开始任何编码之前,我们基于需求来编写测试。 由于还没有编码, 测试最初会失败。 然后写入最小量的代码以通过测
5、试。然后重构代码,直到被优化。目标是编写覆盖所有需求的测试, 而不是一开始就写代码, 却可能甚至都不能满足需求。 TDD 是伟大的,因为它导致简单的模块化代码,且易于维护。总体开发速度加快,容易发现缺陷。此外,单元测试被创建作为 TDD 方法的副产品。然而, TDD 可能不适合所有的情况。在设计复杂的项目中,专注于最简单的设计以便于通过测试用例, 而不提前思考可能会导致巨大的代码更改。 此外, TDD方法难以用于与遗留系统, GUI 应用程序或与数据库一起工作的应用程序交互的系统。另外,测试需要随着代码的改变而更新。因此,在决定采用 TDD 方法之前,应考虑上述因素,并应根据项目的性质采取措施
6、。测量代码覆盖率代码覆盖率衡量(以百分比表示)了在运行单元测试时执行的代码量。通常,高覆盖率的代码包含未检测到的错误的几率要低, 因为其更多的源代码在测试过程中被执行。测量代码覆盖率的一些最佳做法包括:? 使用代码覆盖工具,如 Clover , Corbetura , JaCoCo 或 Sonar 。使用工具可以提高测试质量,因为这些工具可以指出未经测试的代码区域,让你能够开发开发额外的测试来覆盖这些领域。? 每当写入新功能时,立即写新的测试覆盖。? 确保有测试用例覆盖代码的所有分支,即 if / else 语句。高代码覆盖不能保证测试是完美的,所以要小心!下面的 concat 方法接受布尔值
7、作为输入, 并且仅当布尔值为 true 时附加传递两个字符串:public String concat( boolean append, String a,String b) String result =null ;If (append) result = a + b;return result.toLowerCase();以下是上述方法的测试用例:Testpublic void testStringUtil() String result = stringUtil.concat( true , Hello , World ); System.out.println( Result is +
8、result);在这种情况下,执行测试的值为 true 。当测试执行时,它将通过。当代码覆盖率工具运行时,它将显示100% 的代码覆盖率,因为concat 方法中的所有代码 都被执行。 但是, 如果测试执行的值为 false , 则将抛出 NullPointerException 所以 100% 的代码覆盖率并不真正表明测试覆盖了所有场景, 也不能说明测试良好。尽可能将测试数据外部化在 JUnit4 之前,测试用例要运行的数据必须硬编码到测试用例中。这导致了限制,为了使用不同的数据运行测试,测试用例代码必须修改。但是, JUnit4 以及 TestNG 支持外部化测试数据, 以便可以针对不同的
9、数据集运行测试用例, 而 无需更改源代码。下面的MathChecker类有方法可以检查一个数字是否是奇数:public class MathChecker public Boolean isOdd( int n) if (n% 2 != 0) return true ; else return false ; TOC o 1-5 h z MathChecker 类的 TestNG 测试用例:public class MathCheckerTest private MathChecker checker;BeforeMethodpublic void beforeMethod() checker
10、 = new MathChecker();TestParameters (num ) public void isOdd( int num) System.out.println( Ru nning test for +num); Boolean result = checker.isOdd(num); Assert.assertEqu als(result, new Boolean( true );TestNG以下是 testng.xml (用于 TestNG 的配置文件),它具有要为其执行测试的数据:可以看出,在这种情况下,测试将执行两次,值3 和 7 各一次。除了通过XML配置文件指定测
11、试数据之外, 还可以通过DataProvider 注释在类中提供测试数据。JUnit与 TestNG 类似,测试数据也可以外部化用于 JUnit 。以下是与上述相同MathChecker 类的 JUnit 测试用例:RunWith (Parameterized. class )public class MathCheckerTest private int inputNumber;private Boolean expected;private MathChecker mathChecker;Beforepublic void setup()mathChecker = new MathChec
12、ker();/ Inject via constructorpublic MathCheckerTest( int inputNumber, Boolean expected) this .inputNumber = inputNumber;this .expected = expected;Parameterized .Parameterspublic static Collection getTestData() return Arrays.asList( new Object1,true ,2,false ,3,true ,4,false ,5,true );Testpublic voi
13、d testisOdd() System.out.println( Running test for: +inputNumber);assertEquals(mathChecker.isOdd(inputNumber), expected);可以看出,要对其执行测试的测试数据由 getTestData ()方法指定。此方法可以轻松地修改为从外部文件读取数据,而不是硬编码数据。5. 使用断言而不是Print 语句许多新手开发人员习惯于在每行代码之后编写 System.out.println 语句来验证代码是否正确执行。 这种做法常常扩展到单元测试, 从而导致测试代码变得杂乱。除了混乱, 这需要开
14、发人员手动干预去验证控制台上打印的输出, 以检查测试是否成功运行。更好的方法是使用自动指示测试结果的断言。下面的 StringUti 类是一个简单类, 有一个连接两个输入字符串并返回结果的方法:public class StringUtil 2.public String concat(String a,String b) return a + b;以下是上述方法的两个单元测试:Testpublic void testStringUtil_Bad() String result = stringUtil.concat( Hello , World );System.out.println( R
15、esult is +result);Testpublic void testStringUtil_Good() String result = stringUtil.concat( Hello , World );assertEquals( Hello World , result);testStringUtil_Bad 将始终传递,因为它没有断言。开发人员需要手动地在控制台验证测试的输出。如果方法返回错误的结果并且不需要开发人员干预,则testStringUtil_Good 将失败。构建具有确定性结果的测试一些方法不具有确定性结果, 即该方法的输出不是预先知道的, 并且每一次都可以改变。 例
16、如, 考虑以下代码, 它有一个复杂的函数和一个计算执行复杂函数所需时间(以毫秒为单位)的方法:public class DemoLogic private void veryComplexFunction()/This is a complex function that has a lot of database access and is ti me consuming/To demo this method, I am going to add a Thread.sleep for a rando m number of millisecondstry int time = ( int
17、) (Math.random()* 100);Thread.sleep(time); catch (InterruptedException e) / TODO Auto-generated catch blocke.printStackTrace();public long calculateTime()longtime =0;longbefore= System.currentTimeMillis();veryComplexFunction();longafter =System.currentTimeMillis();time = after -before;return time;在这
18、种情况下, 每次执行 calculateTime 方法时, 它将返回一个不同的值。 为该方法编写测试用例不会有任何用处, 因为该方法的输出是可变的。 因此, 测试方法将不能验证任何特定执行的输出。除了正面情景外,还要测试负面情景和边缘情况通常, 开发人员会花费大量的时间和精力编写测试用例, 以确保应用程序按预期工作。 然而, 测试负面测试用例也很重要。 负面测试用例指的是测试系统是否可以处理无效数据的测试用例。例如,考虑一个简单的函数,它能读取长度为 8的字母数字值,由用户键入。除了字母数字值,应测试以下负面测试用例:? 用户指定非字母数字值,如特殊字符。? 用户指定空值。? 用户指定大于或小于 8 个字符的值。类似地, 边界测试用例测试系统是否适用于极端值。 例如, 如果用户希望输入从1 到 100 的数字值,则 1 和 100 是边界值,对这些值进行
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年浙江省高三化学第4章有机化学基础习题
- 乐高早期考试试题及对应答案
- 关于流浪地球的面试问题及答案
- 名人名言测试题及详细答案
- 旅游初步承包合同
- 生物科技年度数据服务合同
- 公路个性化经销合同
- 电子商务专项加工合同
- 2026年河南省人教版高中生物必修第一册单元测试卷
- 2026年高职(数控技术)加工中心编程阶段测试题及答案
- DG-TJ08-2144-2025 公路养护工程质量检验评定标准
- 消防系统组成课件
- 护理风险防范管理制度
- 2024-2025学年湖北省武汉市部分重点中学高二上学期期末联考数学试卷(含答案)
- 公路改扩建工程安全风险辨识与防控表
- 公交司机未关车门保证书
- 高考物理一轮复习课件开学第一课
- GB/T 4706.15-2024家用和类似用途电器的安全第15部分:皮肤及毛发护理器具的特殊要求
- 《无损检测(第2版)》 课件第六章 声发射检测
- (高清版)DZT 0205-1999 地面γ能谱测量技术规程
- 胰腺癌的教学查房
评论
0/150
提交评论