Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] - نسخه متنی

Larne Pekowsky

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







4.1. An Introduction to Automated Testing


One of the most widely used testing toolkits is called JUnit, and it will be introduced shortly. Before getting to JUnit, it is worth considering the motivation behind the development of such a tool.

A developer initially testing a program is likely to do something similar to what was done with the factorial program developed in Chapter 3. That example was tested by running the program with a "typical" input and making sure it worked. We will examine what constitutes a good set of inputs to test against soon, but for now just consider the process by which testing is done.

After repeating this kind of test many times, it may occur to the developer that one of the things computers are good at is performing time-consuming, repetitive tasks so that humans don't need to. This suggests writing a second program to test the first, which might be done as in Listing 4.1.


Listing 4.1. A simple automated tester


package com.awl.toolbook.chapter04;
import com.awl.toolbook.chapter03.Factorial;
public class FactTest {
public void testFact() {
Factorial f = new Factorial(10);
if(f.getFactorial() == 3628800) {
System.out.println("Test succeeded");
} else {
System.out.println("Test failed");
}
}
public static void main(String argv[]) {
FactTest ft = new FactTest();
ft.testFact();
}
}

Listing 4.1 is certainly not the simplest possible test program. It would have been possible to run the test within main() or to make testFact() static and thus avoid the constructor. These shortcuts were avoided to treat TestFact as a full-fledged Java program.

It is straightforward to derive more sophisticated test programs from Listing 4.1 One possibility would be to make the test more comprehensive by testing the behavior when given a negative number. This is a classic example of the kind of test that might often be overlooked. A developer who was asked to write a factorial program is likely to know that the factorial function is only defined for positive integers and so would not think to test a negative value. However, an end user might be curious as to what the factorial of a negative number is, or a more complex program might compute some intermediate value that could be negative and then use Fact to compute the factorial of that value.

Adding such a test can most easily be accomplished by adding another method to FactTest that will closely resemble testFact(). The only question is what value should be compared against the result of getFactorial() to determine whether the test succeeded.

As written, getFactorial() will return 1 when given a negative value. This is wrong in the worst possible way because it produces an answer that looks reasonable but is meaningless. A better behavior would be for Factorial to explicitly reject negative values, which can be accomplished by having setNum() throw an IllegalArgumentException when called with a negative value. A few additional steps will need to be made to accommodate this change. The result is shown in Listing 4.2. Notice how considerations about how a program should be tested can in turn affect how the code is written, which in turn makes that code more robust.


Listing 4.2. The revised Factorial class


/*
* Created on Jun 23, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and
* Comments
*/
package com.awl.toolbook.chapter04;
/**
*
* To change the template for this generated type comment
* go to
* Window>Preferences>Java>Code Generation>Code and
* Comments
*/
public class Factorial {
private int num;
public void setNum(int n)
throws IllegalArgumentException
{
if(n < 1) {
throw new IllegalArgumentException(
"Factorial is only defined for pOSItive integers");
}
num = n;
}
public Factorial() {
try {
setNum(1);
} catch (IllegalArgumentException e) {}
}
public Factorial(int n)
throws IllegalArgumentException
{
setNum(n);
}
public int getFactorial() {
int total = 1;
for(int i=1;i<num+1;i++) {
total = total * i;
}
return total;
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
Factorial f = new Factorial(n);
System.out.println(f.getFactorial());
}
}

With Factorial suitably modified the second test can be written and main() modified to invoke it. The new code is shown in Listing 4.3.


Listing 4.3. A second test


public void testFactNegative() {
try {
Factorial f = new Factorial(-1);
System.out.println("Test failed" );
} catch (IllegalArgumentException e) {
System.out.println("Test succeeded");
}
}
public static void main(String argv[]) {
FactTest2 ft = new FactTest2();
ft.testFact();
ft.testFactNegative();
}


/ 207