测试开发笔记_第七期_iOS 测试技术_20181110

iOS基础

开发者中心

https://developer.apple.com/

证书申请

  • 创建证书
  • 使用keychain的证书助手创建CSR文件

XCode

  • 项目
  • Git
  • Symbol
  • Find
  • Issue
  • 调试
  • 测试
  • 报告

关键概念

Certificates:苹果签发
开发证书:开发者使用
发布证书:对外分化到app store或者使用ad-hoc模式分发
Provisioning Profiles:
App ID:bundleID相关设置
Devices List:可内测的真机列表
分为开发和发布两种大类型
发布又分为ad-hoc、app store、enterprise级别
.app文件:编译后生成的项目打包代码
.ipa文件:经过签名后的打包文件,本质是zip文件

编译

模拟器

CodeSign /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Products/Debug-iphonesimulator/iOSDemo.app (in target: iOSDemo)    cd /Volumes/ram/xcode/iOSDemo    export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocateSigning Identity:     "-"    /usr/bin/codesign --force --sign - --entitlements /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Intermediates.noindex/iOSDemo.build/Debug-iphonesimulator/iOSDemo.build/iOSDemo.app.xcent --timestamp=none /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Products/Debug-iphonesimulator/iOSDemo.app

真机构建

CodeSign /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Products/Debug-iphoneos/iOSDemo.app (in target: iOSDemo)    cd /Volumes/ram/xcode/iOSDemo    export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocateSigning Identity:     "iPhone Developer: yansheng huang (LJGDR784H2)"Provisioning Profile: "iOS Team Provisioning Profile: *"                      (0c3891ec-b6a3-4bd8-bb3c-1774087952ff)    /usr/bin/codesign --force --sign A747E05F425FF31AA6180C146F9BE554AA1983B6 --entitlements /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Intermediates.noindex/iOSDemo.build/Debug-iphoneos/iOSDemo.build/iOSDemo.app.xcent --timestamp=none /Users/seveniruby/Library/Developer/Xcode/DerivedData/iOSDemo-elmdjvdeutixwufmutvahqycagvt/Build/Products/Debug-iphoneos/iOSDemo.app

常见命令

ls ~/Library/MobileDevice/Provisioning\ Profilessecurity find-identity -p codesigning#安装appium的前提#http://appium.io/docs/en/drivers/ios-xcuitest-real-devices/brew install libimobiledevicebrew install ios-deploy

依赖工具包安装:
brew install –HEAD ideviceinstaller
brew install –HEAD libimobiledevice
brew install ios-deploy
查看模拟器列表:instruments -s devices
查看真机列表:idevice_id -l
安装app: ideviceinstaller -i demo.app
命令行编译:
xcodebuild -scheme UICatalog -target iOS clean build
xcodebuild -scheme UICatalog -target iOS archive

WebDriverAgent

git clone https://github.com/facebook/WebDriverAgent.gitcd WebDriverAgent/bash -x  ./Scripts/bootstrap.sh

start
https://github.com/facebook/WebDriverAgent/wiki/Using-the-Inspector

Inspector
http://localhost:8100/inspector

Appium iOS测试

appium desktop error

[XCUITest] WDA is not listening at 'http://localhost:8100/'[XCUITest] WDA is currently not running. There is nothing to cache[XCUITest] Trying to start WebDriverAgent 2 times with 10000ms interval[BaseDriver] Event 'wdaStartAttempted' logged at 1541831315367 (14:28:35 GMT+0800 (CST))[XCUITest] Launching WebDriverAgent on the device[XCUITest] Carthage found: '/usr/local/bin/carthage'[XCUITest] Killing running processes 'xcodebuild.*BB022D2E-9903-4A11-9D18-926B7F0F2447, iproxy 8100, BB022D2E-9903-4A11-9D18-926B7F0F2447.*XCTRunner' for the device BB022D2E-9903-4A11-9D18-926B7F0F2447...[XCUITest] 'pgrep -nif xcodebuild.*BB022D2E-9903-4A11-9D18-926B7F0F2447' didn't detect any matching processes. Return code: 1[XCUITest] 'pgrep -nif iproxy 8100' didn't detect any matching processes. Return code: 1[XCUITest] 'pgrep -nif BB022D2E-9903-4A11-9D18-926B7F0F2447.*XCTRunner' didn't detect any matching processes. Return code: 1[XCUITest] Beginning test with command 'xcodebuild build-for-testing test-without-building -project /Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination id=BB022D2E-9903-4A11-9D18-926B7F0F2447 IPHONEOS_DEPLOYMENT_TARGET=11.0' in directory '/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent'[XCUITest] Output from xcodebuild will not be logged. To change this, use 'showXcodeLog' desired capability[XCUITest] Waiting up to 60000ms for WebDriverAgent to start

xcodebuild error

2018-11-10 14:49:39:565 - info: [Xcode] Details:  stringRep should be a non-empty string, but it's an empty string2018-11-10 14:49:39:566 - info: [Xcode] Object:   <DVTMacroDefinitionConditionSet>2018-11-10 14:49:39:566 - info: [Xcode] Method:   +conditionSetFromStringRepresentation:getBaseMacroName:error:2018-11-10 14:49:39:566 - info: [Xcode] Thread:   <NSThread: 0x7fd84f502350>{number = 1, name = main}2018-11-10 14:49:39:566 - info: [Xcode] Hints:2018-11-10 14:49:39:567 - info: [Xcode]2018-11-10 14:49:39:567 - info: [Xcode] Backtrace:2018-11-10 14:49:39:574 - info: [Xcode]   0   -[DVTAssertionHandler handleFailureInMethod:object:fileName:lineNumber:assertionSignature:messageFormat:arguments:] (in DVTFoundation)2018-11-10 14:49:39:575 - info: [Xcode]   1   _DVTAssertionHandler (in DVTFoundation)2018-11-10 14:49:39:575 - info: [Xcode]   2   _DVTAssertionFailureHandler (in DVTFoundation)2018-11-10 14:49:39:576 - info: [Xcode]   3   +[DVTMacroDefinitionConditionSet conditionSetFromStringRepresentation:getBaseMacroName:error:] (in DVTFoundation)2018-11-10 14:49:39:576 - info: [Xcode]   4   -[DVTMacroDefinitionTable(XCMacroExpansionExtensions) _xc_setValue:forMacroName:errorHandler:] (in DevToolsCore)2018-11-10 14:49:39:577 - info: [Xcode]   5   __108-[DVTMacroDefinitionTable(XCMacroExpansionExtensions) xc_setMacroNamesAndValuesFromDictionary:errorHandler:]_block_invoke (in DevToolsCore)2018-11-10 14:49:39:580 - info: [Xcode]   6   -[__NSFrozenDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] (in CoreFoundation)2018-11-10 14:49:39:582 - info: [Xcode]   7   -[DVTMacroDefinitionTable(XCMacroExpansionExtensions) xc_setMacroNamesAndValuesFromDictionary:errorHandler:] (in DevToolsCore)2018-11-10 14:49:39:583 - info: [Xcode]   8   -[NSProcessInfo(XCMacroExpansionExtensions) xc_cachedEnvironmentAsMacroDefinitionTable] (in DevToolsCore)2018-11-10 14:49:39:583 - info: [Xcode]   9   -[PBXTarget createMacroExpansionScopeWithBuildParameters:] (in DevToolsCore)2018-11-10 14:49:39:583 - info: [Xcode]  10   -[PBXTarget cachedMacroExpansionScopeForBuildParameters:] (in DevToolsCore)2018-11-10 14:49:39:583 - info: [Xcode]  11   -[PBXTarget expandedValueForString:forBuildParameters:] (in DevToolsCore)2018-11-10 14:49:39:584 - info: [Xcode]  12   -[PBXNativeTarget fullProductNameForBuildParameters:] (in DevToolsCore)2018-11-10 14:49:39:584 - info: [Xcode]  13   -[PBXNativeTarget fullProductNameForConfigurationNamed:] (in DevToolsCore)2018-11-10 14:49:39:585 - info: [Xcode]  14   -[PBXTarget fullProductName] (in DevToolsCore)2018-11-10 14:49:39:586 - info: [Xcode]  15   -[PBXReference setProducingTarget:] (in DevToolsCore)2018-11-10 14:49:39:586 - info: [Xcode]  16   -[PBXTarget awakeFromPListUnarchiver:] (in DevToolsCore)2018-11-10 14:49:39:587 - info: [Xcode]  17   -[PBXNativeTarget awakeFromPListUnarchiver:] (in DevToolsCore)2018-11-10 14:49:39:587 - info: [Xcode]  18   -[PBXPListUnarchiver decodeRootObject] (in DevToolsCore)2018-11-10 14:49:39:587 - info: [Xcode]  19   +[PBXProject projectWithFile:errorHandler:readOnly:] (in DevToolsCore)2018-11-10 14:49:39:588 - info: [Xcode]  20   -[Xcode3Project initWithFilePath:extension:workspace:options:error:] (in DevToolsCore)2018-11-10 14:49:39:588 - info: [Xcode]  21   __82+[IDEContainer _retainedContainerAtFilePath:fileDataType:workspace:options:error:]_block_invoke_2 (in IDEFoundation)2018-11-10 14:49:39:589 - info: [Xcode]  22   _dispatch_client_callout (in libdispatch.dylib)2018-11-10 14:49:39:589 - info: [Xcode]  23   _dispatch_lane_barrier_sync_invoke_and_complete (in libdispatch.dylib)2018-11-10 14:49:39:590 - info: [Xcode]  24   DVTDispatchBarrierSync (in DVTFoundation)2018-11-10 14:49:39:590 - info: [Xcode]  25   -[DVTDispatchLock performLockedBlock:] (in DVTFoundation)2018-11-10 14:49:39:591 - info: [Xcode]  26   __82+[IDEContainer _retainedContainerAtFilePath:fileDataType:workspace:options:error:]_block_invoke (in IDEFoundation)2018-11-10 14:49:39:592 - info: [Xcode]  27   __58-[DVTModelObjectGraph performBlockCoalescingModelChanges:]_block_invoke (in DVTFoundation)2018-11-10 14:49:39:593 - info: [Xcode]  28   -[DVTModelGraphTransactionScope performTransaction:] (in DVTFoundation)2018-11-10 14:49:39:593 - info: [Xcode]  29   -[DVTModelObjectGraph performBlockCoalescingModelChanges:] (in DVTFoundation)2018-11-10 14:49:39:594 - info: [Xcode]  30   +[IDEContainer _retainedContainerAtFilePath:fileDataType:workspace:options:error:] (in IDEFoundation)2018-11-10 14:49:39:594 - info: [Xcode]  31   +[IDEContainer retainedContainerAtFilePath:fileDataType:workspace:error:] (in IDEFoundation)2018-11-10 14:49:39:595 - info: [Xcode]  32   -[IDEWorkspace _configureWrappedWorkspaceWithError:] (in IDEFoundation)2018-11-10 14:49:39:595 - info: [Xcode]  33   __82+[IDEContainer _retainedContainerAtFilePath:fileDataType:workspace:options:error:]_block_invoke (in IDEFoundation)2018-11-10 14:49:39:595 - info: [Xcode]  34   +[IDEContainer _retainedContainerAtFilePath:fileDataType:workspace:options:error:] (in IDEFoundation)2018-11-10 14:49:39:595 - info: [Xcode]  35   +[IDEContainer retainedWrappedWorkspaceForContainerAtFilePath:fileDataType:error:] (in IDEFoundation)2018-11-10 14:49:39:596 - info: [Xcode]  36   -[Xcode3CommandLineBuildTool _resolveInputOptionsWithTimingSection:] (in Xcode3Core)2018-11-10 14:49:39:596 - info: [Xcode]  37   -[Xcode3CommandLineBuildTool run] (in Xcode3Core)2018-11-10 14:49:39:596 - info: [Xcode]  38   main (in xcodebuild)2018-11-10 14:49:39:596 - info: [Xcode]  39   start (in libdyld.dylib)2018-11-10 14:49:39:597 - info: [Xcode]2018-11-10 14:49:39:602 - info: [XCUITest] xcodebuild exited with code 'null' and signal 'SIGABRT'

核心编译命令

Beginning test with command 'xcodebuild build-for-testing test-without-building -project /Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination id=BB022D2E-9903-4A11-9D18-926B7F0F2447 IPHONEOS_DEPLOYMENT_TARGET=11.0' in directory '/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent'2018-11-10 14:48:53:338 - info: [debug] [XCUITest] Output from xcodebuild will be logged. To change this, use 'showXcodeLog' desired capability``## SImulator控制https://github.com/facebook/FBSimulatorControl/blob/master/fbsimctl/README.md## 模拟器示例```javapackage ios7;import io.appium.java_client.MobileElement;import io.appium.java_client.ios.IOSDriver;import junit.framework.TestCase;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.net.MalformedURLException;import java.net.URL;import org.openqa.selenium.remote.DesiredCapabilities;public class DemoTest {    private IOSDriver driver;    @Before    public void setUp() throws MalformedURLException {        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();        desiredCapabilities.setCapability("platformName", "ios");        desiredCapabilities.setCapability("deviceName", "iPhone X");        desiredCapabilities.setCapability("platformVersion", "11.0");        desiredCapabilities.setCapability("automationName", "xcuitest");        desiredCapabilities.setCapability("app", "/Users/seveniruby/Library/Developer/Xcode/DerivedData/UICatalog-ftyzdbgapjmxxobezrnrxsshpdqh/Build/Products/Debug-iphonesimulator/UICatalog.app");        //desiredCapabilities.setCapability("showXcodeLog", "true");        URL remoteUrl = new URL("https://127.0.0.1:4723/wd/hub");        driver = new IOSDriver(remoteUrl, desiredCapabilities);    }    @Test    public void sampleTest() {        driver.findElementByAccessibilityId("Buttons").click();        System.out.println(driver.getPageSource());        driver.findElementByXPath("//*[@label='Button']").click();        driver.findElementByAccessibilityId("UICatalog").click();    }    @After    public void tearDown() {        //driver.quit();    }}

真机测试

error

[ 52%] CreatingStagingDirectory[ 57%] ExtractingPackage[ 60%] InspectingPackage[ 60%] TakingInstallLock[ 65%] PreflightingApplication[ 70%] VerifyingApplication2018-11-10 16:07:23.798 ios-deploy[54447:2782396] [ !! ] Error 0xe8000067: There was an internal API error. AMDeviceSecureInstallApplication(0, device, url, options, install_callback, 0)

真机需要的capability

  • udid: auto
  • xcodeOrgId
  • xcodeSigningId
{  "platformName": "ios",  "deviceName": "iPhone X",  "platformVersion": "11.0",  "automationName": "xcuitest",  "showXcodeLog": "true",  "udid": "auto",  "xcodeOrgId": "96NJEQL7Y2",  "xcodeSigningId": "iPhone Developer"}

Browser

brew install –HEAD libimobiledevice
brew install ios-webkit-debug-proxy
settings > safari > advanced > web inspector -> on

package ios7;import io.appium.java_client.MobileElement;import io.appium.java_client.ios.IOSDriver;import junit.framework.TestCase;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.net.MalformedURLException;import java.net.URL;import java.util.concurrent.TimeUnit;import org.openqa.selenium.remote.DesiredCapabilities;public class WebTest {    private IOSDriver driver;    @Before    public void setUp() throws MalformedURLException {        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();        desiredCapabilities.setCapability("platformName", "ios");        desiredCapabilities.setCapability("automationName", "xcuitest");        desiredCapabilities.setCapability("udid", "auto");        desiredCapabilities.setCapability("startIWDP", "true");        desiredCapabilities.setCapability("browserName", "Safari");        desiredCapabilities.setCapability("deviceName", "auto");        URL remoteUrl = new URL("https://127.0.0.1:4723/wd/hub");        driver = new IOSDriver(remoteUrl, desiredCapabilities);        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);    }    @Test    public void sampleTest() {        driver.get("https://testerhome.com");        driver.findElementByXPath("//*[contains(@title, '广州沙龙')]").click();    }    @After    public void tearDown() {        //driver.quit();    }}

WebView

package ios7;import io.appium.java_client.MobileElement;import io.appium.java_client.ios.IOSDriver;import junit.framework.TestCase;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.net.MalformedURLException;import java.net.URL;import org.openqa.selenium.remote.DesiredCapabilities;public class WebViewTest {    private IOSDriver driver;    @Before    public void setUp() throws MalformedURLException {        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();        desiredCapabilities.setCapability("platformName", "ios");        desiredCapabilities.setCapability("deviceName", "iPhone X");        desiredCapabilities.setCapability("platformVersion", "11.0");        desiredCapabilities.setCapability("automationName", "xcuitest");        desiredCapabilities.setCapability("showXcodeLog", "true");        desiredCapabilities.setCapability("udid", "auto");        desiredCapabilities.setCapability("xcodeOrgId", "96NJEQL7Y2");        desiredCapabilities.setCapability("xcodeSigningId", "iPhone Developer");        desiredCapabilities.setCapability("app", "/Users/seveniruby/Library/Developer/Xcode/DerivedData/UICatalog-ftyzdbgapjmxxobezrnrxsshpdqh/Build/Products/Debug-iphoneos/UICatalog.app");        desiredCapabilities.setCapability("startIWDP", "true");        URL remoteUrl = new URL("https://127.0.0.1:4723/wd/hub");        driver = new IOSDriver(remoteUrl, desiredCapabilities);    }    @Test    public void sampleTest() throws InterruptedException {        driver.findElementByXPath("//XCUIElementTypeButton[@name=\"UICatalog\"]").click();        driver.findElementByAccessibilityId("Web View").click();        Thread.sleep(6000);        System.out.println(driver.getContextHandles());        System.out.println(driver.getPageSource());        driver.context("WEBVIEW_1");        System.out.println(driver.getPageSource());    }    @After    public void tearDown() {        driver.quit();    }}

↙↙↙阅读原文可查看相关链接,并与作者交流