Instrumenting Android Applications From Scripts

Applies to TestComplete 14.40, last modified on April 22, 2021

To work with objects in an Android application, you need to instrument it. This topic explains how you can do this from scripts.

Do not submit instrumented applications to the Google Play. Instrumented applications use private APIs and will be rejected. Create a separate build configuration for test builds.

General Information

Instrumentation is needed to expose internal objects, methods and properties of Android applications to TestComplete.

To instrument an Android application, TestComplete recompiles it with the PatchServices.jar library and adds a method call to the application to initialize the library. This procedure includes the following steps:

  1. Adding your .apk file to the TestComplete project as a tested application (this is a requirement).

  2. (Optional) Creating a backup copy of your original .apk file.

  3. Modifying and recompiling the .apk file.

  4. Signing the new .apk file with a debug or custom key.

  5. Overwriting the original .apk file with its instrumented version.

You can automate all these operations in your tests by using the methods and properties of the AndroidTestedApp object that corresponds to your tested Android application. Please find detailed information below.

For information on the PatchServices.jar library and on how instrumentation affects your application, see Instrumenting Android Applications - Overview.

Instrumentation Requirements

  • For instrumentation, TestComplete uses Java modules that are part of JDK or JRE.

    The path to JDK (or JRE) is specified by the Path to Java Runtime setting of TestComplete. You can find it in the Tools | Options » Engines | Mobile | Android dialog. Setting this option is part of Android testing requirements. See Preparing Test Computers and TestComplete for Android Testing.

  • You need to add your application to the Tested Applications collection either manually or by using the TestedApps.AddAndroidApp method.

  • TestComplete replaces the existing .apk file with its instrumented version. So, the user account under which TestComplete is working needs read/write access to this file.

Instrumentation Procedure

1. Adding an APK File to Your Test Project as a Tested Application

To instrument your Android application, first, you need to add it to the Tested Applications list of your project. You can do this either manually or by using the TestedApps.AddAndroidApp method. After that, you can use the methods and properties of the AndroidTestedApp object.

2. Checking if Your Application Is Already Instrumented

Before instrumenting an application, you need to make sure that it has not been instrumented yet. To do this, use the Instrumented property. This property returns true if the application is instrumented and false otherwise.

If your application was instrumented for an earlier or later TestComplete version, it will not be recognized as Open. You need to use either an uninstrumented application, or an application instrumented for the current TestComplete version. To check if TestComplete can work with your application, use the InstrumentedWithSupportedVersion property. This property returns true if TestComplete can work with the application and false otherwise. If you use both properties, you can create a conditional statement to check if the application can be tested, if it needs to be instrumented or if you need to use a different .apk file.

JavaScript, JScript

if (!AndroidTestedApp.Instrumented)
{
  // Instrument the application
}

if (AndroidTestedApp.InstrumentedWithSupportedVersion)
{
  // Launch the application
}
else
{
  // Post an error to the log
}

Python

if not AndroidTestedApp.Instrumented:
  # Instrument the application

if AndroidTestedApp.InstrumentedWithSupportedVersion:
  # Launch the application
else:
  # Post an error to the log

VBScript

If not AndroidTestedApp.Instrumented Then
  ' Instrument the application
End If

If AndroidTestedApp.InstrumentedWithSupportedVersion Then
  ' Launch the application
Else
  ' Post an error to the log
End If

DelphiScript

if not AndroidTestedApp.Instrumented then
begin
  // Instrument the application
end;

if AndroidTestedApp.InstrumentedWithSupportedVersion then
begin
  // Launch the application
end
else
begin
  // Post an error to the log
end;

C++Script, C#Script

if (!AndroidTestedApp["Instrumented"])
{
  // Instrument the application
}

if (AndroidTestedApp["InstrumentedWithSupportedVersion"])
{
  // Launch the application
}
else
{
  // Post an error to the log
}

3. Setting Up Instrumentation Parameters

By default, TestComplete backs up the original application file and uses a debug certificate to instrument the application. If you are satisfied with the default settings, you can skip this step.

Backup Settings

When TestComplete is instrumenting an application, it creates a backup of the original file in the same folder and names it "FileName_ORIGINAL_BACKUP.apk". You can change this behavior by using the BackupOriginalAPK and BackupFileName settings.

  • If you don't want to create a copy of the file, set the BackupOriginalAPK property to false. To make sure that a backup will be created, set the property to true.

  • To save the backup file to a specific location, pass a string containing the fully qualified path to the BackupFileName property.

Below is an example of how you can set backup settings to save the backup file to the specified folder:

JavaScript, JScript

AndroidTestedApp.BackupOriginalAPK = true;
AndroidTestedApp.BackupFileName = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk";

Python

AndroidTestedApp.BackupOriginalAPK = True;
AndroidTestedApp.BackupFileName = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk";

VBScript

AndroidTestedApp.BackupOriginalAPK = true
AndroidTestedApp.BackupFileName = "C:\Android\apks\SampleApp_ORIGINAL_BACKUP.apk"

DelphiScript

AndroidTestedApp.BackupOriginalAPK := true;
AndroidTestedApp.BackupFileName := 'C:\Android\apks\SampleApp_ORIGINAL_BACKUP.apk';

C++Script, C#Script

AndroidTestedApp["BackupOriginalAPK"] = true;
AndroidTestedApp["BackupFileName"] = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk";

Custom Certificate Settings

By default, TestComplete signs applications with the debug certificate. To use a custom certificate, you need to set the following properties:

  • The UseCustomCertificate property specifies whether TestComplete will sign the application with a custom certificate. To use a custom certificate, set the option to true.

  • The KeystorePath property specifies the path to the keystore containing the key that TestComplete will use to sign the certificate.

  • The KeystorePassword property specifies the password that TestComplete uses to access the keystore.

  • The KeyAlias property specifies the alias of the key used to sign the application.

  • The KeyPassword property specifies the password to the key used to sign the application.

Below is an example of how you can set the instrumentation properties to use a custom certificate:

JavaScript, JScript

AndroidTestedApp.UseCustomCertificate = true;
AndroidTestedApp.KeystorePath = "C:\\Android\\Keystore";
AndroidTestedApp.KeystorePassword = "KstrPass";
AndroidTestedApp.Alias = "KeyAlias";
AndroidTestedApp.KeyPassword = "KeyPass";

Python

AndroidTestedApp.UseCustomCertificate = True;
AndroidTestedApp.KeystorePath = "C:\\Android\\Keystore";
AndroidTestedApp.KeystorePassword = "KstrPass";
AndroidTestedApp.Alias = "KeyAlias";
AndroidTestedApp.KeyPassword = "KeyPass";

VBScript

AndroidTestedApp.UseCustomCertificate = true
AndroidTestedApp.KeystorePath = "C:\Android\Keystore"
AndroidTestedApp.KeystorePassword = "KstrPass"
AndroidTestedApp.Alias = "KeyAlias"
AndroidTestedApp.KeyPassword = "KeyPass"

DelphiScript

AndroidTestedApp.UseCustomCertificate := true;
AndroidTestedApp.KeystorePath := 'C:\Android\Keystore';
AndroidTestedApp.KeystorePassword := 'KstrPass';
AndroidTestedApp.Alias := 'KeyAlias';
AndroidTestedApp.KeyPassword := 'KeyPass';

C++Script, C#Script

AndroidTestedApp["UseCustomCertificate"] = true;
AndroidTestedApp["KeystorePath"] = "C:\\Android\\Keystore";
AndroidTestedApp["KeystorePassword"] = "KstrPass";
AndroidTestedApp["Alias"] = "KeyAlias";
AndroidTestedApp["KeyPassword"] = "KeyPass";

4. Instrumenting Your Application

To instrument an application, use the Instrument method. The method recompiles your application and overwrites the original .apk file with its instrumented version. There is no need to pass any parameters to it. The method uses the values you assigned to the properties of the AndroidTestedApp object:

JavaScript, JScript

...
// Setting properties
...
AndroidTestedApp.Instrument();
...

Python

...
# Setting properties
...
AndroidTestedApp.Instrument();
...

VBScript

...
' Setting properties
...
AndroidTestedApp.Instrument()
...

DelphiScript

...
// Setting properties
...
AndroidTestedApp.Instrument();
...

C++Script, C#Script

...
// Setting properties
...
AndroidTestedApp["Instrument"]();
...

An Example of Full Instrumentation

The sample code below demonstrates how to add a new Android application to the list of tested applications, check if it is instrumented (and instrument it if needed), specify the application’s properties and run the application.

JavaScript, JScript

function AddAndroidApplication()
{

  // Sets the current device
  Mobile.SetCurrent("MyDevice");

  // Adds the Android application from the package and obtains its index in the list of tested applications
  var ind = TestedApps.AddAndroidApp("C:\\Android\\apks\\SampleApp.apk");

  // Obtains the added tested application by its index and specifies its properties
  var AndroidTestedApp = TestedApps.Items(ind);
  AndroidTestedApp.DeployOnStart = true;
  AndroidTestedApp.Launch = true;
  AndroidTestedApp.GrantPermissions = true;
  AndroidTestedApp.KeepDataAndCache = false;
  
  // Checks if the applications is instrumented
  if (!AndroidTestedApp.Instrumented)
  {
    // Sets up backup parameters
    AndroidTestedApp.BackupOriginalAPK = true;
    AndroidTestedApp.BackupFileName = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk";
    // Sets up custom certificate parameters
    AndroidTestedApp.UseCustomCertificate = true;
    AndroidTestedApp.KeystorePath = "C:\\Android\\Keystore";
    AndroidTestedApp.KeystorePassword = "KstrPass";
    AndroidTestedApp.Alias = "KeyAlias";
    AndroidTestedApp.KeyPassword = "KeyPass";
    AndroidTestedApp.Instrument();
  }

  // Checks if TestComplete can work with the instrumented application
  if (AndroidTestedApp.InstrumentedWithSupportedVersion)
  {
    // Launches the application
    AndroidTestedApp.Run();
  }
  else
  {
    // Posts an error to the log
    Log.Error("Please use uninstrumented application or application instrumented for the current TestComplete version");
  }
}

Python

def AddAndroidApplication():
  # Sets the current device
  Mobile.SetCurrent("MyDevice")

  # Adds the Android application from the package and obtains its index in the list of tested applications
  ind = TestedApps.AddAndroidApp("C:\\Android\\apks\\SampleApp.apk")

  # Obtains the added tested application by its index and specifies its properties
  AndroidTestedApp = TestedApps.Items[ind]
  AndroidTestedApp.DeployOnStart = True
  AndroidTestedApp.Launch = True
  AndroidTestedApp.GrantPermissions = True
  AndroidTestedApp.KeepDataAndCache = False
   
  # Checks if the applications is instrumented
  if (not AndroidTestedApp.Instrumented):
    # Sets up backup parameters
    AndroidTestedApp.BackupOriginalAPK = True
    AndroidTestedApp.BackupFileName = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk"
    # Sets up custom certificate parameters
    AndroidTestedApp.UseCustomCertificate = True
    AndroidTestedApp.KeystorePath = "C:\\Android\\Keystore"
    AndroidTestedApp.KeystorePassword = "KstrPass"
    AndroidTestedApp.Alias = "KeyAlias"
    AndroidTestedApp.KeyPassword = "KeyPass"
    AndroidTestedApp.Instrument()

  # Checks if TestComplete can work with the instrumented application
  if (AndroidTestedApp.InstrumentedWithSupportedVersion):
    # Launches the application
    AndroidTestedApp.Run()
  else:
   # Posts an error to the log
   Log.Error("Please use uninstrumented application or application instrumented for the current TestComplete version")

VBScript

Sub AddAndroidApplication

  ' Sets the current device
  Mobile.SetCurrent("MyDevice")

  ' Adds the Android application from the package and obtains its index in the list of tested applications
  ind = TestedApps.AddAndroidApp("C:\Android\apks\SampleApp.apk")

  ' Obtains the added tested application by its index and specifies its properties
  Set AndroidTestedApp = TestedApps.Items(ind)
  AndroidTestedApp.DeployOnStart = True
  AndroidTestedApp.Launch = True
  AndroidTestedApp.GrantPermissions = True
  AndroidTestedApp.KeepDataAndCache = False
  
  ' Checks if the applications is instrumented
  If not AndroidTestedApp.Instrumented Then
    ' Sets up backup parameters
    AndroidTestedApp.BackupOriginalAPK = true
    AndroidTestedApp.BackupFileName = "C:\Android\apks\SampleApp_ORIGINAL_BACKUP.apk"
    ' Sets up custom certificate parameters
    AndroidTestedApp.UseCustomCertificate = true
    AndroidTestedApp.KeystorePath = "C:\Android\Keystore"
    AndroidTestedApp.KeystorePassword = "KstrPass"
    AndroidTestedApp.Alias = "KeyAlias"
    AndroidTestedApp.KeyPassword = "KeyPass"
    ' Instruments the application
    AndroidTestedApp.Instrument()
  End If

  ' Checks if TestComplete can work with the instrumented application
  If AndroidTestedApp.InstrumentedWithSupportedVersion Then
    ' Launches the application
    AndroidTestedApp.Run()
  Else
    ' Posts an error to the log
    Log.Error("Please use uninstrumented application or application instrumented for the current TestComplete version")
  End If
End Sub

DelphiScript

procedure AddAndroidApplication();
var 
  ind, AndroidTestedApp;
begin

  // Sets the current device
  Mobile.SetCurrent('MyDevice');

  // Adds the Android application from the package and obtains its index in the list of tested applications
  ind := TestedApps.AddAndroidApp('C:\Android\apks\SampleApp.apk');

  // Obtains the added tested application by its index and specifies its launch properties
  AndroidTestedApp := TestedApps.Items[ind];
  AndroidTestedApp.DeployOnStart := true;
  AndroidTestedApp.Launch := true;
  AndroidTestedApp.GrantPermissions := true;

  AndroidTestedApp.KeepDataAndCache := false;

  // Checks if the applications is instrumented
  if not AndroidTestedApp.Instrumented then
  begin
    // Sets up backup parameters
    AndroidTestedApp.BackupOriginalAPK := true;
    AndroidTestedApp.BackupFileName := 'C:\Android\apks\SampleApp_ORIGINAL_BACKUP.apk';
    // Sets up custom certificate parameters
    AndroidTestedApp.UseCustomCertificate := true;
    AndroidTestedApp.KeystorePath := 'C:\Android\Keystore';
    AndroidTestedApp.KeystorePassword := 'KstrPass';
    AndroidTestedApp.Alias := 'KeyAlias';
    AndroidTestedApp.KeyPassword := 'KeyPass';
    // Instruments the application
    AndroidTestedApp.Instrument();
  end;

  // Checks if TestComplete can work with the instrumented application
  if AndroidTestedApp.InstrumentedWithSupportedVersion then
    // Launches the application
    AndroidTestedApp.Run()
  else
    // Posts an error to the log
    Log.Error('Please use uninstrumented application or application instrumented for the current TestComplete version');
end;

C++Script, C#Script

function AddAndroidApplication()
{

  // Sets the current device
  Mobile["SetCurrent"]("MyDevice");

  // Adds the Android application from the package and obtains its index in the list of tested applications
  var ind = TestedApps["AddAndroidApp"]("C:\\Android\\apks\\SampleApp.apk");

  // Obtains the added tested application by its index and specifies its properties
  var AndroidTestedApp = TestedApps["Items"](ind);
  AndroidTestedApp["DeployOnStart"] = true;
  AndroidTestedApp["Launch"] = true;
  AndroidTestedApp["GrantPermissions"] = true;
  AndroidTestedApp["KeepDataAndCache"] = false;
  
  // Checks if the applications is instrumented
  if (!AndroidTestedApp["Instrumented"])
  {
    // Sets up backup parameters
    AndroidTestedApp["BackupOriginalAPK"] = true;
    AndroidTestedApp["BackupFileName"] = "C:\\Android\\apks\\SampleApp_ORIGINAL_BACKUP.apk";
    // Sets up custom certificate parameters
    AndroidTestedApp["UseCustomCertificate"] = true;
    AndroidTestedApp["KeystorePath"] = "C:\\Android\\Keystore";
    AndroidTestedApp["KeystorePassword"] = "KstrPass";
    AndroidTestedApp["Alias"] = "KeyAlias";
    AndroidTestedApp["KeyPassword"] = "KeyPass";
    // Instruments the application
    AndroidTestedApp["Instrument"]();
  }

  // Checks if TestComplete can work with the instrumented application
  if (AndroidTestedApp["InstrumentedWithSupportedVersion"])
  {
    // Launches the application
    AndroidTestedApp["Run"]();
  }
  else
  {
    // Posts an error to the log
    Log["Error"]("Please use uninstrumented application or application instrumented for the current TestComplete version");
  }
}

Installing TestComplete Android Agent

In order for TestComplete to work with your instrumented Android Open Application, you need to install TestComplete Android Agent on your device. For complete information about the Agent and installation steps, see the Agent description.

See Also

Preparing for Testing Android Applications
Instrumenting Android Applications - Overview
About Testing Android Applications

Highlight search results