Testing and maintenance · 测试与维护
| English | 中文 | Pinyin · 拼音 |
|---|---|---|
| run-time error/rʌn taɪm ˈerə/ | 运行时错误 | yùn xíng shí cuò wù |
| syntax error/ˈsɪntæks ˈerə/ | 语法错误 | yǔ fǎ cuò wù |
| logic error/ˈlɒdʒɪk ˈerə/ | 逻辑错误 | luó jí cuò wù |
| dry run/draɪ rʌn/ | 手工跟踪 | shǒu gōng gēn zōng |
| walkthrough/ˈwɔːkθruː/ | 走查 | zǒu chá |
| white-box testing/waɪt bɒks ˈtestɪŋ/ | 白盒测试 | bái hé cè shì |
| black-box testing/blæk bɒks ˈtestɪŋ/ | 黑盒测试 | hēi hé cè shì |
| integration testing/ˌɪntɪˈɡreɪʃn ˈtestɪŋ/ | 集成测试 | jí chéng cè shì |
| stub/stʌb/ | 桩 | zhuāng |
| alpha testing/ˈælfə ˈtestɪŋ/ | α测试 | α cè shì |
| beta testing/ˈbiːtə ˈtestɪŋ/ | β测试 | β cè shì |
| acceptance testing/əkˈseptəns ˈtestɪŋ/ | 验收测试 | yàn shōu cè shì |
| test strategy/test ˈstrætədʒi/ | 测试策略 | cè shì cè lüè |
| test plan/test plæn/ | 测试计划 | cè shì jì huà |
| normal data/ˈnɔːml ˈdeɪtə/ | 正常数据 | zhèng cháng shù jù |
| abnormal data/əbˈnɔːml ˈdeɪtə/ | 异常数据 | yì cháng shù jù |
| extreme data/ekˈstriːm ˈdeɪtə/ | 极端数据 | jí duān shù jù |
| boundary data/ˈbaʊndəri ˈdeɪtə/ | 边界数据 | biān jiè shù jù |
| corrective maintenance/kəˈrektɪv ˈmeɪntənəns/ | 纠正性维护 | jiū zhèng xìng wéi hù |
| adaptive maintenance/əˈdæptɪv ˈmeɪntənəns/ | 适应性维护 | shì yìng xìng wéi hù |
| perfective maintenance/pəˈfektɪv ˈmeɪntənəns/ | 完善性维护 | wán shàn xìng wéi hù |
| regression testing/rɪˈɡreʃn ˈtestɪŋ/ | 回归测试 | huí guī cè shì |
Thirty-seven seconds
- On 4 June 1996 the first Ariane 5 rocket lifted off from French Guiana. Thirty-seven seconds later it veered off course and destroyed itself. The payload was four satellites worth $370 million.
- The cause was one line of code, reused from Ariane 4, that converted a 64-bit number into a 16-bit integer. Ariane 5 flew faster, the number was bigger, and the conversion overflowed: a run-time error 运行时错误 in a routine that was not even needed after lift-off.
- The code had never been tested with Ariane 5's flight data. Nobody had chosen test data at the extremes of the new rocket's range.
- This lesson is the three kinds of error, the methods of testing, how to choose test data, and how a program is kept alive after release.
三十七秒
- 1996 年 6 月 4 日,第一枚阿丽亚娜 5 号火箭从法属圭亚那升空。三十七秒后它偏离航向并自毁。载荷是四颗价值 3.7 亿美元的卫星。
- 原因是从阿丽亚娜 4 号沿用的一行代码,它把一个 64 位数转换成 16 位整数。阿丽亚娜 5 号飞得更快,数字更大,转换溢出了:一个运行时错误(run-time error),而且出在升空后根本不再需要的例程里。
- 这段代码从未用阿丽亚娜 5 号的飞行数据测试过。没有人在新火箭范围的极端处选过测试数据。
- 这一课讲三种错误、测试方法、怎样选择测试数据,以及程序发布后怎样维持生命。
Three kinds of error
- A syntax error 语法错误 breaks the grammar of the language: a missing bracket, a misspelled keyword. It is found at translation, so the program will not run until it is fixed.
- A run-time error happens while the program runs: division by zero, a file that does not exist, an array index out of range. The program crashes or raises an exception; the fix is a check before the risky operation.
- A logic error 逻辑错误 lets the program run and produce wrong results:
+for-, an off-by-one loop, conditions in the wrong order. Nothing flags it; only testing and tracing reveal it.
Found at translation, found at run time, found only in the output
三种错误
- 语法错误(syntax error)违反语言的语法:缺少括号、关键字拼错。它在翻译时被发现,所以程序修好之前无法运行。
- 运行时错误在程序运行时发生:除以零、文件不存在、数组索引越界。程序崩溃或抛出异常;修法是在危险操作前加检查。
- 逻辑错误(logic error)让程序运行并产生错误的结果:
+写成-、差一的循环、条件顺序错误。没有任何东西标记它;只有测试和跟踪能揭示它。

翻译时发现,运行时发现,只在输出里发现
Match each kind of error to how it shows up. · 将每种错误类型与其表现方式匹配。
Syntax = caught at translation; logic = wrong output; run-time = crash while running. · 语法 = 翻译时捕获;逻辑 = 输出错误;运行时 = 运行过程中崩溃。
Worked example: find and correct the errors
- Syntax: the
IFhas noENDIF. The translator rejects it. Run-time: ifCountis 0 the division fails; guard it withIF Count > 0 THEN. Logic: if a pass is 50 or more,> 50fails a student on exactly 50; it should be>= 50. - Name the type, say why it is that type, and give the correction. Three parts, three marks.
例题:找出并纠正错误
Total ← 0
FOR i ← 1 TO Count
Total ← Total + Marks[i]
NEXT i
Average ← Total / Count
IF Average > 50 THEN
OUTPUT "Pass"
- 语法:
IF没有ENDIF。翻译器拒绝它。运行时:如果Count是 0,除法失败;用IF Count > 0 THEN保护它。逻辑:如果 50 分及以上算通过,> 50会让正好 50 分的学生不通过;应该是>= 50。 - 说出类型,说明为什么是这种类型,给出纠正。三部分,三分。
A program divides a total by the number of entries and crashes when the input file is empty. This is a: · 一个程序将总数除以条目数,当输入文件为空时崩溃。这是:
Division by zero happens while the program runs and stops it. A guard such as IF Count > 0 fixes it. · 除以零发生在程序运行期间并导致其停止。像 IF Count > 0 这样的守卫语句可以修复它。
Testing methods: reading the code
- A dry run 手工跟踪 traces the code on paper, writing each variable's value in a trace table after each line.
- A walkthrough 走查 is a team review: the programmer explains the code line by line while colleagues look for faults.
- White-box testing 白盒测试 designs tests from the code's internal structure, so that every statement, branch and loop is exercised. Black-box testing 黑盒测试 designs tests from the specification only: feed inputs, compare the outputs with what was expected, without looking at the code.
Outside looking in, or inside looking at every path
测试方法:阅读代码
- 手工跟踪(dry run)在纸上追踪代码,在每一行之后把每个变量的值写进跟踪表。
- 走查(walkthrough)是团队评审:程序员逐行解释代码,同事们寻找错误。
- 白盒测试(white-box testing)根据代码的内部结构设计测试,让每条语句、每个分支和循环都被执行。黑盒测试(black-box testing)只根据规格说明设计测试:输入数据,把输出与期望比较,不看代码。

从外面往里看,或从里面看每条路径
Designing test cases from the specification only (inputs and expected outputs), ignoring the code inside, is called ______-box testing. · 仅根据规范(输入和预期输出)设计测试用例,忽略内部代码,称为______盒测试。
Black-box tests from the spec; white-box uses the code's internal structure to cover statements and branches. · 基于规范的黑色盒测试;白色盒测试使用代码的内部结构来覆盖语句和分支。
Testing methods: assembling and releasing
- Integration testing 集成测试 combines modules that were tested separately and tests the interfaces between them. A stub 桩 stands in for a module that is not yet written, returning fixed values so the rest can be tested top-down.
- Alpha testing α测试 is done in-house by the developers before release. Beta testing β测试 gives a limited group of real users the program in their own environment.
- Acceptance testing 验收测试 is done by the customer, against the requirements, to decide whether the product is fit for purpose.
测试方法:组装与发布
- 集成测试(integration testing)把分别测试过的模块组合起来,测试它们之间的接口。桩(stub)代替尚未编写的模块,返回固定值,让其余部分能自顶向下测试。
- α测试(alpha testing)由开发者在发布前在内部进行。β测试(beta testing)把程序交给一小群真实用户在他们自己的环境中使用。
- 验收测试(acceptance testing)由客户对照需求进行,决定产品是否符合用途。
Software process lab · 软件过程实验
Classify development examples by the stage or tool they belong to. · 根据阶段或所属工具对开发示例进行分类。
Worked example: which method for which situation
- The reporting module is finished but the database module it calls does not exist yet: test it with a stub that returns fixed data.
- Two modules pass their own tests but fail when the output of one feeds the other: integration testing of the interface.
- The software is complete; the company wants faults found in real conditions before general release: beta testing by a limited group of users.
- The customer decides whether to pay: acceptance testing against the agreed requirements. Name the method and what it is for.
例题:哪种情形用哪种方法
- 报表模块已完成,但它调用的数据库模块还不存在:用返回固定数据的桩测试它。
- 两个模块各自通过测试,但一个的输出送入另一个时失败:对接口做集成测试。
- 软件已完成;公司想在正式发布前在真实条件下发现故障:由一小群用户做β测试。
- 客户决定是否付款:对照约定需求的验收测试。既要说出方法也要说它的用途。
Match each situation to the testing method it needs. · 将每种情况与其所需的测试方法匹配。
Stub for a missing part, beta for real users, acceptance for the customer, integration for the joins. · 缺失部分的桩,面向真实用户的 Beta 测试,面向客户的验收测试,面向接口的集成测试。
Test strategy and test plan
- A test strategy 测试策略 is the high-level approach: which kinds of testing will be done, by whom, when, and what must pass before the next stage.
- A test plan 测试计划 is the detailed list of tests. For each: the purpose, the input data, the expected output, and a column for the actual output when the test is run.
- A test without an expected result is not a test. It only shows what the program did, not whether that was right.
测试策略和测试计划
- 测试策略(test strategy)是高层方法:做哪些类型的测试、由谁、何时,以及进入下一阶段前必须通过什么。
- 测试计划(test plan)是详细的测试清单。每一项:目的、输入数据、期望输出,以及运行测试时填写实际输出的一列。
- 没有期望结果的测试不是测试。它只显示程序做了什么,不显示那是否正确。
A test plan lists, for each test, the input data and the expected output. · 测试计划列出了每个测试的输入数据和预期输出。
Purpose, input, expected output and a column for the actual output. The strategy is the high-level approach; the plan is the detailed list. · 目的、输入、预期输出以及实际输出的列。策略是高层方法;计划是详细列表。
Choosing test data
- Normal data 正常数据: typical valid values inside the range, which should be accepted and processed correctly.
- Abnormal data 异常数据: values that should be rejected, out of range or the wrong type.
- Extreme data 极端数据: the largest and smallest values still accepted, at the edges of the range. Boundary data 边界数据: the pairs that straddle each edge, the accepted extreme and the rejected value just outside it, where off-by-one errors hide.
Inside, outside, and right on the line
选择测试数据
- 正常数据(normal data):范围内典型的有效值,应该被接受并正确处理。
- 异常数据(abnormal data):应该被拒绝的值,超出范围或类型错误。
- 极端数据(extreme data):仍被接受的最大和最小值,在范围的边缘。边界数据(boundary data):跨在每条边两侧的一对——被接受的极端值和紧邻其外被拒绝的值——差一错误藏在那里。

里面、外面,和正好压在线上
For a field that accepts marks 0–100, which are the boundary test values? · 对于一个接受 0–100 分的字段,哪些是边界测试值?
Boundary data sits at the edges of the valid range (and just outside) — where off-by-one errors hide. · 边界数据位于有效范围的边缘(以及略外侧)——即错一位错误隐藏的地方。
Worked example: test data for a mark from 0 to 100
| Kind | Data | Expected result |
|---|---|---|
| normal | 50, 75 |
accepted and processed |
| abnormal | -10, 200, "abc" |
rejected: out of range or wrong type |
| extreme | 0, 100 |
accepted: the smallest and largest valid values |
| boundary | -1 and 0, 100 and 101 |
-1 rejected, 0 accepted; 100 accepted, 101 rejected |
- Every row needs the expected result; a table of inputs alone scores half. The extremes are accepted:
-1is boundary, not extreme.
例题:0 到 100 分数的测试数据
| 类型 | 数据 | 期望结果 |
|---|---|---|
| 正常 | 50、75 |
接受并处理 |
| 异常 | -10、200、"abc" |
拒绝:超出范围或类型错误 |
| 极端 | 0、100 |
接受:最小和最大的有效值 |
| 边界 | -1 和 0,100 和 101 |
-1 拒绝,0 接受;100 接受,101 拒绝 |
- 每一行都需要期望结果;只有输入的表格得一半分。极端值是被接受的:
-1是边界,不是极端。
A field accepts marks from 0 to 100. Which values are extreme test data? Select all · 所有 that apply. · 一个字段接受 0 到 100 的分数。哪些值是极端测试数据?选择所有适用的选项。
Extreme values are the smallest and largest still accepted. -1 is rejected, so it is boundary or abnormal; 50 is normal. · 极端值是仍被接受的最小值和最大值。-1 被拒绝,因此它是边界或异常值;50 是正常值。
Maintenance
- Most of a program's lifetime cost is spent after release. Corrective maintenance 纠正性维护 fixes faults found in use.
- Adaptive maintenance 适应性维护 keeps the program working in a changing environment: a new operating system, a new API, a change in the law.
- Perfective maintenance 完善性维护 improves a program that already works: faster performance, a new feature users asked for. A program may need all three throughout its life.
Fix it, keep it working, make it better
维护
- 程序一生的大部分成本花在发布之后。纠正性维护(corrective maintenance)修复使用中发现的故障。
- 适应性维护(adaptive maintenance)让程序在变化的环境中继续工作:新操作系统、新 API、法律变化。
- 完善性维护(perfective maintenance)改进一个已经能用的程序:更快的性能、用户要求的新功能。一个程序一生中可能三种都需要。

修好它、让它继续工作、让它更好
Corrective maintenance fixes faults, perfective maintenance improves features, and adaptive maintenance keeps the software working in a changed environment. · 修正性维护修复故障,完善性维护改进功能,适应性维护使软件在变化的环境中继续工作。
Three maintenance types: corrective (fix bugs), perfective (enhance), adaptive (new OS/hardware/rules). · 三种维护类型:修正性(修复错误),完善性(增强),适应性(新操作系统/硬件/规则)。
A payroll program is changed because the tax law changed. Which kind of maintenance is this? · 由于税法变更修改了工资单程序。这属于哪种类型的维护?
The program was not faulty and is not being improved; its environment changed. That is adaptive maintenance. · 程序本身没有故障且未被改进;其环境发生了变化。这是适应性维护。
Amending an existing program
- Read the existing code until you understand the algorithm and the data flow. Find where the change belongs: which subroutine, which lines.
- Make the change as small as possible; do not rewrite working code. Update every related part: each caller of a changed parameter list, each routine that uses a changed data structure.
- Test the new behaviour and the old: regression testing 回归测试 checks that nothing that used to work has broken. Then document the change.
修改现有程序
- 阅读现有代码,直到理解算法和数据流。找出改动属于哪里:哪个子程序、哪几行。
- 把改动做到尽可能小;不要重写能用的代码。更新每个相关部分:参数列表改变后的每个调用者,数据结构改变后使用它的每个例程。
- 既测试新行为也测试旧行为:回归测试(regression testing)检查原来能用的没有被弄坏。然后记录改动。
After changing a program, regression testing checks that: · 修改程序后,回归测试检查:
Regression testing re-runs old tests to confirm existing behaviour still works after a change. · 回归测试重新运行旧测试以确认更改后现有行为仍然有效。
Put the steps of amending an existing program in order. · 将修改现有程序的步骤按顺序排列。
Understand, locate, change small, propagate, test everything, record. Skipping the regression test is how a fix breaks something else. · 理解、定位、小范围更改、传播、全面测试、记录。跳过回归测试正是导致修复引入其他问题的原因。
Marks that slip away
- Extreme is accepted; abnormal is rejected.
0and100are extreme;-1and101are boundary values on the rejected side. - A logic error does not crash the program. If it crashed, it was a run-time error.
- Alpha is in-house; beta is real users outside. A stub replaces a missing module; it is not a test method for finished code.
- A test plan row without an expected output earns nothing. Regression testing follows every change.
容易丢掉的分
- 极端是被接受的;异常是被拒绝的。
0和100是极端;-1和101是拒绝一侧的边界值。 - 逻辑错误不会让程序崩溃。崩溃了,那就是运行时错误。
- α在内部;β是外部的真实用户。桩代替缺失的模块;它不是对已完成代码的测试方法。
- 没有期望输出的测试计划行不得分。每次改动之后都要回归测试。
You've got it
- syntax errors stop translation · run-time errors crash a running program · logic errors run and give wrong output, found only by testing
- methods: dry run, walkthrough, white-box (from the code), black-box (from the specification), integration (interfaces, with stubs for missing modules), alpha (in-house), beta (real users), acceptance (the customer)
- test data: normal accepted, abnormal rejected, extreme the accepted edges, boundary either side of each edge; every test has an expected result
- maintenance: corrective fixes, adaptive keeps up with the environment, perfective improves; amend small, update callers, regression test
你掌握了
- 语法错误阻止翻译 · 运行时错误让运行中的程序崩溃 · 逻辑错误运行但输出错误,只有测试才能发现
- 方法:手工跟踪、走查、白盒(从代码)、黑盒(从规格说明)、集成(接口,用桩代替缺失模块)、α(内部)、β(真实用户)、验收(客户)
- 测试数据:正常被接受、异常被拒绝、极端是被接受的边缘、边界在每条边的两侧;每个测试都有期望结果
- 维护:纠正性修复、适应性跟上环境、完善性改进;小改、更新调用者、回归测试