本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
在 AWS Device Farm 中建立遠端存取工作階段
如需遠端存取工作階段的詳細資訊,請參閱工作階段。
先決條件
-
在 Device Farm 中建立專案。請遵循在 AWS Device Farm 中建立專案中的指示,然後返回此頁面。
建立遠端工作階段
- Console
-
登入 Device Farm 主控台,網址為 https://https://console.aws.amazon.com/devicefarm
。 -
在 Device Farm 導覽面板上,選擇行動裝置測試,然後選擇專案。
-
如果您已有專案,請從清單中選擇。否則,請依照 中的指示建立專案在 AWS Device Farm 中建立專案。
-
在遠端存取索引標籤上,選擇建立遠端存取工作階段。
-
為您的工作階段選擇一個裝置。您可以從可用裝置清單中選擇,或使用清單頂端的搜尋列搜尋裝置。
-
(選用) 在工作階段中包含應用程式和輔助應用程式。這些可以是新上傳的應用程式,或過去 30 天內在此專案中上傳的應用程式 (30 天後,應用程式上傳將會過期)。
-
在 Session name (工作階段名稱) 中,輸入工作階段的名稱。
-
選擇 Confirm and start session (確認並啟動工作階段)。
- AWS CLI
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
首先,下載並安裝最新版本,以確認您的 AWS CLI 版本是up-to-date。
重要
本文件中提及的某些命令不適用於舊版的 AWS CLI。
然後,您可以決定要在哪個裝置上測試:
$aws devicefarm list-devices這會顯示如下所示的輸出:
{ "devices": [ { "arn": "arn:aws:devicefarm:us-west-2::device:DE5BD47FF3BD42C3A14BF7A6EFB1BFE7", "name": "Google Pixel 8", "remoteAccessEnabled": true, "availability": "HIGHLY_AVAILABLE" ... }, ... ] }然後,您可以使用您選擇的裝置 ARN 建立遠端存取工作階段:
$aws devicefarm create-remote-access-session \ --project-arn arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef \ --device-arn arn:aws:devicefarm:us-west-2::device:DE5BD47FF3BD42C3A14BF7A6EFB1BFE7 \ --app-arn arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef \ --configuration '{ "auxiliaryApps": [ "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0", "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1" ] }'這會顯示如下所示的輸出:
{ "remoteAccessSession": { "arn": "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000", "name": "Google Pixel 8", "status": "PENDING", ... }現在,您可以選擇輪詢並等待工作階段準備就緒:
$POLL_INTERVAL=3 TIMEOUT=600 DEADLINE=$(( $(date +%s) + TIMEOUT )) while [[ "$(date +%s)" -lt "$DEADLINE" ]]; do STATUS=$(aws devicefarm get-remote-access-session \ --arn "$DEVICE_FARM_SESSION_ARN" \ --query 'remoteAccessSession.status' \ --output text) case "$STATUS" in RUNNING) echo "Session is ready with status: $STATUS" break ;; STOPPING|COMPLETED) echo "Session ended early with status: $STATUS" exit 1 ;; esac done - Python
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
此範例會先在 Device Farm 上尋找任何可用的 Google Pixel 裝置,然後使用它建立遠端存取工作階段,並等待工作階段執行。
import random import time import boto3 client = boto3.client("devicefarm", region_name="us-west-2") # 1) Gather all matching devices via paginated ListDevices with filters filters = [ {"attribute": "MODEL", "operator": "CONTAINS", "values": ["Pixel"]}, {"attribute": "AVAILABILITY", "operator": "EQUALS", "values": ["AVAILABLE"]}, ] matching_arns = [] next_token = None while True: args = {"filters": filters} if next_token: args["nextToken"] = next_token page = client.list_devices(**args) for d in page.get("devices", []): matching_arns.append(d["arn"]) next_token = page.get("nextToken") if not next_token: break if not matching_arns: raise RuntimeError("No available Google Pixel device found.") # Randomly select one device from the full matching set device_arn = random.choice(matching_arns) print("Selected device ARN:", device_arn) # 2) Create remote access session and wait until RUNNING resp = client.create_remote_access_session( projectArn="arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef", deviceArn=device_arn, appArn="arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef", # optional configuration={ "auxiliaryApps": [ # optional "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0", "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1", ] }, ) session_arn = resp["remoteAccessSession"]["arn"] print(f"Created Remote Access Session: {session_arn}") poll_interval = 3 timeout = 600 deadline = time.time() + timeout terminal_states = ["STOPPING", "COMPLETED"] while True: out = client.get_remote_access_session(arn=session_arn) status = out["remoteAccessSession"]["status"] print(f"Current status: {status}") if status == "RUNNING": print(f"Session is ready with status: {status}") break if status in terminal_states: raise RuntimeError(f"Session ended early with status: {status}") if time.time() >= deadline: raise RuntimeError("Timed out waiting for session to be ready.") time.sleep(poll_interval) - Java
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
注意:此範例使用適用於 Java v2 的 AWS 開發套件,並與 JDK 第 11 版及更高版本相容。
此範例會先在 Device Farm 上尋找任何可用的 Google Pixel 裝置,然後使用它建立遠端存取工作階段,並等待工作階段執行。
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.devicefarm.DeviceFarmClient; import software.amazon.awssdk.services.devicefarm.model.CreateRemoteAccessSessionConfiguration; import software.amazon.awssdk.services.devicefarm.model.CreateRemoteAccessSessionRequest; import software.amazon.awssdk.services.devicefarm.model.CreateRemoteAccessSessionResponse; import software.amazon.awssdk.services.devicefarm.model.Device; import software.amazon.awssdk.services.devicefarm.model.DeviceFilter; import software.amazon.awssdk.services.devicefarm.model.DeviceFilterAttribute; import software.amazon.awssdk.services.devicefarm.model.GetRemoteAccessSessionRequest; import software.amazon.awssdk.services.devicefarm.model.GetRemoteAccessSessionResponse; import software.amazon.awssdk.services.devicefarm.model.ListDevicesRequest; import software.amazon.awssdk.services.devicefarm.model.ListDevicesResponse; import software.amazon.awssdk.services.devicefarm.model.RuleOperator; public class CreateRemoteAccessSession { public static void main(String[] args) throws Exception { DeviceFarmClient client = DeviceFarmClient.builder() .region(Region.US_WEST_2) .build(); String projectArn = "arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef"; String appArn = "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef"; String aux1 = "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0"; String aux2 = "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1"; // 1) Gather all matching devices via paginated ListDevices with filters List<DeviceFilter> filters = Arrays.asList( DeviceFilter.builder() .attribute(DeviceFilterAttribute.MODEL) .operator(RuleOperator.CONTAINS) .values("Pixel") .build(), DeviceFilter.builder() .attribute(DeviceFilterAttribute.AVAILABILITY) .operator(RuleOperator.EQUALS) .values("AVAILABLE") .build() ); List<String> matchingDeviceArns = new ArrayList<>(); String next = null; do { ListDevicesResponse page = client.listDevices( ListDevicesRequest.builder().filters(filters).nextToken(next).build()); for (Device d : page.devices()) { matchingDeviceArns.add(d.arn()); } next = page.nextToken(); } while (next != null); if (matchingDeviceArns.isEmpty()) { throw new RuntimeException("No available Google Pixel device found."); } // Randomly select one device from the full matching set String deviceArn = matchingDeviceArns.get( ThreadLocalRandom.current().nextInt(matchingDeviceArns.size())); System.out.println("Selected device ARN: " + deviceArn); // 2) Create Remote Access session and wait until it is RUNNING CreateRemoteAccessSessionConfiguration cfg = CreateRemoteAccessSessionConfiguration.builder() .auxiliaryApps(Arrays.asList(aux1, aux2)) .build(); CreateRemoteAccessSessionResponse res = client.createRemoteAccessSession( CreateRemoteAccessSessionRequest.builder() .projectArn(projectArn) .deviceArn(deviceArn) .appArn(appArn) // optional .configuration(cfg) // optional .build()); String sessionArn = res.remoteAccessSession().arn(); System.out.println("Created Remote Access Session: " + sessionArn); int pollIntervalMs = 3000; long timeoutMs = 600_000L; long deadline = System.currentTimeMillis() + timeoutMs; while (true) { GetRemoteAccessSessionResponse get = client.getRemoteAccessSession( GetRemoteAccessSessionRequest.builder().arn(sessionArn).build()); String status = get.remoteAccessSession().statusAsString(); System.out.println("Current status: " + status); if ("RUNNING".equals(status)) { System.out.println("Session is ready with status: " + status); break; } if ("STOPPING".equals(status) || "COMPLETED".equals(status)) { throw new RuntimeException("Session ended early with status: " + status); } if (System.currentTimeMillis() >= deadline) { throw new RuntimeException("Timed out waiting for session to be ready."); } Thread.sleep(pollIntervalMs); } } } - JavaScript
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
注意:此範例使用適用於 JavaScript v3 的 AWS 開發套件。
此範例會先在 Device Farm 上尋找任何可用的 Google Pixel 裝置,然後使用它建立遠端存取工作階段,並等待工作階段執行。
import { DeviceFarmClient, ListDevicesCommand, CreateRemoteAccessSessionCommand, GetRemoteAccessSessionCommand, } from "@aws-sdk/client-device-farm"; const client = new DeviceFarmClient({ region: "us-west-2" }); // 1) Gather all matching devices via paginated ListDevices with filters const filters = [ { attribute: "MODEL", operator: "CONTAINS", values: ["Pixel"] }, { attribute: "AVAILABILITY", operator: "EQUALS", values: ["AVAILABLE"] }, ]; let nextToken; const matching = []; while (true) { const page = await client.send(new ListDevicesCommand({ filters, nextToken })); for (const d of page.devices ?? []) { matching.push(d.arn); } nextToken = page.nextToken; if (!nextToken) break; } if (matching.length === 0) { throw new Error("No available Google Pixel device found."); } // Randomly select one device from the full matching set const deviceArn = matching[Math.floor(Math.random() * matching.length)]; console.log("Selected device ARN:", deviceArn); // 2) Create remote access session and wait until RUNNING const out = await client.send(new CreateRemoteAccessSessionCommand({ projectArn: "arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef", deviceArn, appArn: "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef", // optional configuration: { auxiliaryApps: [ // optional "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0", "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1", ], }, })); const sessionArn = out.remoteAccessSession?.arn; console.log("Created Remote Access Session:", sessionArn); const pollIntervalMs = 3000; const timeoutMs = 600000; const deadline = Date.now() + timeoutMs; while (true) { const get = await client.send(new GetRemoteAccessSessionCommand({ arn: sessionArn })); const status = get.remoteAccessSession?.status; console.log("Current status:", status); if (status === "RUNNING") { console.log("Session is ready with status:", status); break; } if (status === "STOPPING" || status === "COMPLETED") { throw new Error(`Session ended early with status: ${status}`); } if (Date.now() >= deadline) { throw new Error("Timed out waiting for session to be ready."); } await new Promise((r) => setTimeout(r, pollIntervalMs)); } - C#
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
此範例會先在 Device Farm 上尋找任何可用的 Google Pixel 裝置,然後使用它建立遠端存取工作階段,並等待工作階段執行。
using System; using System.Collections.Generic; using System.Threading.Tasks; using Amazon; using Amazon.DeviceFarm; using Amazon.DeviceFarm.Model; class Program { static async Task Main() { var client = new AmazonDeviceFarmClient(RegionEndpoint.USWest2); // 1) Gather all matching devices via paginated ListDevices with filters var filters = new List<DeviceFilter> { new DeviceFilter { Attribute = DeviceAttribute.MODEL, Operator = RuleOperator.CONTAINS, Values = new List<string>{ "Pixel" } }, new DeviceFilter { Attribute = DeviceAttribute.AVAILABILITY, Operator = RuleOperator.EQUALS, Values = new List<string>{ "AVAILABLE" } }, }; var matchingArns = new List<string>(); string nextToken = null; do { var list = await client.ListDevicesAsync(new ListDevicesRequest { Filters = filters, NextToken = nextToken }); foreach (var d in list.Devices) matchingArns.Add(d.Arn); nextToken = list.NextToken; } while (nextToken != null); if (matchingArns.Count == 0) throw new Exception("No available Google Pixel device found."); // Randomly select one device from the full matching set var rnd = new Random(); var deviceArn = matchingArns[rnd.Next(matchingArns.Count)]; Console.WriteLine($"Selected device ARN: {deviceArn}"); // 2) Create remote access session and wait until RUNNING var request = new CreateRemoteAccessSessionRequest { ProjectArn = "arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef", DeviceArn = deviceArn, AppArn = "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef", // optional Configuration = new CreateRemoteAccessSessionConfiguration { AuxiliaryApps = new List<string> { "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0", "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1" } } }; request.Configuration.AuxiliaryApps.RemoveAll(string.IsNullOrWhiteSpace); var response = await client.CreateRemoteAccessSessionAsync(request); var sessionArn = response.RemoteAccessSession.Arn; Console.WriteLine($"Created Remote Access Session: {sessionArn}"); var pollIntervalMs = 3000; var timeoutMs = 600000; var deadline = DateTime.UtcNow.AddMilliseconds(timeoutMs); while (true) { var get = await client.GetRemoteAccessSessionAsync(new GetRemoteAccessSessionRequest { Arn = sessionArn }); var status = get.RemoteAccessSession.Status.Value; Console.WriteLine($"Current status: {status}"); if (status == "RUNNING") { Console.WriteLine($"Session is ready with status: {status}"); break; } if (status == "STOPPING" || status == "COMPLETED") { throw new Exception($"Session ended early with status: {status}"); } if (DateTime.UtcNow >= deadline) { throw new TimeoutException("Timed out waiting for session to be ready."); } await Task.Delay(pollIntervalMs); } } } - Ruby
-
注意:這些指示僅著重於建立遠端存取工作階段。如需如何上傳應用程式以在工作階段期間使用的指示,請參閱自動化應用程式上傳。
此範例會先在 Device Farm 上尋找任何可用的 Google Pixel 裝置,然後使用它建立遠端存取工作階段,並等待工作階段執行。
require 'aws-sdk-devicefarm' client = Aws::DeviceFarm::Client.new(region: 'us-west-2') # 1) Gather all matching devices via paginated ListDevices with filters filters = [ { attribute: 'MODEL', operator: 'CONTAINS', values: ['Pixel'] }, { attribute: 'AVAILABILITY', operator: 'EQUALS', values: ['AVAILABLE'] }, ] matching_arns = [] next_token = nil loop do resp = client.list_devices(filters: filters, next_token: next_token) resp.devices&.each { |d| matching_arns << d.arn } next_token = resp.next_token break unless next_token end abort "No available Google Pixel device found." if matching_arns.empty? # Randomly select one device from the full matching set device_arn = matching_arns.sample puts "Selected device ARN: #{device_arn}" # 2) Create remote access session and wait until RUNNING resp = client.create_remote_access_session( project_arn: "arn:aws:devicefarm:us-west-2:111122223333:project:12345678-1111-2222-333-456789abcdef", device_arn: device_arn, app_arn: "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef", # optional configuration: { auxiliary_apps: [ # optional "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde0", "arn:aws:devicefarm:us-west-2:111122223333:upload:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcde1" ].compact } ) session_arn = resp.remote_access_session.arn puts "Created Remote Access Session: #{session_arn}" poll_interval = 3 timeout = 600 deadline = Time.now + timeout terminal = %w[STOPPING COMPLETED] loop do get = client.get_remote_access_session(arn: session_arn) status = get.remote_access_session.status puts "Current status: #{status}" if status == 'RUNNING' puts "Session is ready with status: #{status}" break end abort "Session ended early with status: #{status}" if terminal.include?(status) abort "Timed out waiting for session to be ready." if Time.now >= deadline sleep poll_interval end
後續步驟
Device Farm 會在請求的裝置和基礎設施可用時立即啟動工作階段,通常在幾分鐘內。裝置請求對話方塊會出現,直到工作階段啟動為止。若要取消工作階段請求,請選擇 Cancel request (取消請求)。
如果選取的裝置無法使用或忙碌,工作階段狀態會顯示為待定裝置,表示您可能需要等待一段時間,裝置才能進行測試。
如果您的帳戶已達到公有計量或未計量裝置的並行限制,工作階段狀態會顯示為待定並行。對於未計量的裝置插槽,您可以透過購買更多裝置插槽來增加並行。對於按pay-as-you-go計費的裝置,請透過支援票證聯絡 AWS,以請求提高服務配額。
當工作階段設定開始時,它會先顯示進行中的狀態,然後在本機 Web 瀏覽器嘗試開啟與裝置的遠端連線時顯示連線狀態。
在工作階段開始之後,如果您應該關閉瀏覽器或瀏覽器標籤,而無需停止工作階段,或如果失去瀏覽器與網際網路之間的連線,則工作階段仍有五分鐘保持作用中狀態。之後,Device Farm 會結束工作階段。您的帳戶需要為閒置時間付費。
工作階段開始後,您可以在 Web 瀏覽器中與裝置互動,或使用 Appium 測試裝置。