学习Java?你得先明白测试优先!

本文介绍了软件测试的重要性和类型,包括静态和动态测试,强调了测试用例的编写、测试优先编程原则,如TDD,以及单元测试和JUnit的使用。文章还讨论了如何选择测试用例,如等效划分和边界值分析,并提到了代码覆盖率和自动化测试与回归测试的概念。
摘要由CSDN通过智能技术生成

(注:本文思想主要来源于哈工大计算学部王忠杰教授的《软件构造》)

一、 软件测试

        软件测试是一项调查,目的是向涉众提供有关被测产品或服务质量的信息。也就是说,软件测试是提高软件质量的重要手段。它是执行程序或应用程序的过程,目的是寻找错误(错误或其他缺陷),并验证软件产品是否适合使用。也涉及到通过执行软件组件来评估一个或多个令人感兴趣的属性。

        测试不同于调试。测试是发现错误,而调试是真正地去改正错误。

        再好的软件开发者也无法保证百分百的正确率。测试的目标与其他开发活动的目标背道而驰,目标是找到错误。但是,测试永远不能完全证明没有错误。一个好的测试兼具能发现错误,不太复杂也不太简单,不冗余的这些特点。软件测试可以有以下常见的类型划分:

         静态测试和动态测试的区别用通俗的话来讲,就是用放大镜看一个计划和真正执行一个计划的区别。

        静态测试在不实际执行程序的情况下执行。静态测试通常是隐式的,如校对,加上编程工具/文本编辑器检查源代码结构或编译器(预编译器)检查语法和数据流作为静态程序分析。评审、演练或检查均被称为静态测试。

        动态测试描述了对代码动态行为的测试,它实际上是用一组给定的测试用例执行已编程的代码。动态测试可以在程序100%完成之前开始,以便测试特定的代码部分,并应用于离散的功能或模块。其典型的技术是要么使用存根/驱动程序,要么在调试器环境中执行。  

        白盒测试通过查看源代码来测试程序的内部结构或工作方式。黑盒测试将软件视为一个“黑盒”,在不了解内部实现、不查看源代码的情况下检查功能。

        为什么软件测试有难度?详尽的测试是不可行的:可能的测试用例的空间通常太大,无法详尽地覆盖。而随意的测试(“只是尝试一下,看看它是否有效”)不太可能发现错误,除非程序如此错误,以至于任意选择的输入更有可能失败而不是成功。随机或统计测试并不适用于软件。尽管其他工程学科可以测试小的随机样本(例如生产的硬盘的1%),并推断整个生产批次的不良率,但软件和这些产品有很大差异。另外,软件行为在可能输入的空间中不连续和离散地变化。堆栈溢出、内存不足错误和许多错误往往会突然发生,并且总是以相同的方式发生,而不是以概率变化发生。这给软件测试依据的选取造成了很多麻烦。也就是这些,让软件的测试充满了不规律的地方。

        学着对你的代码暴力些,用“爱之深,责之切”的态度找它的错误。这才是一个程序员应具备的素养。

 二、 软件测试

        测试用例是一组测试输入、执行条件和预期结果。例如,测试用例={测试输入+执行条件+预期结果}。测试用例是为特定的目标而开发的,例如执行特定的程序路径或验证与特定需求的遵从性。换句话说,测试用例可以是您向程序提出的一个问题。运行测试的目的是获取信息,例如程序是否通过测试。

三、测试优先的编程

        请在编写代码之前先编写测试!不要把测试留到最后,当你有一大堆未经验证的代码时。把测试留到最后只会让调试变得更长、更痛苦,因为bug可能在代码中的任何地方。而且,试着编写测试可以在你浪费时间编写一个有bug的规约(方法的规约是对方法行为的描述。包括参数的类型、返回值的类型、约束和它们之间的关系)。实现之前,尽早发现这些问题。

        例如,测试驱动开发(TDD)是一种依赖于非常短的开发周期的重复的开发过程:将需求转化为非常具体的测试用例,然后对软件进行改进以通过新的测试。

 三、单元测试

        单元测试将验证工作集中在软件设计的最小单元——软件组件或模块上。单独测试模块可以大大简化调试。当模块的单元测试失败时,您可以更确信错误是在该模块中发现的,而不是在程序的任何地方。同时,对于设计信息的回顾为建立可能发现错误的测试用例提供了指导。每个测试用例都应该与一组预期的结果相结合。

        因为组件不是一个独立的程序,所以必须经常为每个单元测试开发驱动程序和/或存根软件。驱动程序是一个“主程序”,它接受测试用例数据,将这些数据传递给组件(待测试),并打印相关的结果。存根用来替换从属于被测试组件的模块(由组件调用),存根使用从属模块的接口,可以进行最少的数据操作,打印条目验证,并将控制权返回给正在进行测试的模块。

四、使用JUnit进行自动化单元测试

        JUnit是一个被广泛采用的Java单元测试框架。 单元测试方法通常包含对被测试模块的一个或多个调用,然后使用断言方法(如assertEquals、assertTrue和assertFalse)检查结果。

/**
	 * Tests calculatePolygonSidesFromAngle.
	 */
	@Test
	public void calculatePolygonSidesFromAngleTest() {
		assertEquals(3, TurtleSoup.calculatePolygonSidesFromAngle(60.0));//期望值为3 后面为实际值
		assertEquals(7, TurtleSoup.calculatePolygonSidesFromAngle(128.57));
		assertEquals(5, TurtleSoup.calculatePolygonSidesFromAngle(108.0));

	}

	/**
	 * Tests calculateBearingToPoint.
	 */
	@Test
	public void calculateBearingToPointTest() {
		assertEquals(0.0, TurtleSoup.calculateBearingToPoint(0.0, 0, 0, 0, 1), 0.001);
		assertEquals(90.0, TurtleSoup.calculateBearingToPoint(0.0, 0, 0, 1, 0), 0.001);
		assertEquals(359.0, TurtleSoup.calculateBearingToPoint(1.0, 4, 5, 4, 6), 0.001);
	}

        更多断言方法请点击以下链接查阅。 

Assertions · junit-team/junit4 Wiki · GitHubA programmer-oriented testing framework for Java. Contribute to junit-team/junit4 development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/junit-team/junit4/wiki/Assertions        JUnit测试组织有一个源目录和一个测试目录。

五、通过划分选择测试用例 

        等效划分是一种测试方法,它将程序的输入域划分为可以从中导出测试用例的等价类, 每个等价类代表着对输入约束加以满足/违反的有效/无效数据的集合,再从等价类中导出测试用例。 

        基于的假设:相似的输入,将会展示相似的行为。故可从每个等价类中选一个代表作为测试用例即可。这种方法通过选择不同的测试用例,并迫使测试探索随机测试可能无法到达的部分输入空间,从而最好地利用有限的测试资源,也降低了测试用例数量。

        等价类可以根据以下的指南定义。1.如果输入条件指定了一个范围,则定义一个有效的和两个无效的等价类。2.如果输入条件需要特定的值,则定义一个有效等价类和一个无效等价类。3.如果输入条件指定了集合的成员,则定义一个有效等价类和一个无效等价类。4.如果输入条件是布尔值,则定义一个有效类和一个无效类。

 如:输入的学号no需满足的条件:

•长度为10位:10、>10、<10

•以118开头:以此开头、以其他开头

•之后两位数应为03/36/37:03、36、37、其他

        或者对于BigInteger对象的乘法。BigInteger是Java库中内置的一个类,它可以表示任何大小的整数,不像基本类型int和long只有有限的范围。在考虑其输入输出的特殊情况(-1,0,1)以及输入输出的上限(绝对值更大一些的情况),得到以下二维平面上的划分。

六、在划分中包含边界 

        更多的错误发生在输入域的边界,而不是在“中心”。比如集合的第一个和最后一个元素。边界值分析(Boundary Value Analysis, BVA)是一种基于边界值的测试用例选择方法。 

七、代码覆盖度

        代码覆盖率是一种度量,用于描述在特定测试套件运行时程序源代码执行的程度。 具有高代码覆盖率的程序,在测试期间执行了更多的源代码,这表明与具有低代码覆盖率的程序相比,它包含未检测到的软件错误的机会更低。

八、自动化测试和回归测试

        手工测试的代价太高,最好达到完全的自动化。自动化测试意味着自动运行测试并检查测试结果。一个好的测试框架,比如JUnit,可以帮助您构建自动化的测试套件。请注意,像JUnit这样的自动化测试框架使运行测试变得容易,但是您仍然必须自己想出好的测试用例。自动测试生成是一个难题,仍然是计算机科学研究的活跃课题。

        一旦实现了测试自动化,在修改代码时重新运行测试就非常重要了。在每次更改后运行所有测试称为回归测试。当bug出现时,立即为它编写一个引出它的测试用例,并立即将其添加到您的测试套件中。一旦你发现并修复了错误,你所有的测试用例都将通过,你将完成调试并对该错误进行回归测试。在实践中,自动化测试和回归测试几乎总是结合使用的。

九、记录测试策略

        单元测试策略是ADT设计的补充文档。当他人进行代码审查,以检查您的测试是否足够时,好的策略使其他开发人员理解您的测试。

  • 47
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值