In this paper, we use this technique to improve component’s testability so as to facilitate component’s unit testing and regression testing of CBS as follows: Self-checking aspect is
Trang 1AOP-based Testability Improvement for Component-based Software
Chengying Mao
School of Software, Jiangxi University of Finance and Economics,
330013 Nanchang, China
E-mail: maochy@yeah.net
Abstract
High evolvability is the remarkable character of component-based software (CBS), and brings great
pressure to the testing activity Recently,
aspect-oriented programming has been proposed as an
effective technique for modulating separate concerns,
and facilitating the maintenance and evolution of
software system In this paper, we use this technique to
improve component’s testability so as to facilitate
component’s unit testing and regression testing of CBS
as follows: Self-checking aspect is embedded to check
the invariants which the component should obey, and
tracing aspect is introduced to collect precondition of
method execution in component so as to help
regression testers to pick out precise subset of test suit
In addition, two examples are used to demonstrate the
feasibility and effectiveness of our presented methods
1 Introduction
Component-based development is intended to increase reliability and evolvability of systems while at
the same time decrease the cost of system development
As a consequence, component-based software (CBS)
has been widely used in various application domains
and becomes a fairly popular software form in the last
decade Effective and efficient testing is the most
important solution for ensuring the delivery of
high-quality software However, due to the lack of
information about the externally-developed
components, system testers (i.e component users)
generally can’t perform effective testing on CBS
The essential reason lies in the separation of component development context and use context For
component providers, the information about
application environment might not be available so that
the component is explicitly designed and developed for
the needs of the hypothesis application environment,
however, it might not be the one in which the
component will be actually used [1] On the other hand, the source code of component is seldom available for component users, so they can’t conduct program-based testing on the externally-provided component Additionally, they also might not be able to acquire sufficient document and accurate information about the component to be introduced
In order to tackle the problems caused by such a lack, an approach which can be used to improve component’s capability of supporting testing activities, i.e component’s testability improvement It is to incorporate the idea and principle of testing into the phases of software design and coding with the precondition of a little or even no increase of software complexity, so as to improve the controllability and observability of component in testing process In fact, that approach is to enhance the information exchange between component developer and user [1] At present, quite a few methods for improving component’s testability improvement have been proposed, such as intro-/retro-spection approach [2], wrapper-based method [3], component meta-data approach [4], and so
on The most representative one of them is the built-in test approach [5], which has been popularly utilized for testing component or component-based system
Aspect-oriented programming (AOP) provides explicit mechanisms for capturing the structure of crosscutting concerns in software systems [6] Encapsulating the crosscutting concern as a module
unit aspect, which is easier to develop, maintain and
reuse is possible It’s not hard to see that, the functional points can also be divided into two classes: normal function concern and maintenance concern In this paper, we use AOP to crosscut the maintenance concern from traditional component code, and introduce the new element, i.e aspect, into component-based software so as to provide the facilities for testing
in latter stage
The remainder of this paper is organized as follows
In Section 2, we address related work and the concept
Trang 2of AOP The methods of improving component’s
testability based on AOP technology are detailedly
described in Section 3 In Section 4, we discuss the
advantages and limitations of these methods Section 5
concludes the paper and outlines future work
2 Background
2.1 Related work
Here we address previous work that is popularly accepted or closely related to our work Orso et al
firstly presented the concept of meta-data for
component-based software engineering (CBSE) [7],
and then utilized meta-data to direct the activities such
as self-checking code generation, and test case
selection [4] Metadata, presented by an open format,
describe static and dynamic aspects of a component,
and can be retrieved by component users Strictly
speaking, the aspects introduced into component in our
approach also belong to metadata
Another approach which can be used to avoid of information lack is the retrospection method [2] It can
augment a component with information concerning
tests conducted by the component provider and
indications for tests to be conducted by the component
user It can also collect relevant information during test
activities This approach can provide bidirectional
information exchange between component provider
and user However, our AOP-based method mainly
realizes the information transfer from provider to user
Component testability depends on the ability of a component to support test execution and test
observation to some extent, so the approach of testable
bean [8] is introduced to support these tasks
Unfortunately, too many restrictions have to be
satisfied, for example, the target component model is
merely limited to EJB
In reference [9], Ma et al use matrix to represent the (detailed) dependence relationship of component,
and the final motivation is to improve the testability of
CBS This method can only be applied in the earlier
design phase, and the dependence information should
also be released along with component
Reflection method [3] is also proposed, but is restricted to the components which are written in the
languages with capability of reflection mechanism
Furthermore, Barbier et al realized component
behavior prediction and monitoring through built-in
test design [10] But it needs the support from model
checking and Java reflection package
2.2 Concept of AOP
AOP allows programmers to develop application logic and non-functional properties separately, and enables programmers to weave separately developed logic and properties together using automated support
Up to now, quite a few AOP programming systems have been developed Among them, the most well-known one is AspectJ [11], which is an aspect-oriented extension to Java Besides regular class, it introduces some new constructs to better handle crosscutting concerns, such as introduction, joint point, pointcut, advice, and aspect [12,13]
Introduction (also called intertype declaration) in
AspectJ is used by an aspect to introduce methods, attributes, and interface implementation declarations
into regular classes A joint point is a well-defined
point in the code at which our concerns crosscut the application, such as a call to a method, an access to an
attribute, etc A pointcut is a set of joint points that
optionally expose some of the values in the execution
of these joint points Several primitive pointcut designators are defined in AspectJ to identify all types
of joint points Advice is used to define some code that
is executed when a pointcut is reached AspectJ provides three different types of advice, that is, before, after, and around They execute before the joint point, after the joint point, and instead of the joint point, respectively In general, advice can change the control flow or behavior of classes which are crosscut by it
Aspects are modular units of crosscutting
implementations AOP doesn’t replace existing programming paradigms and languages Instead, it works with them to improve their expressiveness and utility Therefore, an AspectJ program can be divided into two parts: non-aspect code (i.e regular class code) and aspect code
Generally, aspect-oriented technology has many potential benefits, we can use it to specify and encapsulate the concerns such as exception handling, synchronization, logging, and resource sharing perfectly In this paper, we use this technique to handle
a special but important concern in the lifecycle of software development, i.e testing facility
3 Testability improvement based on AOP
As stated in the section of related work, there are a few ways to improve the testability of a component Among them, the typical one is the method of built-in test design Here, our AOP-based testability improvement is motivated by the idea of that method The difference is that we will build some aspects into
Trang 3the traditional components to facilitate testing activities
At present research stage, we mainly work on two
improvement schemes One is to improve component’s
capability of self-checking (or self-testing), and the
other is to provide the information on execution trace
to facilitate test case selection
3.1 AOP-based self-checking
Due to the similarity of our method and built-in test design, we address the concept of built-in test design
firstly
The basic idea of built-in test design is that component provider pre-places test scripts in
component and sets the corresponding
testing-interfaces In general, the built-in test scripts contain
test cases or can possess facilities capable of
generating the test cases which the component can be
used to test itself and its own methods [5] A
component can operate in two modes, namely normal
mode and maintenance mode [14] The underlying
principle can be schematically demonstrated in the
following figure
Figure 1 The framework of built-in test component
However, in our method we doesn’t embed test cases or scripts which can generate test cases into
component, but to seed the scripts which can check the
invariants during the testing process We integrate such
scripts into a separate module, i.e aspect After such
reconstruction, we can realize the separation of
different concerns so as to improve maintainability of
the component In order to address our AOP-based
testability improvement method, we adopt a simple
integer stack example program to discuss the
implementation steps Figure 2 shows the
implementa-tion of the class
Although component developers will perform strict testing on their component, it’s not enough to ensure
the correct execution when it runs in real application
environment Therefore, component users will retest
the component in their context In order to facilitate the
testing activities on the side of component user,
component developer should pre-place some code related to testing into the component Here, we mainly consider for checking some invariants about the functions of component in the additional code
Take the component of integer stack for example, there may be two possible invariants when pushing an integer into it: (1) If component’s previous size (denoted as oldsize) is lower than MAX−1, it should satisfy the following relations after the new element is added into it
(i) newsize oldsize= +1
(ii)newindex oldindex= +1
Where newsize is the component’s size after element addition, and oldindex and newindex are the position pointers of current element in stack before and after addition, respectively
(2) If oldsize is equal to the value of MAX−1, the following relation should be satisfied after pushing new integer
newsize newindex MAX= =
Through above analysis, we can pre-place the self-checking code in the component of integer stack Since
we adopt the AOP technology to write that code here,
the pre-placed code in component is called self-checking aspect For the method push(int) in component INT_Stack, the corresponding self-checking code is illustrated in Figure 3
Similarly, we can also get other invariants while considering other methods such as pop(), then use these invariants to construct testing code in self-checking aspect
Normal Interface
Testing Interface
Normal Scripts
Testing Scripts Test Suit
Functional Methods
Testing Methods
class INT_Stack{
int[ ] stack;
private int stack_index; //the index of current element private int size; //size of the stack
INT_Stack() //the constructor {
stack = new int[MAX];
stack_index = -1;
size = 0;
} //operations of integer stack void setEmpty(){…} //set the stack to be empty int getSize() //get the size of stack
{ return size;
} int getIndex(){…} //get the pointer of current element void pop(){…} //pop out the top element
void push(int element){…} //push the new element into the top of
//integer stack } //A component of integer stack
Figure 2 Program code of an integer stack class
Trang 4Self-checking aspect (or AOP-based built-in test design) exhibits the merits as follows: (1) The
component providers can design rational test
framework on the condition of their sufficient
comprehension of component’s internal structure, so
component users can save plentiful testing efforts (2)
This method separates the testing-purposed code from
normal function code, so it reduces the coupling
between function code and maintenance code (3) The
method is mainly adopted to test the component’s
compatibility for real execution context, but also can
be used for the integration testing of component-based
software system (4) Due to the separation of
maintenance concern, the corresponding functions can
be easily tailored for the needs in latter running phase
3.2 AOP-based information tracing
Aspects can be used to add new functionality to an existing system which can’t be added without invasive
changes to the whole system using conventional
techniques In order to assist component user (i.e
component tester) in observing component’s behavior
or execution profile well, an aspect should be applied
to add an observer for some relevant data to the CBS
In this paper, we demonstrate two kinds of applications
of AOP-based information tracing One is used for fault location, and the other is used for test case selection
3.2.1 AOP-based fault location While considering
fault location, the information about program profile is very useful and important for debugger to understand program’s execution behaviors under specific input
To achieve the execution profile of a component, a specialized tracing aspect should be introduced into the component It is worth noting that the tracing aspect should not change behaviors of a given component, otherwise, it will result in distorting the analysis results Here we use AspectJ to create such aspect to improve observability of component written in Java like in [15], whose code is shown in Figure 4 The pointcut in this aspect means the execution of any method without return value in component INT_Stack When the component is driven by a test case to perform testing, the tracing aspect can record the corresponding method execution sequence according
to the format in advices Then debuggers can use the tracing information to construct component’s execution profile so as to locate potential faults For example, suppose there is a test case tc=push(3),pop() ,push(7),setEmpty , then we can get the tracing information as below via a tracing aspect
Enter into: void INT_Stack.push(int) Stack’s size before execution: 0 Leave out: void INT_Stack.push(int) Stack’s size after execution: 1 Enter into: void INT_Stack.pop() Stack’s size before execution: 1 Leave out: void INT_Stack.pop() Stack’s size after execution: 0 Enter into: void INT_Stack.push(int)
aspect Built_in_Check{
private int oldsize=0;
private int newsize=0;
private int oldindex=-1;
private int newindex=-1;
……;
pointcut pushInt(INT_Stack s, int x): target(s) && agrs(x) &&
call(void INT_Stack.push(int));
……;
before(INT_Stack s, int x): pushInt(s, x) {
oldsize = s.getSize();
oldindex=s.getIndex();
} after(INT_Stack s, int x) returning: pushInt(s, x) {
newsize = s.getSize();
newindex=s.getIndex();
if(oldsize< MAX-1)
if((newsize != oldsize +1) || (newindex != oldindex +1))
System.out.println("Errors in method push(int)!");
esle
if((newsize != MAX) || (newindex != MAX))
System.out.println("Errors in method push(int)!");
} ……;
} //a self-checking aspect
Figure 3 Self-checking aspect for unit testing
aspect traceProfile{
……;
Pointcut methCall(INT_Stack s): target(s) && execution(void INT_Stack.*( ));
……;
before(INT_Stack s): methCall(s) {
Sytem.out.println(“Enter into: ”+thisJionPoint.getSignature()); Sytem.out.println(“Stack’s size before execution: ”+ s.getSize()); }
after(INT_Stack s) returning: methCall(s) {
Sytem.out.println(“Leave out: ”+thisJionPoint.getSignature()); Sytem.out.println(“Stack’s size after execution: ”+ s.getSize()); }
……;
} //a tracing aspect
Figure 4 An aspect for execution profile tracing
Trang 5Stack’s size before execution: 0 Leave out: void INT_Stack.push(int) Stack’s size after execution: 1 Enter into: void INT_Stack.setEmpty() Stack’s size before execution: 1 Leave out: void INT_Stack.setEmpty() Stack’s size after execution: 1
With the support of the above tracing information, debugger can easily judge that a fault perhaps exists in
the method setEmpty()
Of course, the aspect traceProfile is just a simple example, and the more practical code for
improving the observability of component can also be
designed by using AOP technology
3.2.2 Test case selection based on AOP High
evolvability is the remarkable character of
component-based software system, and brings great pressure to the
activity of regression testing In order to reduce the
need of testing resource, a rational way is to select test
cases from the old test suit In our previous work, we
have proposed two ways to select such test case subset
One is based on the enhanced representation of change
information of component version [16], and the other
is implemented via the component built-in test design
[17] These two approaches both require component
users to place some probes in proper branches of CBS
to record the precondition of each published method’s
invocation in the previous testing activities Obviously,
this solution will aggravate the burden of system
maintainers Here, we continue to settle this problem
via aspect-oriented programming
Here, we also take the example of
Vending-Machine in reference [4] to explain our improvement
strategy (component code is omitted for space reason)
In order to precisely select test cases related with
changes in method “public int dispense
aspect to collect the value of its parameters, that is
should be before, and its code is similar to that shown
in Figure 4 Here, we only give the pointcut and advice
as below
before (Dispenser d, int credit, int sel): call(int Dispenser.dispense( int, int)) && target(d) && args(credit, sel) {
System.out.println("The Precondition
of method dispense is:" + credit +","+sel);
}
Therefore, we can get the precondition of each test case through running the component woven with
above aspect code On the other hand, the parameter’s
conditions which will exercise modifications in
method dispense can be gained from change
information provided by component developers Finally, system tester can select out proper subset of test cases for regression testing
4 Discussion
In this section, we evaluate our proposed method in terms of advantages and limitations
The basic idea of AOP is to encapsulate so-called crosscutting concerns which influence many modules
of a given software system in a new module called aspect This might, in turn, allow us to do a better job
in maintaining system as it evolves The method of improving testability based on AOP can separate testing functions from normal functions, and reduce coupling degree between testing code and functional code Therefore, the testing-purposed aspects can be inserted or tailored according to the different needs in the different stage of system lifecycle
The AOP-based testability improvement also encourages the reuse of testing code, that is, the same testing-purposed code and central interface can be used
to validate many different kinds of applications Furthermore, the proposed method is feasible and practical In general, invariants will be addressed in component’s requirements and detailed documents, so
it is not hard to construct self-checking aspect by extracting them from documents Because AOP provides three kinds of advices to monitor the execution or call of method, regression tester can easily construct such aspect to collect precondition of each method’s execution or call As a consequence, they can precisely pick out subset from original teat suit to perform regression testing
However, we only employ pilot study on the problems about testability improvement based on aspect-oriented programming, there are still some limitations which should be extended For example, because the degree of advice is still at method level at present, our testability improvement can only be performed at method level too As a result, self-checking and precondition monitoring are not so flexible But we believe this trouble can be tackled after the AOP technology is developed in these years
On the other hand, the component developer should recompile component’s source code with AspectJ compliers such as ajc [18] due to the introduction of AOP technology Fortunately, the compiled Java bytecode can still run on the traditional Java virtual machine (JVM)
5 Concluding remarks
Trang 6The rapid evolution of CBS brings great challenges
to its maintenance in the later phase, so it is quite
necessary to improve testability of component or CBS
at the design stage Recently, aspect-oriented
programming has been proposed as an effective
technique for modulating separate concerns, which
facilitates the maintenance and evolution of software
system In this paper, we adopt AOP technology to
enhance component’s testability from two sides: One is
to embed self-checking aspect to check the invariants
which the component should obey The other is to
collect precondition of the execution of component’s
method via a tracing aspect and then use this
information to direct test case selection Furthermore,
two examples are used to demonstrate the feasibility
and effectiveness of our presented methods
While our research is at an early stage——that is, there are still some open issues that need to be further
explored, such as, we should experimentally validate
the benefits of these new methods on some large-scale
component-based software Applying AOP technology
to enhance the capability of facilitating other testing
activities such as integration testing is also a research
topic in next step
Acknowledgments
We would like to thank the anonymous reviewers for their insightful comments and suggestions This
work was partially supported by the Science
Foundation of Education Bureau of Jiangxi Province
of China under Grant No.GJJZ-2007-267, and the
Young Teacher Foundation on Research of Jiangxi
University of Finance and Economics
References
[1] S Beydeda, and V Gruhn, “State of the Art in Testing
Components”, Proc of the 3rd International Conference On
Quality Software (QSIC’03), 2003, pp.146-153
[2] C Liu, and D Richardson, “Software Components with
Retrospectors”, Proc of International Workshop on the Role
of Software Architecture in Testing and Analysis, 1998,
pp.63-68
[3] S H Edwards, “Toward Reflective Metadata Wrappers
for Formally Specified Software Components”, Proc of
OOPSLA Workshop Specification and Verification of
Component-Based Systems (SAVCBS’01), 2001, pp.1-8
[4] A Orso, M J Harrold, D Rosenblum, and et al., “Using
Component Metacontent to Support the Regression Testing
of Component-based Software, Proc of IEEE International
Conference on Software Maintenance, 2001, pp.716-725
[5] S Beydeda, “Research in Testing COTS
Components-Built in Testing Approaches”, Proc of the 3rd ACS/IEEE
International Conference on Computer Systems and Applications, 2005, pp.101-104
[6] G Kiczales, J Lamping, A Mendhekar, C Maeda, C lopes, J M loingtier, and J Irwin, “Aspect-Oriented
Programming”, Proc of the 11th European Conf on
Object-Oriented Programming, LNCS, Vol.1241, Springer-Verlag,
1997, pp.220-242
[7] A Orso, M J Harrold, and D Rosenblum, “Component
Metadata for Software Engineering Tasks”, Proc of the 2nd
International Workshop on Engineering Distributed Objects,
LNCS, Vol.1999, Springer-Verlag, 2001, pp.126-140
[8] J Gao, K Gupta, S Gupta, and S Shim “On Building
Testable Software Components”, Proc of COTS-Based
Software Systems (ICCBCC’02), LNCS, Vol.2255,
Springer-Verlag, 2002, pp.108-121
[9] L Ma, H Wang, Y Lu, “The Design of Dependency Relationship Matrix to Improve the Testability of
Component-Based Software”, Proc of the 6th International
Conference on Quality Software (QSIC’06), 2006, pp 93–98
[10] F Barbier, and N Belloir, “Component Behavior
Prediction and Monitoring through Built-in Test”, Proc of
the 10th IEEE International Conference and Workshop on the Engineering of Computer-Based Systems (ECBS’03),
2003, pp.17-22
[11] AspectJ compile 1.2, http://www.eclipse.org/aspectj [12] The AspectJ Team, “The AspectJ Programming Guide”,
2001
[13] T Xie, and J Zhao, “A Framework and Tool Supports
for Generating Test Inputs of AspectJ Programs”, Proc 5th
International Conference on Aspect-Oriented Software Development, 2006, pp.190-201
[14] Y Wang, G King, and H Wickburg, “A Method for Built-in Tests in Component-based Software Maintenance”,
Proc of European Conference on Software Maintenance and Reengineering (CSMR’99), 1999, pp.186-189
[15] M Störzer, J Krinke, and S Breu, “Trace Analysis for
Aspect Application”, Proc of Workshop on Analysis of
AspectOriented Software (AAOS), 2003
[16] C Mao, and Y Lu, “Regression Testing for Component-based Software Systems by Enhancing Change
Information”, Proc of the 12th Asia-Pacific Software
Engineering Conference (APSEC’05), 2005, pp.611-618
[17] C Mao, Y Lu, and J Zhang, “Regression Testing for
Component-based Software via Built-in Test Design”, Proc
of the 22nd Annual ACM Symposium on Applied Computing (SAC’07), ACP Press, 2007 (accepted to appear)
[18] G Kiczales, E Hilsdale, J Hugunin, M Kersten, J
Palm, and W G Griswold, “An Overview of AspectJ”, Proc
of the 15th European Conference on Object-Oriented Programming, LNCS, Vol.2072, Springer-Verlag, 2001,
pp.327-355