测试是一种与调试截然不同并且相互独立的活动,各自需要不同的技术.测试是一种检验你的软件中是否存在缺陷的系统过程.而调试这是一种跟踪造成缺陷的原因的过程.测试导致调试,调试导致测试,而修正又导致更多的测试(我们再次进行测试以严重修正时否有效). 在软件的整个开发过程中,要对各种不同的对象进行测试: A.大量的文档会经历一个测试阶段(常称为”审查”过程); B.实现规范的代码自然将在开发人员的计算机上进行测试; C.将对最终的产品进行测试. 理解产品应该如何运行,并确保产品的运行方式正确,同时也满足为其设立的任何质量标准,这些都是QA部门的职责.QA部门通常叫做公司的测试部门,就是专门负责产品测试的一群人.对于你的程序的质量是否达到了发行的要求,他们拥有最终的发言权. 测试并不能怎么不存在缺陷,而只能怎么存在缺陷.如果你的测试没有发现任何bug并不一定意味着不存在bug,而只是表示你还没有发现bug.不要因为通过了一组不xx的测试,就产生假的安全感. bug的成本会随着开发过程的进行日益增加,所以尽可能早一些(在软件开发期间或之前)开始测试代码非常重要.这种测试驱动型的开发方法在敏捷开发程序员中很流行.这种方法主张将测试作为一种核心的构造手段,即你在编写被测试的代码之前就开始编写测试它的代码这是一个关键点,并且将其加入到你的编程日常工作中至关重要. 测试分为: A. 单元测试,实际上描述的是对原子单元(即类或函数)的测试; B. 组件测试,单元测试的下一步,用于研制由一个或多个单元组成的完整组件的行为; C. 集成测试,对放入一个系统中的组件的组合进行测试,确保它们之间正确相连; D. 回归测试,对软件或其环境进行修正或修改之后重新进行的测试; E. 负载测试,可以发掘与系统的效率相关的问题,检测程序是否如预期是向上扩展的; F. 压力测试,在很短的时间内向代码跑出大量的数据,以观察代码会出现什么情况,通常与负载测试一样用于高可用性系统; G. 疲劳测试,与压力测试相似,但关注的焦点是使代码在较高的负载下运行一段很长的时间,以确定任何会在执行大量的操作之后出现的性能问题; H. 可用性测试,即把软件仿真显示世界的环境中,看看用户觉得怎么样. alpha或beta软件通常都向外界发布,由高级用户试用,前者一般开发以便较早地得到反馈和积累信心.alpha软件,{sg}”代码完成”阶段.也许仍然有很多bug,并且非常不可靠,但是已经可以很好地向你展示最终的产品是什么样的.beta软件经过alpha阶段之后,就基本上没有bug了,而只有很少残留问题.现在离最终的产品很接近了.beta测试一般会涉及现实世界的现场测试.候选版将通过检查和质量保证测试(验证).发布候选版(RC - Release Candidate. Gamma)是内部版本,通常只发往测试部门.如果alpha和beta版本要到外面的世界历险,那么他们也许会带有某种形式的限制(例如运行次数).发布候选版则是”纯”的版本,没有任何这种限制. alpha测试时,软件在一个自然设置状态下使用。开发者坐在用户旁,随时记下错误的情况和使用中的问题。这是在受控制的环境下进行的测试;Beta测试是由软件的多个用户在一个或多个用户的实际使用环境下进行的测试;与Alpha不同的是,Beta测试时开发者通常不在测试现场,Beta测试是在开发者无法控制的环境下进行的软件现场应用。说的通俗易懂点就是,这两种测试方法都是有用户来完成的测试。 黑盒测试也称为功能测试。这种测试会将实际的功能与期望的功能进行比较,测试人员并不知道代码的内部情况。代码的设计者和测试人员可以是相互独立的。黑盒测试并不关心代码的每一行是否都得到了测试,而只关心代码是否满足软件的规范,即如果没有清晰地规范和文档化的API,就很难设计黑盒测试。 白盒测试也被称为结构测试。则是一种涉及所有代码的方法。代码的每一行都要被系统仔细地检查,以确保其正确性。白盒测试可以使用静态的方法或动态的方法。静态测试不运行代码,而是对代码进行检查和逻辑审核,以确保它体现了一种有效地解决方案。动态测试将运行代码,并且会涉及到路径和分支测试,即尝试访问每一行代码,并执行每个分支决策。这也许要求对代码进行一些修改,以迫使控制沿特定的路径进行。与为所有的行为组合而涉及的测试用例相比,这样的修改可能会更容易些。白盒测试的工作量非常大,并且成本要远远高于黑盒测试,所以进行这种测试的机会也要少得多。 bug大概分为三类: A. 编译失败,编译失败很容易引起人们的注意(或者很少被忽略),并且一般都比较容易修正。你必须对它们进行处理,否则将无法运行程序。很多情况下,编译失败的原因就是一个愚蠢的语法错误或者一个简单的疏忽,也可能是由于makefile中的缺陷而造成的; B. 运行时崩溃,这种错误非常显而易见。你不能和无生命的程序争论。你也不能把崩溃说成是一个“功能”。当程序出现故障并崩溃时,你可以退后一步,开始着手调查程序出错的地方在哪里; C. 非预期的行为,这是真正难以处理的错误——你的程序并没有崩溃,而只是在准备跳下悬崖。它会突然间展现出错误的行为。 编程语言有很多种,每一种语言都有其自己的从源代码来构造可执行程序的过程。某些构造模型比其他的模型复杂,而各种模型都有自身的长处和短处。主要的构建机制有三种:解释型语言、编译型语言和字节编译型语言。 解释型语言编写的代码,不需要经历一个专门的构建阶段。在编写了ixie代码之后,你只需要告诉解释程序这些代码在哪里就可以了。解释程序将对指令进行实时的解析和澳洲。常见的解释型语言有Perl、JavaScript。大部分的面向对象语言都是解释型的,这主要是因为它们出现的时间都不长,而计算机已经变得比以前更加强大,可以以相当快的速度来运行解释程序。解释型语言的主要优势在于它们的开发速度。它没有任何中间编译阶段,可以快速的对每个更改进行测试。还可以获得平xx立性,因为大部分语言解释程序可以在许多不同平台运行。缺点是执行能力比同等的编译型程序慢得多。这是因为语言运行时对每条代码语句都进行读取、分析、解释和操作。脚本语言通常都是解释型的,由于非常能容忍有问题的代码(具有松散的语言规则和较弱的输入检查),并且避免了复杂的功能,所以这些语言都支持非常快速的开发周期。 编译型语言会使用一个构建工具链,将你的源代码文件转化为将在目标平台上本地执行的机器指令。大型项目的编译要经历几个阶段,每个源文件都会被编译为一个中间对象文件,然后再将这些对象文件链接到一个最终的可执行文件中。编译型应用程序的运行要比同等的解释型应用程序快得多。编译型语言的构建过程要比解释型程序复杂得多,所以出现故障的几率也要大得多。 字节编译型语言,结语解释型语言和编译型语言之间。它们会经历一个编译过程,但是不会生成本地的可执行程序。相反,它们会生成字节码文件。字节码是一种伪机器语言,可以由虚拟机来执行。Java和C#是常见的字节编译型语言。作为一种折衷方案,字节编译器继承了前两种方法的一些优点和缺点。字节码可以在任何虚拟机已移植到的平台上运行,这样就获得了可移植性。 优化技术主要分为两类:设计更改和代码更改。设计级的更改对性能造成的影响一般比代码级的调整更加复杂。与几行糟糕的源代码相比,低效的设计更能束缚程序的执行效率,所以设计修正(尽管更困难些)会带来更大的成效。 返回值和异常不是等效的错误报告机制。返回值等价于全局状态变量,因为这两种机制可以返回相同的原因代码信息(尽管状态变量更容易被忽略)。你可以编写出分别使用这两种方法,以相似的方式运行的代码。异常则是一种xx不同的机制。它们伴随着新的控制流,这与简单的原因代码非常不同。它们与语言以及程序运行时密切相关,虽然你可以通过手工编写传播错误的代码来模拟异常,但是你必须认真考虑以下事项: A.如何使用任意对象,而不只是整型的原因代码来表示错误; B. 支持异常的类层次结构,并提供通过基类捕获异常的能力; C. 通过任意函数(甚至那些不具有try/catch或throw语句的函数)来传播异常。 异常是在语言层面上事项的,xx不会干扰你的代码。手工编写的模拟机制则必须在每一点上管理可能的发生故障。每个函数都将被迫返回错误代码(即使它本身不会发生故障),以传播其他的错误信息。这需要代码具备极强的适应能力。 |