TAPE
Test Code Adaptation Plugin for Eclipse
Lehmia Kiran
Department of Computer Sciences NUCES-FAST
Lahore, Pakistan [email protected]
Dr. Fakhar Lodhi
Department of Computer Sciences NUCES-FAST
Lahore, Pakistan [email protected]
Wafa Basit
Department of Computer Sciences NUCES-FAST
Lahore, Pakistan [email protected]
Abstract— Refactoring improves the design of software and makes it easier to maintain by eliminating code smells. Manual refactoring is often error-prone and time-consuming. Refactoring tools available in almost all major object oriented programming languages like java, C++, C# etc that provide varying degree of automation. The problem with these tools is that they do not support adaptation of unit tests of the refactored code resulting in inconsistent unit tests. Unit tests are the only safety net available to developers to verify the system behavior after refactoring. Once these tests get broken there is no way to describe whether the system preserved its behavior or not. In this paper we provide technical details of TAPE (Test code Adaptation Plug-in for Eclipse). This tool not only automates a few commonly used refactorings but also supports adaptation of unit tests affected by the refactoring process. Using this tool the developers can concentrate more on code development activities instead of resolving consistency issues between code and unit tests.
Keywords-Refactoring; Unit testing; Adaptation
I. INTRODUCTION
Refactoring is the process to change the code, making it easier to understand and cheaper to modify [6]. But it is important to verify semantic and syntactic correctness of the refactored code. Any modification in code can induce new bug in the code. Unit testing is the key method used to validate the code after refactoring [16]. Unit test cases in Object Oriented Paradigm are the programs that test classes [12]. So, each program is composed of units. Each unit is set of functions and these units are tested separately and test the code at lowest level of granularity [13]. Different frameworks for unit testing are available [1, 23, 24]; Junit [1] is the java plug-in which is used to run the test cases in the background. It tells about the failure or acceptance of the testcases. Eclipse [17] is the java IDE, which is used to edit, compile and run the java code. When junit is embedded in eclipse, test cases can also run on Eclipse. But, junit does not provide support for writing testcases and developers have to write the test cases by themselves, this problem is solved by moreUnit. MoreUnit [5] is an eclipse plug-in that helps in generating automated Junit tests.
Extreme Programming (XP) [14] allows the code to change often; consequently unit tests must also be changed. In traditional testing, it is a tester who writes the tests but in XP it is developers (not testers) who write tests for every class they develop. Whenever refactoring is applied on code, many test cases fail due to inconsistency with source code. The significant amount of developers’ effort is required to manually manipulate the testing suite on every single refactoring [15].The process of refactoring is automated by many tools [17, 20, 21, 22]. Eclipse supports automated refactoring and provides separate API to perform refactoring. But this API only focuses on source and does not adapt test cases, making both inconsistent.
Cost and effort of adapting test cases are very high. Complication of the adaptation increases with complexity of refactoring applied. In some cases adaptation becomes very complex and test cases have to be thrown away and new test cases have to develop [19]. Creation and maintenance of test cases are very expansive so it’s not feasible to throw away [8]. The solution to this problem is presented by TAPE “Test Code Adaptation Plug-in for Eclipse”.
TAPE has been especially designed to improve the process of refactoring. It is an Eclipse plug-in which adapts test cases making it consistent and semantically aligned with the code after applying refactoring. TAPE reduces the cost of maintenance of test cases because it makes source code and test cases synchronized. Both source code and the test code come under the owner ship of a developer. If there is change in the source code; the associated test code should also be adapted accordingly[18].Our plug-in gives sigh of relief to developers by drastically reducing time and effort of manually resolving the consistency issues between code and unit test.
Section 2 is of literature review which discusses refactoring and available tools for performing refactoring. Section3 contains architecture and implementation details of Test Code adaptation plug-in. Before discussing technical details of TAPE, prerequisite information like refactoring API for eclipse, plug-in for unit testing "Junit" and "MoreUnit", eclipse java plug-in for generation of unit tests are briefly illustrated. Section 4 contains conclusion and future work.
II. LITERATUREREVIEW
Refactoring is a means to improve the quality of existing code. The main idea behind refactoring is to change the code in small steps, while maintaining its external behavior [6]. Preserving code behavior means that functionality of the program must be unchanged after refactoring. The process of refactoring can be done manually but it’s very tedious and error-prone. Significant amount of work can be reduced and efficiency can be increase by making this process automated [10]. Fowler’s refactoring guidelines provides road map to perform 72 refactoring [6] but these guidelines are only applicable to production code. To incorporate the unit test adaptation in refactoring the Fowler’s guidelines for refactoring are not sufficient so extended guidelines to adapt production code and test code are illustrated in [8] and are followed in TAPE to perform refactoring with unit test adaptation.
[8] categorizes refactoring guidelines into three categories based on their affect on test code and production code. In this paper only the impact of refactoring on unit tests is considered therefore the type II and III are merged. So, two broad classes of refactoring guidelines are:
A: Refactoring that break test code
B: Refactoring that does not break test code
Automated tools are available for refactoring in almost all major object oriented programming languages like Java, C++, C# etc. IntelliJIDEA, Eclipse and Net Beans are refactoring tool for java language, CppRefactory and Xrefactory supports refactoring in C++ and to perform refactoring in C#, C# Refactoring Tool and C# Refactory are available. Following table shows the total number of refactorings in different tools and the number of refactorings belongs to classes A and B.
Table 1: Class A and Class B refactorings of different tools
Tool name Refactorings
Total Class A Class B
Netbeans 14 10 4 Eclipse 21 17 4 IntelliJ IDEA 32 28 4 Cpp Refactory 2 2 0 Visual Studio .NET(C# refactoring Tool) 5 4 1
Netbeans offers total 14 refactorings. And out of 14, 8 refactorings are defined by fowlers. So, 8 fowlers’
refactorings out of 72 are supported by net beans. 10 refactorings belong to classA and 4 refactorings belongs to class B. These figures tell us that out of 72 refactorings only 4 refactorings are those which do not break test code and it is very less in number.
Eclipse supports total 21 refactorings. The tool also implements 8 refactorings other then fowler.17 refactorings belongs to class A and 4 refactorings belongs to class B. Only 4 refactorings are those which adapt unit tests in it. Similarly, in IntelliJIDEA 13 refactorings are those, whose guidelines are not provided by fowler and only 4 refactorings out of 72 belongs to Class B, which are very few in number. In CppRefactory there is no refactoring which belongs to class B and in visual Studio.Net only one refactoring adapts unit test with source.
III. TAPE
Eclipse refactoring plug-in has been used as a baseline for TAPE. Find below a short overview of how refactoring is done in Eclipse.
A. Refactoring in Eclipse
Eclipse supports automated refactoring and provides an API for implementing refactoring that can be applied to any of its workspace elements (e.g. class or method). Eclipse refactoring is implemented for several languages e.g. Java and C++; but only refactoring of Java code [7] is highlighted in this paper.Following eclipse IDE snippet shows the types of available refactoring.
Figure 1: Refactoring Menu in Eclipse
B. Junit
To test the code after refactoring some testing mechanism is needed but writing unit tests is a tedious task. The objective is to make process of writing testing code easier and more maintainable [11]. Testing frameworks are available that automate many aspects of test creation and
maintenance [1, 23, 24]. An example of such a framework is Junit [1].
“JUnit is a unit testing framework for the Java programming language. JUnit has been important in the development of test-driven development, and is one of a family of unit testing frameworks collectively known as xUnit that originated with SUnit.”[1]
To run the test cases in background Junit has been used, but problem of writing test cases remains the same as Junit only runs the test cases and gives output about its failure or success. To resolve the issue of writing test cases moreUnit an existing plug-in for Eclipse is brought into use [5].
C. MoreUnit
MoreUnit is an eclipse plug-in that helps in generating automated JUnit tests. MoreUnit supports the generation of test cases, associates code and test cases. Classes which have associated unit tests are decorated with green marker and it also provides the facility to navigate between code and corresponding test using short cut [5].
Figure 2:package explorer of eclipse showing source classes and corresponding testCases
TAPE uses moreUnit to make an association between source code and test code. MoreUnit also helps in searching for corresponding test cases or test methods of source code when refactoring is applied.
D. TAPE
Adaptation of unit tests with refactored code means the process of eliminating syntactic and semantic errors after applying refactoring; also the quality of test code and capability to test should remain same as before refactoring of source code [8].
TAPE has been especially designed to improve the process of refactoring. It is an Eclipse java plug-in which is used to
assist in refactoring the code and adapting test cases in it. Following refactorings are discussed in this paper:
1. Move method
2. Inline method
3. Pull Up method
4. Rename method
Sometimes adaptation of unit tests turns out to be test code refactoring like in ‘move method’ and ‘pull up method’ refactoring, if the method is moved, the corresponding test method will also be moved in test case. After applying ‘pull up method’ refactoring, the corresponding test method will also be pulled up in the test cases. But when inline method refactoring is applied then its corresponding test method is deleted, not the same refactoring is applied on test code.
1) TAPE Overall Architecture
Architecture diagram of “TAPE” is shown in Figure 3, describes that how different components involved in the TAPE are associated with each other. As described above, Eclipse plug-ins are used to perform refactoring on the code (to get the code eclipse plug-ins are associated with eclipse workspace). MoreUnit generates unit test cases and builds an association between tests and corresponding classes. So the inputs to “Test Code Adaptation Plug-in for Eclipse” are code and its corresponding test cases. TAPE adapts test cases thus making both code and its corresponding test cases synchronous.
2) Basic Elements of TAPE
Figure 4: Basic Elements of TAPE
Figure illustrates how TAPE fits into existing elements of eclipse refactoring plug-in [3]. User starts refactoring by using TAPE GUI. The refactoring implementer gets the requirements for refactoring as specified by the user and then sends this information to the refactoring processor. Based on the requirements provided by refactoring implementer, the refactoring processor determines what change is required in the code then textual changes are performed in workspace resources like the java project or java files to reflect the changes made in underlying code. After that, selected element is sent to moreUnit plug-in, it searches for the test cases which are associated with source code. Test cases are sent to take where corrective actions are being taken to make test code and source code consistent. Lastly output of TAPE plug-in is the adapted test cases.
3) Life Cycle of TAPE
Figure 5: Lifecycle of TAPE
Whenever a client requests for refactoring, the UI forwards this request to the eclipse refactoring to initialize the refactoring. In this initiation phase of refactoring, initial conditions for refactoring are being checked and if some
information which is required for refactoring is missing, then it will gather more details and check for final conditions. If all conditions are satisfied, corresponding testcases of the code are gathered. After that textual change of refactoring are applied on source code and respective corrective actions are taken on testcases to make test cases synchronous with source code.
4) Object Model
Figure 6: TAPE Object Model
“Type Façade” and “Class Type facade” are the classes of moreUnit which help in parsing eclipse workspace to search for test cases and test methods.”Move Method Call”, “Inline Method Call” and “Call Pull Method” serves as the
bridge between GUI and wrapper
classes.”MoveMethodParticipant”,”MoveMethodChange”,
Inline Method”,”InlineMethodChange”
and”PullUpMethodProcessor” are the wrapper classes of existing eclipse refactoring. In these classes already built-in functions of refactoring are overridden to adapt test cases with source code refactoring.
5) Implementation details of TAPE
In this section, details of how refactoring is implemented to incorporate test cases change are explained. Few refactorings’ implementation are illustrated separately. MoreUnit plug-in helps to make an association between source and its test-cases. Using this association the corresponding test cases and test methods are searched and then the process of refactoring is applied on both source and test method.
a) Move Method Refactoring:
In ‘move method’, the source class must have the some association with destination class and this association should be made by passing destination class object as parameter. If this pre condition is not satisfied, Eclipse refactoring will not allow method to move, but when we write test method for a given method, it cannot pass any parameter. So, for moving test method refactoring Eclipse refactoring plug-in is not used.
The flow of move refactoring is as follows: firstly the method which is to be moved is taken from GUI and its corresponding test method is searched by ClassTypefacade. This information is sent to MoveMethodProcessor to check preconditions of refactoring. If these conditions are test method is physically moved to destination class using “move” function which is defined in IMethod (IMethod represents a method in java Model of eclipse) class [2]. Up till now the references that are changed due to moving methods are not updated.
Figure 7: sequence diagram of move method refactoring
b) Inline Method refactoring:
When the method is being inlined then its corresponding test method should be deleted. Thus, when the call from UI is made to the inline method then a call to delete test method must be generated. Hence when Inline method processor performs refactoring, it implicitly calls delete method processor which deletes test method.
Figure 8: Sequence diagram for inline method refactoring
GUI sends request to “InlineMethodCall” to initiate inline method refactoring by clicking Inline method button from the starting window of TAPE, after that you have to select class and the method which is to be inlined. This information is sent to “ClassTypeFcade”. “ClassTypeFacade” searches for the corresponding testMethod, then “inlineMethod” class checks for the preconditions of refactoring, and apply refactoring on source method and delete its corresponding test method. The physical changes on code are applied by “InlineMethodChange”. When refactoring completes both code method and its corresponding test method will be consistent.
c) Pull Up Method Refactoring:
Like all other refactorings, pullUpMethod refactoring is started by selecting super class, sub classes and the method which is to be pulled up from the GUI. The major class which is involved in Pull up method is pull up method processor, but before applying actual refactoring of eclipse plug-in some additional checks on source code are added, like
1. Does the inheritance hierarchy exist between the classes?
2. If there are more than one child classes, only then pull up method refactoring is applied.
3. Body of the methods, in all sub classes, that are to be pulled up should be same.
If these conditions are satisfied, then test methods are being searched by “ClassTypeFacade” and cycle of refactoring that
is discussed previously in section 3 is applied to both source and testcases, making testcases and source synchronized.
Figure 9: sequence diagram for pull up method refactoring
d) Rename Method Refactoring:
Major class that is involved in ‘rename Method’ refactoring is ‘renameMethod’, which is extended from abstract base class “rename-Participant”; participants that participate in refactoring that rename elements. “renameMethod” class is responsible to follow the cycle of refactoring and “renameTextChange” class is used to incorporate the text changes in the workspace resources. So, the flow of rename method refactoring is like refactoring corresponding elements of tests are gathered in class “renameMethod”. The “renameMethod” then checks for the conditions which are necessary for refactoring and sends all information of source code and test to “renameTextChange”. “renameTextChange” in turn performs textual changes in the code and updates all references to avoid any chances of syntactical or logical errors.
IV. CONCLUSION
TAPE is a tool which helps in synchronizing code and its corresponding test cases after refactoring. This automated tool of refactoring saves developer's time to make code and test cases consistent in refactoring process. Currently, only
impact of refactoring on unit tests is taken into account and client code is not incorporated. This tool can be extended to cater client code also. Guidelines for performing these refactorings are available in [8].
REFERENCES
[1] http://junit.sourceforge.net/
[2] http://www.jarvana.com/jarvana/view/org/eclipse/jdt/doc/isv/ [3] M. Petito, Eclipse Refactoring, Clarkson University,EE564 Spring
2007
[4] J. V. D. Bos ,Refactoring (in) Eclipse,August 15, 2008 [5] http://sourceforge.net/projects/moreunit/
[6] M. Fowler, Refactoring: Improving the Design of Existing Code, Addison Wesley, ISBN 0201485672, 1999
[7] http://www.ibm.com/developerworks/opensource/library/os-ecref/ [8] W. Basit et al., Extending Refactoring Guidelines to Perform Client
and Test Code Adaptation, Lecture Notes in Business Information Processing, Volume 48, Part 1, 1-13, DOI: 10.1007/978-3-642-13054-0_1, 2010
[9] W. F. Opdyke, Refactoring Object Orineted frameworks thesis, , University of Illinois at Urbana-Champaign,Urbana , 1992
[10] M. KATIĆ and K. FERTALJ ,Towards an Appropriate Software Refactoring Tool Support, Proceedings of the 9th WSEAS International Conference on APPLIED COMPUTER SCIENCE [11] Y. Cheon and G.T. Leavens, A Simple and Practical Approach to
Unit,Testing: The JML and JUnit Way ,2003
[12] T. Xie et al.,Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution, Lecture Notes in Computer Science, Volume 3440/2005, 365-381, DOI: 10.1007/978-3-540-31980-1_24, 2005
[13] K. Sen et al. ,CUTE: A Concolic Unit Testing Engine for C, ESECFSE’,05, Lisbon, Portugal, September 5–9, 2005
[14] K. Beck. Extreme programming explained. Addison-Wesley, 2000 [15] B. Walter and B. Pietrzak, Automated Generation of Unit Tests for
Refactoring, Lecture Notes in Computer Science, Volume 3092/2004 ,2004
[16] G.Meszaros and M. Fowler. xUnit Patterns: Refactoring Test Code, Addison-Wesley, 2007.
[17] http://www.eclipse.org/
[18] J. U. Pipka, “Refactoring in a “test first”-world,” in Proceedings of 3rd Int’l Conference on eXtreme Programming and Flexible Processes in Software Engineering, 2002.
[19] http://www.exampler.com/testing-com/writings/half-day-programmer.pdf [20] http://www.jetbrains.com/idea/ [21] http://netbeans.org/ [22] http://sourceforge.net/projects/cpptool/ [23] http://www.nunit.org/ [24] http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_ Page