We briefly tested our programs by executing them to see if they produced the output we expected. However, there is far more to testing than just running the program once.
How you test and what you test depend on what the program does, how it will be used, and how essential it is that it be correct.
Almost all programs have errors. They are a fact of life. Programmers create errors during the act of creating a program, and then have to find and fix them. Interestingly, whether a program has errors or not may depend on who’s doing the evaluation. The end user, who best understands how the program will be used, has a different perspective than the program designer, who is coming at the problem from another viewpoint. A program may “work,” but if it doesn’t solve the problem the end user needs solved, then it’s not correct.
For now, we will focus on straightforward correctness as defined by the stated goals of the program.
How do we test a specific program to determine its correctness? We design and implement a test plan. A test plan is a document that specifies how many times and with which data a program must be run to thoroughly test the program. Each set of input data values is called a test case. The test plan should list the reason for choosing the data, the data values, and the expected output from each case.
The test cases should be chosen carefully. Several approaches to testing can be used to guide this process. Code coverage is an approach that designs test cases to ensure that each statement in the program is executed. Because the tests are based on the code of the program, this approach is also called clear-box testing. Another approach, data coverage, calls for designing test cases to ensure that the limits of the allowable data are covered. Because this approach is based solely on input data and not the code, it is also called black-box testing. Often testing entails a combination of these two approaches.
Test plan implementation involves running each of the test cases described in the test plan and recording the results. If the results are not as expected, you must go back to your design and find and correct the error(s). The process stops when each of the test cases gives the expected results. Note that an implemented test plan gives us a measure of confidence that the program is correct; however, all we know for sure is that our program works correctly on the test cases. Therefore, the quality of the test cases is extremely important.
In the case of the program that reads in two values and sums them, a clear-box test would include just two data values. There are no conditional statements in this program to test with alternate data. However, a clear-box test would not be sufficient here, because we need to try both negative and positive data values. The numbers that are being read in are stored in one word. The problem does not limit values to ±215 2 1, but our implementation does. We should also try values at the limits of the size of the allowed input in the test plan, but because they are being summed, we need to be sure the sum does not exceed ±215 − 1.
To implement this test plan, we ran the program five times, once for each test case. The results were then written in the “Observed Output” column. They were what we had predicted, which increases our confidence that the program works as planned. If any of the observed output had been different than expected, we would then explore the problem the test case uncovered.
A computer can store, retrieve, and process data. A user can enter data into the machine, and the machine can display data so that the user can see it. At the lowest level of abstraction, instructions to the machine directly relate to these five operations.
A computer’s machine language is the set of instructions that the machine’s hardware is built to recognize and execute. Machine-language programs are written by entering a series of these instructions in their binary form. The Pep/9 is a virtual computer with an A register (the accumulator) and two-part instructions. One part of the instruction tells which action the instruction performs, and the other part specifies where the data to be used (if any) can be found. Programs written using the Pep/9 instruction set can be run using a simulator—a program that behaves like the Pep/9 computer.
The Pep/9 assembly language is a language that allows the user to enter mnemonic codes for each instruction rather than binary numbers. Programs written in assembly language are translated into their machine-language equivalents, which are then executed using the Pep/9 simulator.
Pseudocode is a shorthand-like language that people use to express algorithms. It allows the user to name variables (places to put values), input values into variables, and print out the values stored in variables. Pseudocode also allows us to describe algorithms that repeat actions and choose between alternative actions. Asking questions and deferring details are two problem-solving strategies used in algorithm design.
Programs, like algorithms, must be tested. Code coverage testing involves determining the input to the program by looking carefully at the program’s code. Data coverage testing involves determining the input by considering all possible input values.
For Exercises 1–15, mark the answers true or false as follows:
True
False
Given the following state of memory (in hexadecimal), complete Exercises 16–20 by matching the problem to the solution shown.
0001 A2
0002 11
0003 00
0004 FF
A2 11
A2 12
00 02
11 00
00 FF
Exercises 21–60 are programs or short-answer questions.
000?
001?
41. The following program seems to run, but does strange things with certain input values. Can you find the bug?
BR |
main |
|
sum: |
.WORD |
0x0000 |
numl: |
.BLOCK |
1 |
num2: |
.BLOCK |
1 |
num3: |
.BLOCK |
1 |
main: |
LDWA |
sum,d |
DECI |
numl,d |
|
DECI |
num2,d |
|
DECI |
num3,d |
|
ADDA |
num3,d |
|
ADDA |
num2,d |
|
ADDA |
numl,d |
|
STWA |
sum,d |
|
DECO |
sum,d |
|
STOP |
||
.END |
Branch to location Branch1 if the accumulator is zero.
Branch to location Branch1 if the accumulator is negative.
Branch to location Branch1 if the accumulator is negative and to Branch2 if the accumulator is not negative.
Would you like to do assembly-language programming? Can you think of any personality types that would be well suited for such detail-oriented work?
The translation process has been demonstrated by showing the machine-language program that is the result of the assembly-language program. Look carefully at the solution in Exercise 45. Think about the steps that the assembler program must execute. Do you think that the translation can be made by looking at each assembly-language instruction once, or must each one be examined twice? Convince a friend that you are right.
If a person has two computers of the same kind, is it ethical to buy one copy of a software package and install it on both machines? What are the arguments on the yes side? What are the arguments on the no side?
Has anyone borrowed software from you? Do you think he or she copied it?
18.224.33.107