Fabrice31
Fabrice31

Reputation: 760

How to find app version with appium on iOS

When I launch my tests, I want a lots of debug informations : device used, operating system, and version of the app tested.

My problem is about the version of the app.

On Android, I use :

String line = "adb -s " + udid + " shell dumpsys package"; Runtime.getRuntime().exec(line);

After that, searching the package name and then the versionName is easy.

But how to find the same information on iOS ? I didn't find any documentation to have app informations. (and obviously, adb is not compatible with iphone)

Upvotes: 0

Views: 3098

Answers (3)

asma
asma

Reputation: 11

I guess you can get the app version using this command :

ideviceinstaller -l | grep appBundleId

But you need to install the ideviceinstaller first of all using this command:

brew install --HEAD ideviceinstaller

Upvotes: 0

martin
martin

Reputation: 2194

TL;DR Check out this article for a summary.


For iOS, you have the following options:

  1. Use a command line tool like defaults on Mac or plistutil on Linux and call it from within your Java code using ProcessBuilder.
  2. Use the dd-plist library for Java
  3. Use the justtestlah library for Java (which wraps dd-plist and a similar library for Android apps) Disclaimer: I'm the author of this tool.

In short, if you only require iOS I suggest option 2, if you want the same approach for Android and iOS I recommend option 3.

Ad 1.

This is platform-dependent and therefore not ideal (IMO). If you are only targeting one platform to execute your tests from or don't mind maintaining multiple and also don't mind installing some additional tools this works fine though.

These are the commands to retrieve the version information. Similarly, you can also query other metadata from the app packages.

Mac OS:

defaults read /path/test.app/Info CFBundleShortVersionString
defaults read /path/test.app/Info CFBundleVersion

Linux:

plistutil -i /path/test.app/Info | xmllint --xpath "//key[text()='CFBundleShortVersionString']/following-sibling::string[1]/text()" -
plistutil -i /path/test.app/Info | xmllint --xpath "//key[text()='CFBundleVersion']/following-sibling::string[1]/text()" -

This approach is probably most useful for use in shell scripts (e.g. in a CI pipeline).

Integrating it into a Java program will look something like this (please note that you might need to add some additional error handling if you decide to use this):

String versionName = executeCommand("defaults read /path/test.app/Info CFBundleShortVersionString");

public String executeCommand(String command) {
    LOG.info("Executing command {}", command);
    String[] shellCommand = {"/bin/sh", "-c", command};
    Process process;
    try {
      process = new ProcessBuilder(shellCommand).start();
      return Stream.of(process.getErrorStream(), process.getInputStream())
          .parallel()
          .map(
              (InputStream inputStream) -> {
                try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
                  return br.readLine(); // we only care about the first line
                } catch (IOException e) {
                  throw new RuntimeException(e);
                }
              })
          .collect(Collectors.joining());
    } catch (IOException exception) {
      LOG.error(String.format("Error while executing command %s", command), exception);
    }
    return "";
  }

I did a PoC for this here. While this works fine and has the advantage of not needing any additional Java libraries, I would recommend one of the other options instead.

Ad 2.

Add the dd-list JAR file to your classpath. For example, for Maven:

<properties>
  <dd.plist.version>1.21</dd.plist.version>
</properties>

<dependencies>
  <dependency>
    <groupId>com.googlecode.plist</groupId>
    <artifactId>dd-plist</artifactId>
    <version>${dd.plist.version}</version>
  </dependency>
</depdencies>

Then, run the code like this:

String appPath = "/path/test.app";
NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(path);
String versionName = dictionary.objectForKey(“CFBundleShortVersionString”).toString();
String versionCode = dictionary.objectForKey(“CFBundleVersion”).toString();

Ad 3.

Add the justtestlah-mobile-tools JAR file to your classpath. For Maven:

<properties>
  <justtestlah.version>1.3.2</justtestlah.version>
</properties>
<dependencies>
  <dependency>
    <groupId>io.github.martinschneider</groupId>
    <artifactId>justtestlah-mobile-tools</artifactId>
    <version>${justtestlah.version}</version>
  </dependency>
</depdencies>

Then run the code like this:

ApplicationInfo appInfo = new ApplicationInfoService().getAppInfo(appPath);
String versionName = appInfo.getVersionName();
String versionCode = appInfo.getVersionCode();
String applicationName = appInfo.getApplicationName();

The added benefit of the last one is that you can use the same code for APK, APP and even IPA files.

Upvotes: 1

Kovacic
Kovacic

Reputation: 1481

You can try this. If You're using *.app You can try with this comand:

or ipa "IPA/payload/NAME.app/Info.plist"

String line = "/usr/libexec/PlistBuddy -c print Downloads/Payload/NAME.app/Info.plist | grep CFBundleVersion"
Runtime.getRuntime().exec(line);

Upvotes: 0

Related Questions