blob: d59086bf1b9372f95938129ca764b814eb647a8f [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<org.eclipse.epf.uma:ContentDescription xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:org.eclipse.epf.uma="http://www.eclipse.org/epf/uma/1.0.5/uma.ecore"
xmlns:epf="http://www.eclipse.org/epf" epf:version="1.5.0" xmi:id="-VGT8iHGtQSiOUGitq1qmow"
name=",_eRutgC5QEduVhuZHT5jKZQ" guid="-VGT8iHGtQSiOUGitq1qmow" changeDate="2006-12-28T10:50:35.593-0800"
version="1.0.0">
<mainDescription>&lt;p>&#xD;
This guideline describes a number of types of tests. To perform these types of testing you need to define, and then&#xD;
run, a series of tests against the source code. A developer test is a single test that needs to be performed.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
It is valuable&amp;nbsp;to augment automated tests with human readable test scripts in order to implement developer test&#xD;
cases, scripts that include the information discussed below. A test script is the actual steps, sometimes either&#xD;
written procedures to follow or the source code of a test. Developer test scripts are run against testing targets:&#xD;
either one unit of source code, a more complex portion of your system (such as a component), or the entire system&#xD;
itself to test&amp;nbsp;some developer issue such as integration.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Regression Testing&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Regression testing is the act of ensuring that changes to&amp;nbsp;the code have not adversely affected existing&#xD;
functionality. It is important to recognize that incremental development makes regression testing critical. Whenever&#xD;
you release an application, you must ensure its previous functionality still works, and because you release&#xD;
applications more often when taking the incremental approach, this means regression testing becomes that much more&#xD;
important. Regression testing is the first thing you should be thinking about when testing for the following reasons:&#xD;
&lt;/p>&#xD;
&lt;ol>&#xD;
&lt;li>&#xD;
You want to be able to modify code and know that you can rerun your tests to see if you broke anything.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Existing users get very angry when things that previously worked don’t work anymore.&#xD;
&lt;/li>&#xD;
&lt;/ol>&#xD;
&lt;p>&#xD;
Regression testing is fairly straightforward conceptually – you just need to run all of the previous test cases against&#xD;
the new version of the code. Regression testing tools help immensely because they are designed with regression testing&#xD;
in mind. However, there are potential challenges to regression testing:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
When you change your production, either to enhance it or to refactor it, you will need to rework existing test&#xD;
cases coupled to that code.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
If your updates affect only a component of the system, then potentially you only need to run the test cases that&#xD;
affect this single component. Although this approach is a little risky because your changes may have had a greater&#xD;
impact than you suspect, it does help to reduce both the time and cost of regression testing.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
The more non-code artifacts that you decide to keep, the greater the effort to regression test your work and&#xD;
therefore the greater the risk to your project because you are more likely to skimp on your testing efforts.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
Regression testing is critical to success as an agile developer. Many software developers use the xUnit family of open&#xD;
source tools, such as &lt;a href=&quot;http://www.junit.org/&quot; target=&quot;_blank&quot;>JUnit&lt;/a> and &lt;a href=&quot;http://www.vbunit.org/&quot; target=&quot;_blank&quot;>VBUnit&lt;/a>, to test their code. The advantage of these tools is that they implement a testing framework&#xD;
with which you can regression test all of your source code. Commercial testing tools are also viable options.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Traditional Code Testing Techniques&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Although object and procedural technologies are different, several important testing concepts from the procedural world&#xD;
are valid regardless of the underlying technology. These traditional testing techniques are:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Black-box testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Clear-box testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Boundary-value testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Coverage/Path testing&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h4>&#xD;
Black-Box Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Black-box testing, also called interface testing, is a technique in which you create test cases based only on the&#xD;
expected functionality of a method, class, or application without any knowledge of its internal workings. One way to&#xD;
define black-box testing is that given input A you should obtain expected results B.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The goal of black-box testing is to ensure the system can do what it should be able to do, but not how it does it. For&#xD;
example, if you invoke differenceInDays(June 30 2006, July 3 2006) the expected result should be three. The creation of&#xD;
black-box tests is often driven by the requirements for&amp;nbsp;the system. The basic idea is&amp;nbsp;to look at the user&#xD;
requirement and ask what needs to be done to show that the user requirement is met.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The primary advantage of black-box testing is that it enables you to prove that your application fulfills the&#xD;
requirements defined for it.&amp;nbsp;&amp;nbsp; The primary disadvantage is that it does not show that the internals&#xD;
of&amp;nbsp;the system work (hence the need for clear-box testing).&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Clear-Box Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Clear-box testing, also called white-box testing, is based on the idea that&amp;nbsp;the program code can drive the&#xD;
development of test cases. The basic concept is you look at&amp;nbsp;the code, and then create test cases that exercise it.&#xD;
For example, assume you have access to the source code for differenceInDays(). When you look at it, you see an IF&#xD;
statement determines whether the two dates are in the same year. If they are in the same year then&amp;nbsp;a simple&#xD;
strategy based on Julian dates is used; if not then a more complex&amp;nbsp;strategy is used. This indicates that you need&#xD;
at least one test that uses dates from the same year and one from different years. By looking at the code, you are able&#xD;
to determine new test cases to exercise the different logic paths within it.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The primary advantage of this concept is that it motivates you to create tests that exercise specific lines of&#xD;
code.&amp;nbsp; The disadvantages are that it does not ensure that your code fulfils the actual requirements (hence the&#xD;
need for black-box testing) and that your testing code becomes highly coupled to your application code.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Boundary-Value Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
This is based on the knowledge that you need to test your code to ensure it can handle unusual and extreme situations.&#xD;
For example, boundary-value test cases differenceInDays() would include passing it the same date, two wildly different&#xD;
dates, one date on the last day of the year and the second on the first day of the following year, and one date on&#xD;
February 29th of a leap year. The basic idea is you want to look for limits defined either by your business rules or by&#xD;
common sense, and then create test cases to test attribute values in and around those values.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The primary advantage of boundary value testing is that it motivates you to confirm that your program code is able to&#xD;
handle “unusual” or “extreme” cases.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Coverage and Path Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Two critical “traditional” concepts are coverage and path testing. Coverage testing is a technique in which you create&#xD;
a series of test cases designed to test all the code paths in your code. In many ways, coverage testing is simply a&#xD;
collection of clear-box test cases that together exercise every line of code in your application at least once. Path&#xD;
testing is a superset of coverage testing that ensures not only have all lines of code been tested, but all paths of&#xD;
logic have also been tested. The main difference occurs when you have a method with more than one set of case&#xD;
statements or nested IF statements: to determine the number of test cases with coverage testing you would count the&#xD;
maximum number of paths between the sets of case/nested IF statements and, with path testing, you would multiply the&#xD;
number of logic paths.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Unit and Integration Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Unit testing is the testing of an item, such as an operation, in isolation. For example, the tests defined so far for&#xD;
differenceInDays() are all unit tests. Integration testing, on the other hand, is the testing of a collection of items&#xD;
to validate that they work together. In the case of the data library/class, do the various functions work together?&#xD;
Perhaps the differenceInDays() function has a side effect that causes the dayOfWeek() function to fail if&#xD;
differenceInDays() is called first. Integration testing looks for problems like this.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Object-Oriented Testing Techniques&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
When testing systems built using object technology it is important to understand that your source code is composed of&#xD;
several constructs, including methods (operations), classes, and inheritance. Therefore you need testing techniques&#xD;
that reflect the fact that you have these constructs. These techniques are:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Method testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Class testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Class-integration testing&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Inheritance-regression testing&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h4>&#xD;
Method Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Method testing is the act of ensuring that your methods (operations) perform as defined. In procedural testing this&#xD;
would have been called function/procedure testing. Issues to address via method testing include:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Ensure that your getter/setter methods work as intended&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Ensure that each method returns the proper values, including error messages and exceptions&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Validate the parameters being passed to a method&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Ensure that a method does what it should&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
The advantage of method testing is that it ensures that methods work well in isolation but it does not help to find&#xD;
unintended side effects.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Class Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
The main purpose of class testing is to test classes in isolation, and it is effectively the combination of traditional&#xD;
unit testing and integration testing. It is unit testing because you are testing the class and its instances as single&#xD;
units in isolation, but it is also integration testing because you need to verify the methods and attributes of the&#xD;
class work together. The one assumption you need to make while writing “class tests” is that all other classes in the&#xD;
system work. Issues to address via class testing include:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Validate that the attributes of an object are initialized properly&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Validate the invariants of the class&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
The primary advantages of class testing are that it validates that the operations and properties of a class work&#xD;
together and that the class works in isolation. However, it does not guarantee that a class works well with the rest of&#xD;
your system.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Class-integration Testing&#xD;
&lt;/h4>&#xD;
&lt;p>&#xD;
Also known as component testing, this technique addresses the issue of whether the classes in your system, or a&#xD;
component of your system, work together properly. The relationships between classes can be used to drive the&#xD;
development of class integration test cases. Issues to address via class-integration testing include:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Validate that objects do what other objects expect of them&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Validate that return values are acted appropriately&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Validate that exceptions/errors are processed appropriately&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
The technique helps to validate that the various classes within a component, or a system, work together. However, it&#xD;
can be difficult to define and develop the test cases to fully perform this level of testing.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Inheritance-regression Testing&#xD;
&lt;/h4>This is the act of running of test cases defined for the superclasses on the instances of a subclass because errors&#xD;
have not been introduced by that new subclass. New methods are added and existing methods may be redefined by subclasses,&#xD;
methods which access and potentially change the value of the attributes defined in the superclass. It is possible that a&#xD;
subclass may change the value of the attributes in a way that was never intended in the superclass, or at least was never&#xD;
expected. The point is that you need to invoke the test suite of the superclass(es) when testing a subclass. &lt;br /></mainDescription>
</org.eclipse.epf.uma:ContentDescription>