18 Testing and Debugging ADF Mobile Applications

This chapter provides information on testing and debugging ADF Mobile applications developed for both iOS and Android platforms.

This chapter includes the following sections:

18.1 Introduction to Testing and Debugging ADF Mobile Applications

Before you start any testing and debugging of your ADF Mobile application, you have to deploy it to one of the following:

  • iOS-powered device

  • iOS-powered device simulator

  • Android-powered device

  • Android-powered device emulator

You cannot run the ADF Mobile application until it is deployed. For more information, see Chapter 16, "Deploying ADF Mobile Applications."

To test and debug an ADF Mobile application, you generally take the following steps:

  1. Test the application's infrastructure, such as a splash screen, application feature navigation, authentication, and preferences, ensuring that all declared application features are available.

  2. If the application includes ADF Mobile AMX content, test this application feature's logic, page flows, data controls, and UI components.

  3. Make changes to the application as necessary.

  4. Reconnect the mobile device or restart the simulator, and then deploy and run the application for further testing and debugging.

For more information, see the following:

18.2 Testing ADF Mobile Applications

There are two approaches to testing an ADF Mobile application:

  1. Testing on a mobile device: this method always provides the most accurate behavior, and is also necessary to gauge the performance of your application. However, you may not have access to all the devices on which you wish to test, making device testing inconclusive.

  2. Testing on a mobile device emulator or simulator: this method usually offers better performance and faster deployment, as well as convenience. However, even though a device emulator or simulator closely approximates the corresponding physical device, there might be differences in behavior and limitations on the capabilities that can be emulated.

Typically, a combination of both approaches yields the best results.

18.2.1 How to Perform Accessibility Testing on iOS-Powered Devices

You should use a combination of the following methods to test the accessibility of your ADF Mobile application developed for iOS-powered devices:

  • Testing with the Accessibility Inspector on an iOS-powered device simulator.

    For detailed information, see the "Testing the Accessibility of Your iPhone Application" section in Accessibility Programming Guide for iOS, which is available through the iOS Developer Library (http://developer.apple.com/library/ios/navigation/).

  • Testing with the VoiceOver on an iOS-powered device.

    For more information, see the "Using VoiceOver to Test Your Application" section in Accessibility Programming Guide for iOS, which is available through the iOS Developer Library (http://developer.apple.com/library/ios/navigation/).

18.3 Debugging ADF Mobile Applications

JDeveloper is equipped with debugging mechanisms that allow you to execute a Java program in debug mode and use standard breakpoints to monitor and control execution of an Oracle ADF application. For more information, see the section on debugging applications in Oracle Fusion Middleware User's Guide for Oracle JDeveloper.

Since an ADF Mobile application cannot be run inside JDeveloper, the debugging approach is different: you can use the JDeveloper debugger to connect to a Java Virtual Machine (JVM) 1.4 instance on a mobile device or simulator and control the Java portions of your deployed ADF Mobile application.

The following are the steps you need to take to use JDeveloper to debug the Java code in your ADF Mobile application:

  1. Configure the project properties for remote debugging. This step involves creating an ADF Model debugging configuration as follows:

    1. From the JDeveloper's main menu, click Application > Project Properties to open the Project Properties dialog.

    2. In the Project Properties dialog, select the Run/Debug/Profile node.

    3. Using the Run Configurations pane of the Run/Debug/Profile dialog, create a new configuration, or click Edit to modify an existing one.

    4. In the Edit Run Configuration > Launch Settings dialog, select Remote Debugging.

    5. Expand the Tools Settings node of the Edit Run Configuration dialog, then expand Debugger, and then select Remote.

    6. In the Edit Run Configuration > Remote dialog that Figure 18-1 shows, perform the following configurations:

      - Set the protocol to Attach to JPDA.

      - Set the host to one of the following: 1) For simulator or emulator debugging, set to localhost; 2) For the device debugging, ensure that your development computer can access that device over the network (you may use the ping command to test network access), and then enter the device's IP address.

      - Set the port to the appropriate port number.

      - Set the timeout to 2.

      Figure 18-1 Configuring Remote Debugging

      Select Attach to JPDA.
  2. Deploy the application to a mobile device or simulator (see Section 18.3.1, "How to Debug on iOS Platform" or Section 18.3.2, "How to Debug on Android Platform").

  3. Specify the following debugging parameters in the cvm.properties file:

    java.debug.enabled=true
    java.debug.port=4000
    

    The port number must match the one you set in JDeveloper.

    For more information, see Section 18.3.4, "How to Enable Debugging of Java Code and JavaScript."

  4. Redeploy the application to the mobile device or simulator.

  5. Launch the application in a mobile device or simulator by clicking the application icon.

  6. Start the debugger from JDeveloper as follows:

    1. Use the debug icon on JDeveloper's main menu to select the run configuration (the one that you defined for your project in step 3).

    2. Confirm the debugger Attach to JPDA Debugger dialog.

Note:

To avoid timeout (20 seconds), start the debugger immediately after launching the application on the mobile device or simulator.

If you use the mobile device for debugging, you have to connect through WiFi.

For additional information, see the following:

18.3.1 How to Debug on iOS Platform

To debug an ADF Mobile application on the iOS platform using JDeveloper, follow the generic debugging procedure described in Section 18.3, "Debugging ADF Mobile Applications."

For information on how to configure an iOS-powered device or simulator and how to deploy an ADF Mobile application for debugging, see the following:

18.3.2 How to Debug on Android Platform

To debug an ADF Mobile application on the Android platform using JDeveloper, follow the generic debugging procedure described in Section 18.3, "Debugging ADF Mobile Applications."

For information on how to configure an Android-powered device or emulator and how to deploy an ADF Mobile application for debugging, see Section 16.3.1, "How to Deploy an Android Application to an Android Emulator."

When you debug Java code, either on an Android-powered device connected through USB or on an Android-powered device emulator, you need to forward the TCP port by executing the following command on a terminal:

  • For the device debugging:

    adb -d forward tcp:<host port> tcp:<target port>

  • For the emulator debugging:

    adb -e forward tcp:<host port> tcp:<target port>

For example, executing adb -d forward tcp:4510 tcp:4510 forwards the device TCP port 4510 to the host TCP port 4510. Upon execution, the debugging settings in the cvm.properties file (see Section 18.3.4, "How to Enable Debugging of Java Code and JavaScript") should be defined as follows:

java.debug.enabled=true

java.debug.port=4510

Note:

If the connection is made through Wi-Fi, ensure that this connection is correct. It is recommended to place both the debugger and target on the same network without the use of the virtual private network (VPN).

18.3.3 How to Debug the ADF Mobile AMX Content

If your ADF Mobile application includes the ADF Mobile AMX content, after you configure the device or emulator, you can set breakpoints, view the contents of variables, and inspect the method call stack just as you would when debugging a web-based ADF Faces application. For more information, see the "Testing and Debugging ADF Components" section in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Note:

You can only debug your Java code and JavaScript (see Section 18.3.4, "How to Enable Debugging of Java Code and JavaScript"). Debugging of EL expressions or other declarative elements is not supported.

18.3.4 How to Enable Debugging of Java Code and JavaScript

A cvm.properties file allows you to specify startup parameters for the JVM and web views of ADF Mobile to enable debugging of the Java code and JavaScript. The cvm.properties file is automatically created and placed in your project's Descriptors/META-INF directory (see Section 18.5, "Using and Configuring Logging").

You can use the following debugging properties in the cvm.properties file:

  • java.debug.enabled: Enables or disables Java debugging for ADF Mobile. Valid values are true and false.

    Caution:

    When java.debug.enabled is set to true, the JVM waits for a debugger to establish a connection to it. Failure of the debugger to connect will result in the failure of the ADF Mobile AMX application feature to load.

  • java.debug.port: Specifies the port to be used during debugging. The valid value is an integer.

  • javascript.debug.enabled: Enables or disables JavaScript debugging when the application is running in the device simulator. Valid values are true and false.

  • javascript.debug.feature: Specifies the application feature that is to trigger the activation of JavaScript debugging in ADF Mobile. The format of the value is featureId:port . The port must be specified (it is initially set to a placeholder value).

The contents of the cvm.properties file may be similar to the following:

java.debug.enabled=true
java.debug.port=8000
javascript.debug.enabled=true
javascript.debug.feature=products:8888

After the cvm.properties file has been configured to debug JavaScript, you can navigate to the following URL to see a listing of all the loaded pages that can be debugged in ADF Mobile:

http://localhost:9999

Caution:

Problems may arise if you debug JavaScript on a computer shared by multiple instances of an iOS-powered device simulator: if multiple instances of an iOS-powered device simulator are running, you might not be able to connect to your specific instance, which will prevent the debugging page from displaying.

For information on how to use JDeveloper to debug the Java code, see Section 18.3, "Debugging ADF Mobile Applications."

18.4 Using the Debug Mode

You use the application's deployment profile to specify either the release or debug execution mode for your ADF Mobile application. The debug mode allows for inclusion of special debugging libraries and symbols at compile time.

Figure 18-2 shows how to set the debug mode option on Android.

Figure 18-2 Setting Debug Mode for Android

Setting Debug Mode for Android

Figure 18-3 shows how to set the debug mode option on iOS.

Figure 18-3 Setting Debug Mode for iOS

Setting Debug Mode for iOS

For more information, see the following:

18.5 Using and Configuring Logging

For your ADF Mobile application, you can enable logging on Android and iOS platforms, through JavaScript and embedded code, all using a single configuration with the log output, including the output produced by System.out.println and System.err.println statements, directed to a single file.

The default ADF Mobile's logging process is as follows:

  • The logging begins at application startup.

  • The existing log file from the previous application run is deleted, so only the contents of the current run are available.

  • When you are running your application on an iOS-powered device simulator, all logging output is sent to the console, which you can access through the Application/Utilities directory on your development computer.

    When you are running your application on an iOS-powered device, the console output is redirected to an application.log file that is placed in the Documents/logs directory of your application.

    On Android, the output is forwarded to a text file with the same name as the application. The output file location is /sdcard. If this location is not present or is configured as read-only, the log output is rerouted to the application's writable data directory.

  • The logging.properties file is created in /.adf/META-INF directory and added to the application under the Application Resources (see Section 4.2.2.1, "About the Application-Level Resources"). In this file, it is defined that all loggers use the com.sun.util.logging.ConsoleHandler and SimpleFormatter, and the log level is set to SEVERE. You can edit this file to specify different logging behavior (see Section 18.5.1, "How to Configure Logging Using the Properties File").

    Note:

    In your ADF Mobile application, you cannot use loggers from the java.util.logging package.

ADF Mobile loggers are declared in the oracle.adfmf.util.Utility class as follows:

public static final String APP_LOGNAME = "oracle.adfmf.application";
public static final Logger ApplicationLogger = Logger.getLogger(APP_LOGNAME);

public static final String FRAMEWORK_LOGNAME = "oracle.adfmf.framework";
public static final Logger FrameworkLogger = Logger.getLogger(FRAMEWORK_LOGNAME);

The logger that you are to use in your ADF Mobile application is the ApplicationLogger.

You can also use methods of the oracle.adfmf.util.logging.Trace class.

For more information, see Oracle Fusion Middleware Java API Reference for Oracle ADF Mobile.

18.5.1 How to Configure Logging Using the Properties File

Example 18-1 shows the logging.properties file that you use to configure logging.

Example 18-1 logging.properties File

# default - all loggers to use the ConsoleHandler
.handlers=com.sun.util.logging.ConsoleHandler
# default - all loggers to use the SimpleFormatter
.formatter=com.sun.util.logging.SimpleFormatter

oracle.adfmf.util.logging.ConsoleHandler.formatter=
             oracle.adfmf.util.logging.PatternFormatter
oracle.adfmf.util.logging.PatternFormatter.pattern=
             [%LEVEL%-%LOGGER%-%CLASS%-%METHOD%]%MESSAGE%

#configure the framework logger to only use the adfmf ConsoleHandler
oracle.adfmf.framework.useParentHandlers=false
oracle.adfmf.framework.handlers=oracle.adfmf.util.logging.ConsoleHandler
oracle.adfmf.framework.level=SEVERE

#configure the application logger to only use the adfmf ConsoleHandler
oracle.adfmf.application.useParentHandlers=false
oracle.adfmf.application.handlers=oracle.adfmf.util.logging.ConsoleHandler
oracle.adfmf.application.level=SEVERE

The oracle.adfmf.util.logging.ConsoleHandler plays the role of the receiver of the custom formatter.

The oracle.adfmf.util.logging.PatternFormatter allows the following advanced formatting tokens that enable log messages to be printed:

  • %LEVEL%—the logging level.

  • %LOGGER%—the name of the logger to which the output is being written.

  • %CLASS%—the class that is being logged.

  • %METHOD%—the method that is being logged.

  • %TIME%—the time the logging message was sent.

  • %MESSAGE%—the actual message.

The following logging levels are available:

  • SEVERE: this is a message level indicating a serious failure.

  • WARNING: this is a message level indicating a potential problem.

  • INFO: this is a message level for informational messages.

  • FINE: this is a message level providing tracing information.

  • FINER: this level indicates a fairly detailed tracing message.

  • FINEST: this level indicates a highly detailed tracing message.

Caution:

When selecting the amount of verbosity for a logging level, keep in mind that by increasing the verbosity of the output at the SEVERE, WARNING, and INFO level negatively affects performance of your application.

The logger defined in the logging.properties file matches the logger obtained from the oracle.adfmf.util.Utility class (see Section 18.5, "Using and Configuring Logging"). The logging levels also match. If you decide to use the logging level that is more fine-grained than INFO, you have to change the ConsoleHandler's logging level to the same level, as Example 18-2 shows.

Example 18-2 Setting Very Fine-Grained Logging Level

oracle.adfmf.util.logging.ConsoleHandler.formatter=
             oracle.adfmf.util.logging.PatternFormatter
oracle.adfmf.util.logging.ConsoleHandler.level=FINEST
oracle.adfmf.util.logging.PatternFormatter.pattern=
             [%LEVEL%-%LOGGER%-%CLASS%-%METHOD%]%MESSAGE%

18.5.2 How to Use JavaScript Logging

JavaScript writes the output to the console.log or.error/.warn/.info. This output is redirected into the file through the System.out utility.

You customize the log output by supplying a message. The following JavaScript code produces "Message from JavaScript" output:

<script type="text/javascript" charset="utf-8">
   function test_function() { console.log("Message from JavaScript"); }
</script>

To make use of the properties defined in the logging file, you need to use the adf.mf.log package and the Application logger that it provides.

The following logging levels are available:

  • adf.mf.log.level.SEVERE

  • adf.mf.log.level.WARNING

  • adf.mf.log.level.INFO

  • adf.mf.log.level.CONFIG

  • adf.mf.log.level.FINE

  • adf.mf.log.level.FINER

  • adf.mf.log.level.FINEST

To trigger logging, use the adf.mf.log.Application logger's logp method and specify the following through the method's parameters:

  • the logging level

  • the current class name as a String

  • the current method as a String

  • the message string as a String

Example 18-3 shows how to use the logp method in an ADF Mobile application.

Example 18-3 Using Logging Method

adf.mf.log.Application.logp(adf.mf.log.level.WARNING,
                            "myClass",
                            "myMethod",
                            "My Message");

Upon execution of the logp method, the following output is produced:

[WARNING - oracle.adfmf.application - myClass - myMethod] My Message

18.5.3 How to Use Embedded Logging

Embedded logging uses the com.sun.util.logging.Logger, as illustrated in Example 18-4.

Example 18-4 Using Embedded Logging

import com.sun.util.logging.Level;
import com.sun.util.logging.Logger;
import oracle.adfmf.util.logging.*;
...
   Utility.ApplicationLogger.logp(Level.WARNING, 
                                  EmbeddedClass.class.getName(),
                                  "onTestMessage",
                                  "embedded warning message 1");
   Logger.getLogger(Utility.APPLICATION_LOGNAME).logp(Level.WARNING,
                                                 this.getClass().getName(),
                                                 "onTestMessage",
                                                 "embedded warning message 2");
   Logger.getLogger("oracle.adfmf.application").logp(Level.WARNING,
                                                this.getClass().getName(),
                                                "onTestMessage",
                                                "embedded warning message 3");

The preceding code produces the following output:

[WARNING - oracle.adfmf.application - EmbeddedClass - onTestMessage] embedded warning message 1
[WARNING - oracle.adfmf.application - EmbeddedClass - onTestMessage] embedded warning message 2
[WARNING - oracle.adfmf.application - EmbeddedClass - onTestMessage] embedded warning message 3