Code modules | Ranorex
Help CenterUser GuideCode modules

Code modules

Though a Ranorex Recording with only smart actions, variables and user code capabilities is good enough to create robust test automation modules, it might be useful or preferable to write pure Ranorex automation code. In the following section, you learn how to create a new code module which automates the process of adding a new credential data set to the KeePass application.

In this chapter

    Creating Code Modules

    Create a new code module by clicking the ‘Add Code Module’ button at the toolbar.

    Alternatively you are able to add a new code module by using the context menu in the Test Suite.

    Specifying the name used for the code module

    After clicking the ‘Create’ button a new file is added to the project and automatically opened in the file view. Ranorex Studio creates a new test module class which contains a ‘Run’ method that is ready to be extended with test automation code.

    namespace KeePass { /// /// Description of AddCredentialEntry. /// [TestModule("03F5603B-0DDC-49AA-8C26-4D8088260C66", ModuleType.UserCode, 1)] public class AddCredentialEntry : ITestModule { /// /// Constructs a new instance. /// public AddCredentialEntry() { // Do not delete - a parameterless constructor is required! } /// /// Performs the playback of actions in this module. /// /// You should not call this method directly, instead pass the module /// instance to the method /// that will in turn invoke this method. void ITestModule.Run() { Mouse.DefaultMoveTime = 300; Keyboard.DefaultKeyPressTime = 100; Delay.SpeedFactor = 1.0; } } }
    Namespace KeePass ''' ''' Description of AddCredentialEntry. ''' _ Public Class AddCredentialEntry Implements ITestModule ''' ''' Constructs a new instance. ''' ' Do not delete - a parameterless constructor is required! Public Sub New() End Sub ''' ''' Performs the playback of actions in this module. ''' ''' You should not call this method directly, instead pass the module ''' instance to the method ''' that will in turn invoke this method. Private Sub ITestModule_Run() Implements ITestModule.Run Mouse.DefaultMoveTime = 300 Keyboard.DefaultKeyPressTime = 100 Delay.SpeedFactor = 1.0 End Sub End Class End Namespace

    Using Repository within Code Module

    In the same way you use a repository in the recording to identify UI elements for automation, you can also use it in code. Simply add a new private member which represents the repository to your code module class as shown below:

    public class AddCredentialEntry : ITestModule { // Repository object to access UI Elements MyFirstTestProjectRepository MyRepo = MyFirstTestProjectRepository.Instance; /// Constructs a new instance. public AddCredentialEntry() { // Do not delete - a parameterless constructor is required! } void ITestModule.Run() { Mouse.DefaultMoveTime = 300; Keyboard.DefaultKeyPressTime = 100; Delay.SpeedFactor = 1.0; // Click 'Add Entry' Button MainMenu MyRepo.MainForm.Edit.Click(); MyRepo.KeePass.AddEntry.Click(); // Set text fields MyRepo.AddEntry.TabSheetAddEntry.Title.TextValue = "WordPressDemo"; MyRepo.AddEntry.TabSheetAddEntry.UserName.TextValue = "admin"; MyRepo.AddEntry.TabSheetAddEntry.Password.TextValue = "demo123"; MyRepo.AddEntry.TabSheetAddEntry.Repeat.TextValue = "demo123"; MyRepo.AddEntry.TabSheetAddEntry.URL.TextValue = "bitly.com/wp_demo"; // Choose an icon MyRepo.AddEntry.TabSheetAddEntry.MBtnIcon.Click(); MyRepo.IconPicker.LI_Icon.Click(Location.CenterLeft); MyRepo.IconPicker.ButtonClose.Click(); // Set Expires MyRepo.AddEntry.TabSheetAddEntry.MBtnStandardExpires.Click(); MyRepo.KeePass.MI_Expires.Click(); // Save Credential Entry MyRepo.AddEntry.ButtonOK.Click(); } }
    Public Class AddCredentialEntry Implements ITestModule ' Repository object to access UI Elements Private MyRepo As MyFirstTestProjectRepository = MyFirstTestProjectRepository.Instance ''' Constructs a new instance. ' Do not delete - a parameterless constructor is required! Public Sub New() End Sub Private Sub ITestModule_Run() Implements ITestModule.Run Mouse.DefaultMoveTime = 300 Keyboard.DefaultKeyPressTime = 100 Delay.SpeedFactor = 1.0 ' Click 'Add Entry' Button MainMenu MyRepo.MainForm.Edit.Click() MyRepo.KeePass.AddEntry.Click() ' Set text fields MyRepo.AddEntry.TabSheetAddEntry.Title.TextValue = "WordPressDemo" MyRepo.AddEntry.TabSheetAddEntry.UserName.TextValue = "admin" MyRepo.AddEntry.TabSheetAddEntry.Password.TextValue = "demo123" MyRepo.AddEntry.TabSheetAddEntry.Repeat.TextValue = "demo123" MyRepo.AddEntry.TabSheetAddEntry.URL.TextValue = "bitly.com/wp_demo" ' Choose an icon MyRepo.AddEntry.TabSheetAddEntry.MBtnIcon.Click() MyRepo.IconPicker.LI_Icon.Click(Location.CenterLeft) MyRepo.IconPicker.ButtonClose.Click() ' Set Expires MyRepo.AddEntry.TabSheetAddEntry.MBtnStandardExpires.Click() MyRepo.KeePass.MI_Expires.Click() ' Save Credential Entry MyRepo.AddEntry.ButtonOK.Click() End Sub End Class
    Note icon

    Note

    By default the class name of a repository is the same as the repository file name (*.rxrep) shown in the project’s view.

    Now the class uses a private member to refer to the repository in order to reuse some of the objects (‘Title’, ‘Username’, ‘Password’, ‘PasswordRepeat’ and ‘URL’) within the ‘Run’ method.

    Depending on the structure of your repository, accessing items in code might become more and more complex. To reduce complexity – especially when UI elements are used more than once – you should use local variables instead of coding the whole structure of your repository everytime you need to automate a UI element.

    var ButtonOK = MyRepo.FormAdd_Entry.ButtonOK; ButtonOK.Click();
    Dim ButtonOK = MyRepo.FormAdd_Entry.ButtonOK ButtonOK.Click()

    To create local variables as shown in the code above, simply drag and drop elements from the repository browser directly into the code.

    Note icon

    Note

    If the repository itself is not already part of the class(e.g. newly created code modules), a local variable for the repository is generated too.

    Accessing Screen Shots within Code Modules

    Starting with Ranorex 3.3 it’s possible to access screen shots directly in code using the Info object of a repository item. This can be useful if you are going to compare a captured screen shot with the actual appearance of your application under test, for example.

    Note icon

    Note

    Screenshots will be captured automatically if you chose to record image based. Get more information here: ⇢ Image Based Automation.

    Screenshot captured in repository

    // get the screenshot from the repository Bitmap MyScreenshot = MyRepo.IconPicker.LI_IconInfo.GetScreenshot_Icon(); // create FindOptions with similarity set to 95% Imaging.FindOptions MyFindOptions = new Imaging.FindOptions(0.95); // compare the captured screenshot with the actual list item Validate.CompareImage(MyRepo.IconPicker.LI_Icon, MyScreenshot, MyFindOptions);
    ' get the screenshot from the repository Dim MyScreenshot As Bitmap = MyRepo.IconPicker.LI_IconInfo.GetScreenshot_Icon() ' create FindOptions with similarity set to 95% Dim MyFindOptions As New Imaging.FindOptions(0.95) ' compare the captured screenshot with the actual list item Validate.CompareImage(MyRepo.IconPicker.LI_Icon, MyScreenshot, MyFindOptions)
    Note icon

    Note

    Using the FindOptions, you can set custom values like ‘similarity’. This option allows you to define the minimum similarity that the image region to search for needs to have in common with the screenshot in order to be considered a match. For further details have a look at
    ⇢ Image Based Automation.

    Using Variables with Code Modules

    In order to use values provided by a data connector within your code modules, you need to add variables to the code. Use the context menu item ‘Insert Module Variable’.

    Add a new variable to your code module

    Specify the variable name and the default value

    By adding a new variable Ranorex Studio inserts a new code fragment at the current cursor position. A variable implementation consists of a public property ” and a private member ‘_’.

    string _varTitle = "Wordpress Credentials"; [TestVariable("9348A7E6-80B6-4A2B-9CBF-0276A236AA3E")] public string varTitle { get { return _varTitle; } set { _varTitle = value; } }
    Private _varTitle As String = "Wordpress Credentials" _ Public Property varTitle() As String Get Return _varTitle End Get Set _varTitle = value End Set End Property

    Now create additional variables for the ‘Username’, ‘Password’ and ‘URL’. All the module variables will appear immediately in the module browser.

    Accessing Repository Variables with the Use of Setter Methods

    To bind repository variables to external data when accessing the repository element via the code module, you have to create a new module variable to act as a bridge. You can use the setter method for the public variable to also set the repository variable.

    Variables used by the repository (e.g. ‘varExpires’ for the Menu Item in the context menu of KeePass’s ‘Add Entry Dialog’) are easily accessible via the repository, even from code. In order to bind these variables to external data (e.g. one row in our Excel file) in a code module you have to create a new module variable to act as a bridge between external data and repository variables. Following such an approach, it is obviously best to use the setter methods for public variables. A public variable’s setter method is called every time the value of this variable is set; i.e. assigning the value to the private variable holding the information for the public property. This method can easily be extended in order to set the repository variable as well.

    First two new module variables, ‘varExpires’ and ‘varIconIndex’, have to be created the same way as was shown for ‘varTitle’, ‘varPassword’. After that, a simple code line has to be inserted into the setter method for each variable. This code line is used for assigning the passed value to the repository variable and facilitates binding to external data.

    string _varRepoIconIndex = "1"; [TestVariable("EF09BC93-3447-4AC2-9DEB-FE3D78ED5538")] public string varRepoIconIndex { get { return _varRepoIconIndex; } set { _varRepoIconIndex = value; // Additionally set the Repository Variable in Setter-Method MyRepo.varIconIndex = _varRepoIconIndex; } } string _varRepoExpires = "1 Year"; [TestVariable("D0A54427-68FF-4B9D-B861-4882BCEC846B")] public string varRepoExpires { get { return _varRepoExpires; } set { _varRepoExpires = value; // Additionally set the Repository Variable in Setter-Method MyRepo.varExpires = _varRepoExpires; } }
    Private _varRepoIconIndex As String = "1" _ Public Property varRepoIconIndex() As String Get Return _varRepoIconIndex End Get Set _varRepoIconIndex = value ' Additionally set the Repository Variable in Setter-Method MyRepo.varIconIndex = _varRepoIconIndex End Set End Property Private _varRepoExpires As String = "1 Year" _ Public Property varRepoExpires() As String Get Return _varRepoExpires End Get Set _varRepoExpires = value ' Additionally set the Repository Variable in Setter-Method MyRepo.varExpires = _varRepoExpires End Set End Property
    Thus the two columns in the Excel file can be bound to these module variables. This binding causes the variables to be set for each iteration in the test case. When setting those variables, the extended functionality also sets the repository variable assuring that the correct icon will be used and clicked in our example.

    Using Code Modules within Test Cases

    The code module implemented above is now ready to be run by a test case. Add a new test case (‘TC_AddEntryFromCode’) to your test suite and reuse already existing modules to start KeePass, login at the beginning and to validate, delete, save and close it at the end of the test case. You can use drag and drop to quickly insert the newly created code module into the test case.

    Drag and drop the code module into a test case and combine it with recordings

    Now you can reuse the existing data connector created during ⇢ data-driven testing with your new test case.

    Reuse the existing data connector by choosing the item from the drop-down

    Bind the newly created variables to the data connector’s columns, i.e. columns from the Excel file