Back to TTCN-3 Refactoring Catalog

Generalize Runs On

Change the component in the runs on clause of a function, test case or altstep to a more general component to improve reusability.

Motivation

Functions, test cases and altsteps running on a component typically use ports, constants, variables or timers which are part of this component (source component). When another component (target component) is available that contains exactly the ports, constants, variables and timers that are used in this function, test case or altstep and the target component is a subset of the source component (in terms of the declarations local to the component), the runs on clause of the function, test case or altstep may be generalized and hence changed to the target component. As a result, the reuse is improved since it may be used with any component which is an extension or superset of the target component. In the extreme case, the runs on clause can be removed entirely when no component element is referenced at all.

Note that the source component is not necessarily an extension of the target component. Type compatibility rules in TTCN-3 allow the use of a function, test case or altstep running on component a to be used with any component b that contains all declarations of a with the same identifier names, types and initialization values. In addition, note that the runs on clause in a local test architecture implicitly defines the interface towards the SUT and should not simply be changed.

Mechanics

  • If no element of the source component is referenced in a function or altstep, the runs on clause can be removed entirely. Otherwise, follow the subsequent steps. Test cases must always have a runs on clause.
  • Find all components containing a subset of the declarations in the source component. These components must have the same identifier names, types and initializations values for its elements.
  • From these found components, find the most minimal component which is still compatible with the concerned function, test case or altstep, i.e. it must have all declarations which are referenced in the function, test case or altstep and it must have the fewest declarations. This is the target component.
  • Change the runs on specification in concerned function, test case or altstep to use the target component instead of the source component.
  • If the test suite is using a local test architecture, the original runs on clause implicitly defined the interface towards the SUT if there was no additional system clause. In this case, add the source component to a new system clause of the function, test case or altstep.
  • Compile and validate.

Example

There are three components, MySuperComponent?, mySecondSuperComponent and MySubComponent?. MySuperComponent? and mySecondSuperComponent are extensions of MySubComponent? and hence the declaration myIntegerVar is also part of MySuperComponent? and MySecondSuperComponent?. The function f_myFunction runs on MySuperComponent?, but actually uses only myIntegerVar.

type component MySuperComponent extends MySubComponent { 
	var charstring myCharstring; 
} 

type component MySecondSuperComponent extends MySubComponent { 
	var boolean myBoolean; 
} 

type component MySubComponent { 
	var integer myIntegerVar; 
} 

function f_myFunction() runs on MySuperComponent { 
	myIntegerVar := 255; 
} 

In order to use f_myFunction with MySecondSuperComponent? as well, the runs on clause must be generalized. The only component which is a subset of MySuperComponent? and is compatible with f_myFunction is MySubComponent?. Hence, after applying the Generalize Runs On refactoring, the runs on clause of f_myFunction is changed to MySubComponent? and f_myFunction can be used with the components MySuperComponent?, MySecondSuperComponent? and MySubComponent? now.

type component MySuperComponent extends MySubComponent { 
	var charstring myCharstring;
}

type component MySecondSuperComponent extends MySubComponent {
	var boolean myBoolean;
}

type component MySubComponent {
	var integer myIntegerVar;
}

function f_myFunction() runs on MySubComponent { 
	myIntegerVar := 255;
}

Back to TTCN-3 Refactoring Catalog