Test-driven development (TDD) is commonly used for open-source projects like Umple, a language for object-oriented programming and modeling. All development of Umple uses TDD principles, which leads to more manageable code. TDD involves writing automated tests before code, then writing minimum code to pass tests, and refactoring code. Umple development uses a continuous integration process that works well with TDD by immediately testing any committed code changes. A practical example shows how refactoring code in Umple uses the TDD process of writing new tests, making code pass tests, and cleaning up code.
2. Introduction
Test-driven development is a very common
development process for open-source
software projects, especially those which
adhere to Agile principles or which use
continuous integration.
All development for the open-source UML
programming language, Umple, should be
done using TDD principles. This decision
leads to more manageable, understandable
code.
3. Umple
Umple is a language used for both object-oriented
programming and modeling with class and state
diagrams.
The name Umple is a portmanteau of “UML”, “ample”,
and “programming language”. This is meant to convey
that Umple provides ample features to extend
programming languages with UML capabilities, such
as Java, PHP, or Ruby. Code can also be generated
in these mentioned languages from a source Umple
file.
Created in 2008, Umple was open-sourced in 2011
when it was released publicly on Google Code.
4. Test-driven development (TDD)
TDD is a software development process with two
main rules:
1. Don‟t write a new line of code unless you have a
failing automated test.
2. Eliminate duplication.
These two rules imply an order to the tasks of
programming in a TDD environment:
• Developer writes an (initially failing) automated test
case that defines the desired improvement or new
functionality
• Developer writes the minimum code required to
pass the automated test case
• Developer refactors the new code to acceptable
standards
5. “Red/green/refactor”
The TDD mantra, “Red/green/refactor” is visually
depicted as a repetitive process in the figure below.
6. Benefits of TDD
By writing automated tests first during
development, we can:
• Fully imagine and plan our changes before
actually implementing them
• Ensure the changes produce expected
behaviours
• Changes must be fully tested on a developer‟s
local environment before they are committed to
source
• Ensure the changes don‟t affect other areas
of the source code
• Potentially catch errors we may have
missed without tests
7. Testing in Umple
There are several levels of testing in the Umple compiler.
Testing also exists for all of the non-compiler components.
The primary levels of compiler testing are as follows:
• Parser tests verify that a construct parses correctly
• Metamodel tests check that the metamodel is populated
correctly by the various umple constructs
• Template tests verify that the generated output in
languages like Java is as expected
• Testbed tests verify that compiled code that generates
languages such as Java can then compile under the
language compiler
• User manual tests verify that examples in the user
manual can properly run
The separation of testing levels comes naturally from the
hierarchal components of Umple‟s architecture.
8. TDD & Umple
TDD complements the collaborative and
distributed way in which Umple is developed
Umple is developed using a continuous
integration process, which works very well
with TDD
The continuous integration process makes it so that
any changes committed to the Umple source
repository are immediately tested to ensure that
they do not negatively effect the build
9. TDD & Umple cont‟d
The figure below shows an example of the continuous
integration process which relies on TDD. Changes are
committed to the code base until an error is detected by
the build process. Once an error is detected, action must
be taken to resolve that error before any other new
commits can be integrated into the source repository.
10. Practical Example – Refactoring Some Code
Revision r3915 provides a clean example of how
refactoring can work in a TDD environment.
The goal of this revision was to extract a portion of code
from the method „checkDefaultedNameConflict()‟ in the
„UmpleInternalParser_Code.ump‟ class so said code
could be put into its own method and used in other
places.
Instead of having this code at the parser level, it makes
more sense to have it at the model level.
11. Practical Example – Refactoring cont‟d
Steps taken to complete code changes in Revision
r3915:
1. Analysed the code needing to be extracted and determine
where it will reside once it has been refactored.
In this case, the code was suited to be moved to the „UmpleModel‟
class
The figure below shows the code needing to be extracted in red
12. Practical Example – Refactoring cont‟d
Steps taken to complete code changes in Revision
r3915:
2. (RED) - Wrote unit tests for the new method based on
expected behaviour.
All of the tests went in the „UmpleModelTest‟ class (at the
metamodel level) as can be seen in the figure below
These tests all initially failed (wouldn‟t even compile) because the
new method had not been created yet
13. Practical Example – Refactoring cont‟d
Steps taken to complete code changes in Revision
r3915:
(GREEN) - Created the new method in its new location and ran
the unit tests
In the „UmpleModel‟ class, the new method „getAllTranslators()‟ was
created using code extracted from the „checkDefaultedNameConflict()‟
method, as can be seen in the figure below
Ran tests and they all passed; therefore, new method behaved as
expected
If tests hadn‟t passed, would have modified the method and run the
tests again
14. Practical Example – Refactoring cont‟d
Steps taken to complete code changes in Revision
r3915:
(REFACTOR) – Cleaned up code to use the refactored
changes
Changed the code in „checkDefaultedNameConflict()‟ method so
the new method was being used
The figure below shows the refactored code in green
15. Conclusion
The TDD process integrates very well with the
distributed nature of development on an open-
source project.
By adhering to TDD principles, contributors to the
Umple project are ensuring that the code is
reliable and maintainable, and are making it easier
for new developers to contribute in the future.