在 VTS 測試期間,殼層指令的作用是執行目標端測試
用於取得/設定屬性、環境變數和系統資訊
以及啟動/停止 Android 架構你可以執行 VTS 裝置殼層
使用 adb shell
指令或 VTS 殼層驅動程式
在裝置上執行 (建議做法)。
使用 ADB 殼層
在測試期間需要關閉 USB 連接埠或重新啟動裝置
測試必須使用 ADB 殼層,因為如果沒有
以及永久的 USB 連線您可以從
Python 測試指令碼中的 AndroidDevice
物件。例如:
- 取得 Android 裝置物件:
self.device = self.android_devices[0]
- 發出單一殼層指令:
result = self.device.adb.shell(‘ls')
使用 VTS 殼層驅動程式
VTS 殼層驅動程式是代理程式二進位檔,會在裝置上執行並執行
殼層指令根據預設,如果驅動程式正在執行,VTS 會使用殼層驅動程式
因為這個方法的延遲時間比使用 adb
shell
指令少。
VTS 架構支援每部 Android 裝置進行的多裝置測試 在基本執行器中以 AndroidDevice 物件表示。VTS 預設 架構會將 VTS 代理程式和 VTS 殼層驅動程式二進位檔推送至每部 Android 裝置 並為裝置上的 VTS 代理程式建立 TCP 連線。
如要執行殼層指令,主機端 Python 指令碼會產生一個函式 呼叫 AndroidDevice 物件中的 ShellMirror 物件。ShellMirror 物件會將殼層指令文字封裝為 protobuf 訊息,並透過 TCP 管道傳送給 Android 上的 VTS 代理程式 裝置。在裝置上執行的代理程式接著將殼層指令轉送至 VTS 殼層 透過 Unix 通訊端存取及變更驅動程式
VTS 殼層驅動程式收到殼層指令後,會執行指令
來源:nohup
裝置殼層以防止當機。Stdout、stderr 和傳回代碼
擷取自 nohup
,並傳回 VTS 代理程式。最後,服務專員
將指令結果包裝在
protobuf
訊息。
優點
使用 VTS 殼層驅動程式 (而非 adb
shell
) 的優點包括:
- 穩定性。VTS 殼層驅動程式會使用
nohup
:在預設設定中執行指令。隨著 VTS 測試 大多為較低層級的 HAL 和核心測試,nohup
可確保殼層 指令在執行期間不會停止運作。 - 效能:
adb shell
指令時 快取一些具有連線的結果,例如列出目錄中的檔案 您也會耗費不少心力 執行測試二進位檔等工作VTS 殼層驅動程式 在整個測試期間保持有效連線,因此只有 USB 負擔 非常適用於內部微服務通訊在測試中,使用 VTS 殼層驅動程式,執行含有 100 次呼叫空白 gtest 二進位檔的速度比使用adb shell
;但實際差異會比較大 通訊的機制非常豐富 - 狀態保留:VTS 殼層驅動程式會維護終端機 每個終端機名稱的工作階段 (預設終端機名稱是 default)。一個終端機工作階段中設定的環境變數為 僅適用於同一工作階段中的後續指令
- 擴充:VTS 的殼層指令通訊 所有架構和裝置驅動程式都會納入 protobuf 中,藉此 。其他時間範圍 還能提升效能,包括剖析裝置端結果 通訊負擔大於結果字串剖析時。
缺點
使用 VTS 殼層驅動程式而非 adb
shell
的缺點包括:
- 其他二進位檔。VTS 代理程式檔案必須推送至 並在執行測試後清理裝置。
- 必須連上網路。如果 TCP 連線
主機和代理程式在測試期間遺失 (因為 USB 中斷連線、通訊埠關閉,
裝置當機等) 觸發的動作
無法傳輸至 VTS 代理程式即使自動切換成
adb shell
,在中斷連線前執行指令的結果和狀態 便是未知的。
範例
在 VTS 主機端 Python 測試指令碼中使用殼層指令的範例:
- 取得 Android 裝置物件:
self.device = self.android_devices[0]
- 取得所選裝置的殼層物件:
self.shell = self.device.shell
- 發出單一殼層指令:
results = self.shell.Execute(‘ls')
- 發出殼層指令清單:
results = self.shell.Execute([‘cd /data/local/tmp', ‘ls'])
指令結果物件
執行殼層指令時傳回的傳回物件是含有
索引鍵 stdouts
、stderrs
和 return_codes
。
無論 shell 指令是以單一字串或清單形式提供
指令字串的每個值都會是清單。
若要驗證指令清單的傳回代碼,測試指令碼必須檢查 索引。例子:
asserts.assertFalse(any(results[‘return_codes']), ‘some command failed.')
或者,指令碼可以個別檢查每個指令索引。 例子:
asserts.assertEqual(results[‘return_codes'][0], 0, ‘first command failed')
asserts.assertEqual(results[‘return_codes'][1], 0, ‘second command failed')