Back to TTCN-3 Refactoring Catalog
Extract Module / Move Declarations to Another Module
Move parts of a module into a newly created module or into another existing module to improve structure and reusability.
Motivation
Modules are essential and necessary for flexibility and structure of TTCN-3 test suites. Structuring code is essential for readability on the one hand and on the other hand allows to apply other refactorings that can improve the reuse of certain parts of code (e.g. using Parameterize Module. Therefore, it should be considered to move parts that share a meaningful relationship of a long test suite into its own module (i.e. Extract Module) or into another more suitable module that already exists (i.e. Move Declarations to Module). Except for the different target modules, both refactorings are the same and thus described together in this section. Good candidates for extracting/moving may already be collected in a group. If not, a possible preceding refactoring is Group Fragments.
Mechanics
- If the target module does not exist already, create a new module as target using a name describing the identified code part in a good way.
- Copy the identified code into the target module. Copy also the complete import declarations from the source module to the target module. Dependencies between modules should generally be kept to a minimum. This should be kept in mind when extracting a module or moving declarations. Furthermore, make sure that the result of moving the chosen declarations does not create a cyclic dependency between the source module and the target module. If such a dependency occurs, this refactoring is not applicable.
- Compile.
- Remove the identified code from the source module and put an import from ... all statement at the top of the source module to import all declarations from the new module.
- Compile and validate.
- Use the Restrict Imports refactoring on the import statement in both, source and target, modules.
Example
The Example module contains type and template declarations. It is desirable to separate type and templates declarations for a better structure.
module Example {
group types {
type charstring Answer;
type integer IdentificationCode;
}
group structured {
type record PersonType {
charstring firstName,
charstring middleName,
charstring lastName
}
type record ExampleMessageType {
PersonType Person,
IdentificationCode idCode
}
}
template ExampleMessageType a_testMessage := {
Person := { "Arthur", "Dent" },
idCode := 42
}
}
A new module with the name ExampleTypes? is created which is the target module. The type declarations from module Example are copied to the target module ExampleTypes? and the corresponding declarations from the source module are removed while the template declarations reside in module Example. No import is necessary as the extracted code in module ExampleTypes? does not refer to any external declarations. The source module, however, needs to import from ExampleTypes? to have access to the required type declarations. The imports have been minimized by applying the Restrict Imports refactoring afterwards.
module ExampleTypes {
group types {
type charstring Answer;
type integer IdentificationCode;
}
group structured {
type record PersonType {
charstring firstName,
charstring middleName,
charstring lastName
}
type record ExampleMessageType {
PersonType Person,
IdentificationCode idCode
}
}
}
module Example {
import from ExampleTypes {
type PersonType, IdentificationCode, ExampleMessageType;
}
template ExampleMessageType a_testMessage := {
Person := { "Arthur", "Dent" },
idCode := 42
}
}
