静态白盒测试:检查设计和代码
静态是指不启动,白盒是指看内部代码。
静态白盒测试是在不执行软件的条件下有条理地仔细审查软件设计、体系结构和代码,从而找出软件缺陷的过程,有时称为结构化分析。
进行静态白盒测试的首要原因是尽早发现软件缺陷,以找出动态黑盒测试难以发现或隔离的软件缺陷。在开发过程初期让测试小组集中精力进行软件设计的审查非常有价值。
进行静态白盒测试的另外一个好处是,为黑盒测试员在接受软件进行测试时设计和应用测试用例提供思路。他们可能不必了解代码的细节,但是通过听审查评论,可以确定有问题或者容易产生软件缺陷的特性范围。
对于静态白盒测试最不幸的是常常不能善始善终。许多小组错误地认为这样耗时太多、费用太高、没有产出。这些都不对一与产 品接近完工时的有选择性的测试,找出、甚至找不出软件缺陷相比。问题在于人们一般认为程序员的任务是编写代码,而任何破坏代码编写效率的事情都会减缓开发过程。
所幸的是,形势变了。许多公司意识到早期测试的好处,并招聘和培训程序员和测试员进行白盒测试。这不是高新的学科(除非有人设计成这样),但是起步要求了解- -些基 本技术。假如有兴趣进一步深入, 那么机会是无限的。
正式审查
正式审查(formal review)就是进行静态白盒测试的过程。正式审查的含义很广,从两个程序员之间的简单交谈,到软件设计和代码的详细、严格检查均属于此过程。
正式审查有4个基本要素:
●确定问题。审查的目的是找出软件的问题一不仅 是出错的项目,还包括遗漏项目。全部的批评,应该直指代码或设计,而不是其设计实现者。参与者之间不应该相互指责。应把自我意识、个人情绪和敏感丟在一边。
●遵守规则。审查要遵守一套固定的规则,规则可能设定要审查的代码量(通常有数百行),花费多少时间(数小时),哪些内容要做评价等。其重要性在于参与者了解自己的角色、目标是什么。这有助于使审查进展得更加顺利。
●准备。每一个参与者都为审查做准备,并尽自己的力量。根据审查的类型,参与者可能扮演不同的角色。他们需要了解自己的责任和义务,并积极参与审查。在审查过程中找出的问题大部分是在准备期间发现的,而不是实际审查期间。
●编写报告。审查小组必须做出审查结果的书面总结报告,并使报告便于开发小组的成员使用。审查会议结果必须尽快告诉别人一诸如发现了多少问题,在哪里发现的,等等。
除了发现问题,坚持正式审查还有一些间接效果:
●交流。正式报告中未包含的信息得以交流。例如,黑盒测试员可以洞察问题所在。缺少经验的程序员可以向有经验的程序员学习新技术。管理员对于项目如何跟上进度更加心中有数。
●质量。程序员的代码经过逐个功能、逐行代码仔细复查,常常会使程序员变得更加仔细。这不是说他粗心大意一-只是说如果他知道自己的工作要被他人仔细审查,就会多花--些心思保证正确性。
●小组同志化。如果审查正确进行,就会建立软件测试员和程序员对双方技艺的相互尊重,并且更好地了解相互的工作及需求。
●解决方案。尽管是否讨论解决方案取决于审查的规则,但是解决方案应该用于处理严重问题。在审查的范围之外讨论解决方案也许更有效。这些间接好处虽然不可依赖,但是确实存在。在许多小组中,由于某种原因,成员之间自始至终独立工作。正式审查是把大家聚在--起讨论同一个项目问题的良机。
同事审查
召集小组成员进行初次正式审查最简单的方法是通过同事审查的方式。这是要求最低的正式方法,有时称为伙伴审查。这处方法大体类似于“如果你给我看你的,我也给你看我的”类型的讨论。
同事审查常常仅在编写代码或设计体系结构的程序员,以及充当审查者的其他一两个程序员和测试员之间进行。这个小团体只是在- -起审查代码,寻找问题和失误。为了保证审查的高效率(不致流于休息闲聊),所有的参与者要切实保证正式审查的4个关键要素:查找问题、遵守规则、审查准备和编写报告。因为同事审查是非正式的,这些要素常常大打折扣。即便如此,聚集起来讨论代码也能找出软件缺陷。
走查
走查(Walkthrough)是比同事审查更正规化的下-步。走查中编写代码的程序员向5人.小组或者其他程序员和测试员组成的小组做正式陈述。审查人员应该在审查之前接到软件拷贝,以便检查并编写备注和问题,在审查过程中提问。审查人员之中至少有一位资深程序员是很重要的。
陈述者逐行或者逐个功能地通读代码,解释代码为什么且如何工作。审查人员聆听叙述,提出有疑义的问题。由于公开陈述的参与人数要多于同事审查,因此,为审查做好准备和遵守规则是非常重要的。同样重要的是审查之后,表述者编写报告说明发现了哪些问题,计划如何解决发现的软件缺陷。
检验
检验(inspections)是最正式的审查类型,具有高度组织化,要求每一个参与者都接受训练。
检验与同事审查和走查的不同之处在于表述代码的人一表述者 (presenter) 或者宣读者(reader)一:不是原来的程序员。这就迫使他学习和了解要表述的材料,从而有可能在检验会议上提出不同的看法和解释。
其余的参与者称为检验员(inspector), 其职责是从不同的角度,例如用户、测试员或者产品支持人员的角度审查代码。这有助于从不同视角来审查产品,通常可以指出不同的软件缺陷。检查员甚至要担负着倒过来审查代码的责任一也就是说,从尾至头一一确保材料的彻底和完整。
有些检验员还同时被委任为会议协调员(moderator) 和会议记录员(recorder), 以保证检验过程遵守规则及审查有效进行。召开检验会议之后,检验员可能再次碰头讨论他们发现的不足之处,并与会议协调员共同准备一份书面报告,明确解决问题所必须重做的工作。然后程序员进行修改,由会议协调员验证修改结果。根据修改的范围和规模以及软件的关键程度,可能还需要进行重新检验,以便找到其余的软件缺陷。
检验经证实是所有软件交付内容中,特别是设计文档和代码中发现软件缺陷非常有效的方法,随着公司和产品开发小组发现其好处多多而日趋流行。
编码标准和规范
在正式审查中,检验员查找代码中的问题和缺漏。这些是典型的言行不一的软件缺陷,最佳方式是通过仔细代码分析发现一资 深程序员和测试员很善于此道。
还有一些问题是代码虽然可以正常运行,但是编写不符合某种标准或规范。这相当于写的东西可以被人理解和表述观点,但是不符合语言的语法和文法规则。标准是建立起来、经过修补和必须遵守的规则一做什 么和不做什么。规范是建议最佳做法、推荐更好的方式。标准没有例外情况,缺少结构化的放弃步骤。规范就要松一些。可以运行,甚至在测试中也表现稳定的一些软件,因为不符合某项标准而仍然被认为有问题,真是令人感到奇怪。然而,有三个重要的原因要坚持标准或规范:
●可靠性。事实证明按照某种标准或规范编写的代码比不这样做的代码更加可靠和安全。
●可读性/维护性。符合设备标准和规范的代码易于阅读、理解和维护。
●移植性。代码经常需要在不同的硬件中运行,或者使用不同的编译器编译。如果代码符合设备标准,迁移到另一个平台就会轻而易举,甚至完全没有障碍。
项目要求可能从严格遵守国家或国际标准的,到松散符合小组内部规范的,不一而足。
重要的是开发小组在编程过程中拥有标准和规范,并且这些标准和规范被正式审查验证。
通用代码审查清单
下面将介绍关于静态白盒测试时应该查找的问题。
数据引用错误
数据引用错误是指使用未经正确声明和初始化的变量、常量、数组、字符串或记录而导致的软件缺陷。
- 是否引用了未初始化的变量?查找遗漏之处与查找错误同等重要。
- 数组和字符串的下标是整数值吗?下标总是在数组和字符串长度范围之内吗?
- 在检索操作或者引用数组下标时是否包含“丢掉一个”这样的潜在错误?
- 是否在应该使用常量的地方使用了变量-- -例如在检查数组边界时?
- 变量是否被赋予不同类型的值?例如,无意中使代码为整形变量赋予一个浮点数值?
- 为引用的指针分配内存了吗?
- 一个数据结构是否在多个函数或者子程序中引用,在每一个引用中明确定义结构了吗?
数据声明错误
数据声明缺陷产生的原因是不正确地声明或使用变量和常量。
●所有变量都赋予正确的长度、类型和存储类了吗?例如,本应声明为字符串的变量声明为字符数组了吗?
●变量是否在声明的同时进行了初始化?是否正确初始化并与其类型一致?
●变量有相似的名称吗?这基本上不算软件缺陷,但有可能是程序中其他地方出现名称混淆的信息。
●存在声明过、但从未引用或者只引用过一次的变量吗?
●所有变量在特定模块中都显式声明了吗?如果没有,是否可以理解为该变量与更高级别的模块共享?
计算错误
计算或者运算错误实质上是糟糕的数学问题。计算无法得到预期结果。
●计算中是否使用了不同数据类型的变量,例如将整数与浮点数相加?
●计算中是否使用了类型相同但长度不同的变量,例如,将字节与字相加?
●计算时是否了解和考虑到编译器对类型或长度不一致的变量的转换规则?
●赋值的目的变量是否小于赋值表达式的值?
●在数值计算过程中是否可能出现溢出?
●除数/模是否可能为零?
●对于整型算术运算,处理某些计算(特别是除法)的代码是否会导致精度丢失?
●变量的值是否超过有意义的范围?例如,可能性的计算结果是否小于0%或者大于100%?
●对于包含多个操作数的表达式,求值的次序是否混乱,运算优先级对吗?需要加括号使其清晰吗?
比较错误
小于、大于、等于、不等于、真、假。比较和判断错误很可能是由于边界条件问题。
●比较得正确吗?虽然听起来简单,但是比较应该是小于还是小于或等于常常发生混淆。
●存在分数或者浮点值之间的比较吗?如果有,精度问题会影响比较吗?1.0000001和1 00000002极其接近,它们相等吗?
●每一个逻辑表达式都正确表达了吗?逻辑计算按预计的进行了吗?求值次序有疑问吗?
●逻辑表达式的操作数是逻辑值吗?例如,是否包含整数值的整型变量用于逻辑计算中?
控制流程错误
控制流程错误的原因是编程语言中循环等控制结构未按预期方式工作。它们通常由计算或者比较错误直接或间接造成。
●如果程序包含begin.。.end和do. . .while等语句组,end是否明确给出并与语句组对应?
●程序、模块、子程序和循环能否终止?如果不能,可以接受吗?
●可能存在永远不停的循环吗?
●循环是否可能永不执行?如果是这样,可以接受吗?
●如果程序包含像switch. . . case语句这样的多个分支,索引变量能超出可能的分支数目吗?如果超出,该情况能正确处理吗?
●是否存在“丢掉一个”错误,导致循环意外的流程?
子程序参数错误
子程序参数错误的来源是软件子程序不正确地传递数据。
●子程序接收的参数类型和大小与调用代码发送的匹配吗?次序正确吗?
●如果子程序有多个入口点,引用的参数是否与当前入口点没有关联?
●常量是否当做形参传递,在子程序中被意外改动?
●子程序更改了仅作为输人值的参数吗?
●每一个参数的单位是否与相应的形参匹配,例如,英吠对米?
●如果存在全局变量,在所有引用子程序中是否有相同的定义和属性?
输入/输出错误
输入/输出错误包括文件读取、接受键盘或者鼠标输入以及向打印机或者屏幕等输出设备写入错误。下列条目非常简单、通用,应该在使用时补充,以涵盖所测试的软件。
●软件是否严格遵守外部设备读写数据的专用格式?
●文件或者外设不存在或者未准备好的错误情况有处理吗?
●软件是否处理外部设备未连接、不可用,或者读写过程中存储空间占满等情况?
●软件以预期方式处理预计的错误吗?
●检查错误提示信息的准确性、正确性、语法和拼写了吗?
其他检查
这个压轴清单定义了一些不适合放在其他类别的条目。这不是为了完整,而是提示为定制软件项目清单应该加入的内容。
●软件是否使用其他外语?是否处理扩展ASCII字符?是否需要用统一编码取代ASCII?
●软件是否要移植到其他编译器和CPU,具有这样做的许可吗?如果没有计划或者测试,那么,移植性可能成为一个大难题。
●是否考虑了兼容性,以使软件能够运行于不同数量的可用内存、不同的内部硬件(例如图形和声卡)、不同的外设( 例如打印机和调制解调器) ?
●程序编译是否产生“警告”或者“提示”信息?这些信息通常指示进行了有疑问的处理。纯粹主义者可能认为警告信息是不可接受的。
动态白盒测试:带上x光眼镜测试
动态就是要启动运行,白盒就是看内部的代码。
动态白盒测试不仅仅是查看代码的运行情况,还包括直接测试和控制软件。动态白盒测试包括以下4个部分:
●直接测试底层函数、过程、子程序和库。在Microsoft Windows中这称为应用程序编程接口(API)。
●以完整程序的方式从顶层测试软件,但是根据对软件运行的了解调整测试用例。
●从软件获得读取变量和状态信息的访问权,以便确定测试与预期结果是否相符,同时,强制软件以正常测试难以实现的方式运行。
●估算执行测试时“命中”的代码量和具体代码,然后调整测试,去掉多余的测试用例,补充遗漏的用例。
本章余下部分讨论以上各部分。阅读的同时,请思考怎样用它们来测试我们熟悉的软件。
动态白盒测试和调试
一定不要把动态白盒测试和调试(debugging)弄混了。做过编程的人可能会花费大量时间调试自己编写的代码。这两项技术表面上很相似,因为它们都包括处理软件缺陷和查看代码的过程,但是它们的目标大不相同。
动态白盒测试的目标是寻找软件缺陷,调试的目标是修复缺陷。
分段测试
如果代码分段构建和测试,最后合在一起形成更大的部分,那么整个产品无疑会链接在一起。
在底层进行的测试称为单元测试(unit testing)或者模块测试(module testing)。
单元经过测试,底层软件缺陷被找出并修复之后,就集成在一起,对模块的组合进行集成测试(integration testing)。
这个不断增加的测试过程继续进行,加入越来越多的软件片段,直至整个产品一至少是产品的主要部分一在称为系统测试(system testing)的过程中一起测试。
采取这种测试策略很容易隔离软件缺陷。在单元级发现问题时,问题肯定就在那个单元中。如果在多个单元集成时发现软件缺陷,那么它一定 与模块之间的交互有关。当然也有例外,但是总的说来,测试和调试比一起测试所有内容要有效得多。
次边界
次边界在第5章与ASCII表和2的幂问题一起讨论过。这些是次边界导致软件缺陷的最常见例子,而软件的各个部分都有自己独特的次边界。以下是其他一些例子:
●计算税收的模块在某些财务结算处可能从使用数据表转向使用公式。
●在RAM底端运行的操作系统也许开始把数据移到硬盘上的临时存储区。这种次边界甚至无法确定,它随着磁盘上剩余空间的数量而发生变化。
●为了获得更高的精度,复杂的数值分析程序根据数字大小可能切换到不同的等式以解决问题。
如果进行白盒测试,就需要仔细检查代码,找到次边界条件,并建立能测试它们的测试用例。询问编写代码的程序员是否知道这些条件,并对内部数据表给予特别的注意,因为这里聚集了大量次边界条件。
公式和等式
公式和等式通常深藏于代码中,从外部看,其形式和影响不是非常明显。计算复利的财务程序一定包含以下公式:
其中.
p=本金
r=年利率
n=每年复加的利率次数
t=.年数
A=t年后的本息总和
优秀的黑盒测试员很可能选择n=0的测试用例,但是白盒测试员在看到代码中的公式之后,就知道这样做将导致除零错,而使公式乱套。
然而,如果n是另一项计算的结果,会怎样呢?也许软件根据用户输入来设置n的值,或者为了找出最低赔付金额而从算法角度试验各种n值。软件测试员需要考虑有没有n值为零的情形出现,指出什么样的程序输入会导致它出现。
错误强制
本章中数据测试的最后一种类型是错误强制(error forcing)。如果执行在调试器中测试的程序,不仅能够观察到变量的值,还可以强制改变变量的值。
在进行复利计算时,如果找不到将复加数设置为零的直接方法,就可以利用调试器来强制赋值。于是软件不得不处理这情况,或者报告处理不了。
代码覆盖
与黑盒测试一样,测试数据只是一半工作。为了全面地覆盖,还必须测试程序的状态以及程序流程,必须设法进人和退出每一一个 模块,执行每一行代码, 进入软件每一条逻辑和决策分支。这种类型的测试叫做代码覆盖(code coverage)测试。
代码覆盖测试是一种动态白盒测试,因为它要求通过完全访问代码以查看运行测试用例时经过了哪些部分。
代码覆盖测试最简单的形式是利用编译环境的调试器通过单步执行程序查看代码。图7-9给出了一个运行中的Visual Basic调试器的例子。
配置测试
如果决定进行完整、全面的配置测试,检查所有可能的制造者和型号组合,就会面临巨大的工作量。
市场上大致有336种显卡,210种声卡,1500种调制解调器,1200种打印机。 测试组合的数目是336 x210x 1500x 1200,总计上亿种一规模之 大难以想像。
如果限于排除法测试,每-种配置 单独测试一种板卡只用30分钟,也要近一年的时间。
别忘了这只是配置测试中的一个步骤。在产品发布之前修复软件缺陷,只通过两三种配置测试是很少见的。
减少麻烦的答案是等价划分。需要找出-一个方法把巨大无比的配置可能性减少到尽可能控制的范围。由于没有完全测试,因此存在- -定的风险,但这正是软件测试的特点。
在每种配量中执行测试
软件测试员需要执行测试用例,仔细记录并向开发小组报告结果(见第19章“报告发现的问题”),必要时还要向硬件生产厂商报告。如本章前面所述,明确配置问题的准确原因通常很困难,而且非常耗时。软件测试员需要与程序员和白盒测试员紧密合作,分离问题原因,判断所发现的软件觖陷是软件的原因还是硬件的原因。
如果软件缺陷是硬件的原因,就利用生产厂商的网站向他们报告问题。一定要指明自己的软件测试员身份以及所在的公司。许多公司有专人帮助软件公司编写和硬件配合的软件。他们可能要求发送测试软件的副本、测试用例和相关细节,以便帮助他们分离问题。
反复测试直到小组对结果满意为止
配置测试一般不会贯穿整个项目期间。最初可能会尝试一些配置,接着整个测试通过,然后在越来越小的范围内确认缺陷的修复。最后达到没有未解决的缺陷或觖陷限于不常见或不可能的配置上。
兼容性测试
软件兼容性测试( software compatibility testing)是指检查软件之间是否能够正确地交互和共享信息。交互可以在同时运行于同一台计算机上的两个程序之间,甚至在相隔几千公里、通过因特网连接的不同计算机上的两个程序之间进行。交互还可以简化为在软盘上保存数据,然后拿到其他房间的计算机上。
兼容软件的例子如下:
●从Web页面剪切文字,在文字处理程序打开的文档中粘贴。
●从电子表格程序保存账目数据,在另一个完全不同的电子表格程序中读入。
●使照片修饰软件在同一操作系统下的不同版本正常工作。
●使文字处理程序从通信录管理程序中读取姓名和地址,打印个性化的邀请函和信封。
●升级到新的数据库程序,读入现存所有数据库,像老程序一样对其进行处理。
平台和应用程序版本
选择目标平台或者兼容的应用程序实际上是程序管理或市场定位的任务。软件设计用于某个操作系统、Web浏览器或者其他平台要由熟悉客户基本情况的人来决定。他们还要明确软件的版本或软件需要兼容的版本。
例如,软件包装或者启动画面上可能有如下通告:
Works best with AOL 9.0
Requires Windows XP or greater
For use with Linux 2.6.10
该信息是说明书的一部分, 向开发者和测试小组说明软件的目标。每一种平台都有己的开发标准,并且从项目管理的立场看,使平台清单在满足客户要求的前提下尽可能小是很重要的。
向后和向前兼容
向后兼容是指可以使用软件的以前版本。
向前兼容是指可以使用软件的未来版本。
标准和规范
第一步应该是研究可能适用于软件或者平台的现有标准和规范。
实际上这些要求有两个层次:高级和低级。说高级和低级可能用词不当,但在某种意义上,情况就是这样。
高级标准是产品普遍遵守的规则,例如外观和感觉、支持的特性等。
低级标准是本质细节,例如文件格式和网络通信协议等。两者都很重要,都需要测试以保证兼容。
高级标准和规范
软件要在Windows, Mac或者Linux操作 系统上运行吗?是Web应用程序吗?如果是,运行于何种浏览器上?每一个问题都关系到平台,如果某个应用程序声称与某平台兼容,就必须遵守该平台自身的标准和规范。
低级标准和规范
从某种意义上说,低级标准比高级标准更重要。假如创建一个运行在Windows之上的程序,与其他Windows软件在外观和感觉上有所不同。它不会获得Microsoft Windows认证徽标。
用户虽然不会因为它与其他应用程序不同而感到激动,但是他们可能会使用该产品。
然而,如果该软件是一个图形程序,把文件保存为.pict文件格式(标准的Macintosh图形文件格式),而程序不符合.pict文件的标准,用户就无法在其他程序中查看该文件。该软件与标准不兼容,很可能成为短命产品。
同样,通信协议、编程语言语法以及程序用于共享信息的任何形式都必须符合公开的标准和规范。此类低级标准常常不被重视,但是从测试员的角度来看必须测试。低级兼容性标准可以视为软件说明书的扩充部分。如果软件说明书说:“ 本软件以.bmp, jpg和.gif格式读写图形文件”,就要找到这些格式的标准,并设计测试来确认软件符合这些标准。
数据共享兼容性
在应用程序之间共享数据实际上是增强软件的功能。写得好的程序支持并遵守公开标准;允许用户与其他软件轻松传输数据,这样的程序可称为兼容性极好的产品。
程序之间最为人熟知的数据传输方式是读写磁盘文件。如上--节所述,严格遵守磁盘和文件格式的低级标准是实现此类共享的前提。虽然其他方式有时被想当然地接受,但仍然需要做兼容性测试。以下是一些例子:
●文件保存和文件读取是人人共知的数据共享方法。把数据存入软盘(或者其他形式的磁介质和光介质存储器),然后拿到另外一台运行不同软件的计算机上读取。文件的数据格式只有符合标准,才能在两台计算机上保持兼容。
●文件导出和文件导入是许多程序与自身以前版本、其他程序保持兼容的方式。
●剪切、复制和粘贴是程序之间无需借助磁盘传输数据的最常见的数据共享方式。在这种情况下,传输在内存中通过称为剪贴板(Clipboard) 的即时程序实现。
外国语言测试
使文字和图片有意义
看到过按外语字面意思粗劣翻译过来的某个器械或者玩具的用户手册吗?“把第5个螺栓穿过绿杆拧紧在螺母上。”什么意思?
这就是粗劣的翻译( translation)。如果在制作外国语软件时不多花心思,则软件对于不讲英语的用户可能就是这样的感觉。逐字直译单词是容易的,但要想使整个操作提示意思明确、实用,就需要投入更多的时间和精力。
好的翻译工作者可以做到这一点,如果对两种语言都很熟练,就能够将外文翻译得读起来和原文一样。遗憾的是,在软件行业中甚至连一个像样的好翻译都找不到。以西班牙文为例。把英语翻译成西班牙文应该是轻而易举的事,对吧?那么是指哪个国家的西班牙文?西班牙的西班牙文吗?哥斯达黎加、秘鲁或多米尼加共和国的西班牙文呢?它们都是西班牙语国家,但是语言有极大差异,为一个国家编写的软件不能被其他国家很好地接受。即使英语也有同样的问题。不仅有美国英语,还有加拿大、澳大利亚和英国英语。在文字处理程序中可以令人惊奇地找到colour, neighbour和rumour这样的 单词。
除了语言,还需要考虑地域(region或locale)一用 户的国家和地理位置。使软件适应特定地域特征,照顾到语言、方言、地区习俗和文化的过程称为本地化( localization)或国际化(internationalization)。 测试此类软件称为本地化测试。
翻译问题
虽然翻译只是整个本地化工作的一部分,但是从测试角度看这是重要的一环,最明显的问题是如何测试用其他语言做的产品。那么,软件测试员或者测试小组至少要对所测试的语言基本熟悉,能够驾驭软件,看懂软件显示的文字,输入必要的命令执行测试。现在也许要申请一直没时间上的斯洛文尼亚语公共大学课程了。
不要求测试小组中的每-一个人会说软件所用的当地语言,只需要有一个人会就行了。不知道单词如何说也可以检查许多内容。学会一点语言肯定会有帮助,但是从下面的讲述中可以看到没有特别流利的外语水平也可以进行许多测试工作。
文本扩展
可能出现的翻译问题中最直接的例子来自于文本扩展(text expansion)。虽然英语有时显得比较哕嗦,但是实践证明,当英语被翻译为其他语言,用来表达同一事物时往往需要加一些字符。
一个好的大拇指规则是每个单词长度预计增加100%。例如一 个按钮上;语句和短小段落长度预计增加50%,通常是在对话框和错误提示信息中的短语。
ASCII、DBCS和Unicode
Unicode为每一个字符提供唯一编号,
无论何种平台,无论何种程序,无论何种语言。
因为Unicode是由主要软件公司、硬件生产厂商和其他标准组织所支持的世界标准,所以它变得更加通用。大多数主要软件应用程序都支持它,图10-2给出 了Unicode支持的多种字符。如果软件终究需要进行本地化,软件测试员和程序员就应该摆脱“古老ASCII的”的束缚,而转向Unicode,以节省时间、减少烦恼和软件缺陷。
从左往右 和 从右往左读
翻译中有一个大难题是某些语言(例如希伯莱文和阿拉伯文)从右向左读,而不是从左向右读。想像一下把整个用户界面镜像翻转是什么情形。
幸好大多数主要操作系统提供了处理这些语言的内部支持。如果没有这一一点,完成任务几乎是不可能的。即便如此,翻译这样的文本也不是容易的事。利用操作系统的特性来实现这些需要大量的编程工作。从测试的角度看,把它当做全新的产品,而不仅是本地化产品比较稳妥。
让文本脱离代码
最后要讨论的翻译问题是白盒测试问题一-让文本 与代码脱离。这句话的意思是说所有文本字符串、错误提示信息和其他可以翻译的内容都应该存放在与源代码独立的文件中。应该杜绝如下代码:
Print "Hello World"
大多数本地化人员不是程序员,也没有必要是。让他们修改源代码,进行语言翻译,既没有把握又有风险。他们要修改的是称为资源文件(resource file) 的简单文本文件,该文件包含软件可以显示的全部信息。当软件运行时,通过查找该文件来引用信息,不管信息的内容是什么。无论信息是英文或丹麦文,都按照原文显示。
这就是说,对于白盒测试员来说,检查代码,确保没有任何嵌入的字符串未出现在外部文本文件中很重要。如果在西班牙语程序中的一个重要错误提示信息以英语的方式出现将是很令人尴尬的。
参考书籍:软件测试原书第二版