随着移动应用程序测试变得越来越普遍,不同类型的自动化测试之间的界限可能会变得越来越模糊。性能测试已成为开发周期的组成部分。
iOS应用程序的性能测试涉及Apple与Xcode一起分发的Instruments实用程序。仪器带有许多内置的分析和测量功能。如果打开它,则会看到以下列表:

这些是可以使用Appium进行初始化的各种性能指标,由于我们使用的是Appium,因此不需要在Instruments应用本身中单击任何内容。相反,我们将转到代码编辑器!
iOS配置文件与Appium一起工作的方式有两个命令:一个用于启动配置文件,一个用于停止配置文件并将数据转储给我们查看。这些命令自Appium 1.8起可通过mobile:命令界面使用。代码如下
driver.executeScript("mobile: startPerfRecord", args);
// here: do some stuff in the app that you want to profile
String b64Zip = (String)driver.executeScript("mobile: stopPerfRecord", args);
// here: convert the base64-encoded zip file to actual file data on your system
当我们希望在脚本执行分析时,使用mobile: startPerfRecord和mobile: stopPerfRecord命令向Appium发出信号。
上面的代码段还有另一个我还没有涉及的参数:args参数如何设置?“开始”方法采用具有三个字段的参数对象,例如:
HashMap<String, Object> args = new HashMap<>();
args.put("pid", "current");
args.put("profileName", "Time Profiler");
args.put("timeout", 60000);
- pid:指定测试进程编号pid,如果不指定任何内容,则将对所有进程进行概要分析
- profileName:指定我们要运行哪种仪器(如:Time Profiler)
- timeout:指定超时时间(以毫秒为单位)。之后性能跟踪将自行停止。
对于stopPerfRecord,我们关心的唯一参数是profileName,它的值应与传递给的值相同startPerfRecord。
当您停止演奏录制时,Appium会给您带来的回报实际上是一个Instruments Trace Document,它恰好是一个目录。由于目录无法以字符串格式发送,因此Appium会压缩该.trace
目录,并将其以base64编码形式交还给客户端脚本。要使用此数据,我们必须对其进行解码,然后将其转储到系统中的zip文件中,其代码如下所示:
File traceZip = new File("/path/to/trace.zip");
String b64Zip = (String)driver.executeScript("mobile: stopPerfRecord", args);
byte[] bytesZip = Base64.getMimeDecoder().decode(b64Zip);
FileOutputStream stream = new FileOutputStream(traceZip);
stream.write(bytesZip);
将下载好的trace.zip文件进行解压,添加.trace
后缀,就可以用Instruments打开

在此Instruments UI中,我们可以挖掘Appium测试的概要分析部分期间处于活动状态的各种线程,并查看该线程在大部分例程中花费了哪些时间(通过概要分析器拍摄的stacktrace快照)。例如,这可以帮助我们查找应用程序中需要CPU的区域,例如,我们可能决定将其卸载到工作线程中以改善用户体验。(有关更多信息,请查看Appium XCUITest性能文档)。
为了显示完整的示例,以下是一个简单的测试,该测试从不同版本的Appium Pro中提升了实际的应用行为,并在性能记录括起来的情况下多次运行了这些步骤。然后将zip文件写入磁盘,就像上面一样,在这里我可以很高兴地在Instruments中打开报告。
import io.appium.java_client.MobileBy;
import io.appium.java_client.ios.IOSDriver;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Edition012_iOS_Performance {
private String APP = "https://github.com/cloudgrey-io/the-app/releases/download/v1.3.0/TheApp-v1.3.0.app.zip";
private File traceZip;
private By msgInput = By.xpath("//XCUIElementTypeTextField[@name=\"messageInput\"]");
private By savedMsg = MobileBy.AccessibilityId("savedMessage");
private By saveMsgBtn = MobileBy.AccessibilityId("messageSaveBtn");
private By echoBox = MobileBy.AccessibilityId("Echo Box");
private String TEST_MESSAGE = "Hello World";
@Test
public void testAppActivity() throws Exception {
// Note: Appium server must have been started with --relaxed-security
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "iOS");
capabilities.setCapability("platformVersion", "11.3");
capabilities.setCapability("deviceName", "iPhone X");
capabilities.setCapability("app", APP);
IOSDriver driver = new IOSDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities);
traceZip = new File("/path/to/trace.zip");
try {
HashMap<String, Object> args = new HashMap<>();
args.put("timeout", 60000);
args.put("pid", "current");
args.put("profileName", "Time Profiler");
driver.executeScript("mobile: startPerfRecord", args);
performActions(driver);
performActions(driver);
performActions(driver);
args = new HashMap<>();
args.put("profileName", "Time Profiler");
String b64Zip = (String)driver.executeScript("mobile: stopPerfRecord", args);
byte[] bytesZip = Base64.getMimeDecoder().decode(b64Zip);
FileOutputStream stream = new FileOutputStream(traceZip);
stream.write(bytesZip);
} finally {
driver.quit();
}
}
public void performActions(IOSDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(echoBox)).click();
wait.until(ExpectedConditions.presenceOfElementLocated(msgInput)).sendKeys(TEST_MESSAGE);
wait.until(ExpectedConditions.presenceOfElementLocated(saveMsgBtn)).click();
String savedText = wait.until(ExpectedConditions.presenceOfElementLocated(savedMsg)).getText();
Assert.assertEquals(savedText, TEST_MESSAGE);
driver.navigate().back();
}
}
网友评论