淺談音視頻自動化測試
好久不見~今天想來聊聊音視頻/多媒體/播放器自動化測試的思路。總體來說,可以從以下幾個角度來思考。
1.測項設(shè)計
1.1.功能測試
?對各類傳輸協(xié)議、封裝格式、編碼格式的支持,在編碼格式測試方面,又涉及到各類編碼參數(shù)的組合,測項數(shù)量會瘋狂膨脹起來?各類基礎(chǔ)播放控制,包括播放、暫停、倍速、seek等?和自身產(chǎn)品強相關(guān)的feature測試,如無縫切換、音頻輸出通路、DRM等
1.2.性能測試
?啟播(首屏)時間,更細粒度的考量因素可能有啟播各個環(huán)節(jié)細分的耗時?seek耗時?丟幀(卡頓)率,更細粒度的考量因素可能有連續(xù)丟幀數(shù)、每秒丟幀數(shù)等?緩沖(rebuffer)率,更細粒度的考量因素可能有每次bufferd的時長?AV同步情況?錯誤率
1.3.壓力測試
?長時間播放?弱網(wǎng)環(huán)境播放?低性能設(shè)備環(huán)境播放?高頻播放操作控制,如頻繁啟播、頻繁seek、頻繁切換碼流等
在這一環(huán)節(jié),還要考慮好測項的組織和展示形式。常規(guī)的選擇一般是json或xml,如下面這個例子
{
cases:[
{
"name": "DASH-LIVE-001",
"brief": "Live - number template",
"data":
{
"exe-type": "TYPE_CUSTOM",
"urls":["http://vm2.dashif.org/livesim-dev/periods_1/testpic_2s/Manifest.mpd"]
}
},
{
"name": "DASH-LIVE-002",
"brief": "Live - time template",
"data":
{
"exe-type": "TYPE_CUSTOM",
"urls":["http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd"]
}
},
]
}`
2.測試方法
無論是用黑盒測試還是白盒測試,其實就兩個關(guān)鍵問題:如何發(fā)起測試以及如何驗證測試結(jié)果。
2.1. 黑盒測試
發(fā)起測試的方式有以下幾種:
?直接給播放器發(fā)送播放指令 以android平臺為例,可以通過測試工具給播放器應(yīng)用發(fā)送Intent來調(diào)起不同的測項,但這限制了只能在本機上發(fā)起測試。如果考慮遠程測試的話,可以利用http請求發(fā)送測項內(nèi)容(上一節(jié)提到的json就用上了),測試工具接收http請求后解析測項內(nèi)容,再轉(zhuǎn)換為Intent或其他指令形式調(diào)起播放器。?模擬用戶操作 可以通過模擬觸摸屏操作、遙控器按鍵操作等各種方式來實現(xiàn)。還是以android平臺為例,uiAutomator就是一個現(xiàn)成的工具。
驗證測試結(jié)果的方法則有以下幾種:
?利用日志分析。利用提前加好的關(guān)鍵日志,可以方便的驗證結(jié)果。?利用圖像、聲音傳感器進行分析 可以抓取屏幕圖像數(shù)據(jù)、揚聲器輸出的音頻數(shù)據(jù),然后對這些輸出數(shù)據(jù)結(jié)果進行分析。一個簡單的例子是用外部camera拍攝屏幕并分析屏幕畫面的幀差,如果發(fā)現(xiàn)畫面長時間沒有變化,則很有可能是發(fā)生了卡頓。更復(fù)雜的比如分析AVSync用的SyncOne設(shè)備、Netflix的EyePatch設(shè)備,都是著名的案例,當然開發(fā)難度也更高。
2.2.白盒測試
播放器的白盒測試就用插樁測試方法即可。還是以android平臺為例,CTS media中的測試代碼就是很好的參考,舉一例如下
public void testPlayMidi() throws Exception {
final int resid = R.raw.midi8sec;
final int midiDuration = 8000;
final int tolerance = 70;
final int seekDuration = 1000;
MediaPlayer mp = MediaPlayer.create(mContext, resid);
try {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
mp.start();
assertFalse(mp.isLooping());
mp.setLooping(true);
assertTrue(mp.isLooping());
assertEquals(midiDuration, mp.getDuration(), tolerance);
int pos = mp.getCurrentPosition();
assertTrue(pos >= 0);
assertTrue(pos < midiDuration - seekDuration);
mp.seekTo(pos + seekDuration);
assertEquals(pos + seekDuration, mp.getCurrentPosition(), tolerance);
// test stop and restart
mp.stop();
mp.reset();
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
Thread.sleep(SLEEP_TIME);
} finally {
mp.release();
}
}
插樁測試代碼編寫完成之后,同樣可以選擇直接在本機用指令方式調(diào)起或者遠程通過http請求調(diào)起。各種插樁測試方案一般都會提供測試結(jié)果的格式化工具,所以測試結(jié)果的驗證與展示不是什么大問題。
設(shè)計可擴展的測項
在前面我們提到可以用json形式來記錄測項,其實還可以在此基礎(chǔ)上進行發(fā)散,讓測項可以隨時定制、隨時擴展。
如果我們預(yù)定義一些播放器指令字段,如“play”,“pause”, "loop", "change_track"等,然后將這些指令組合起來,就可以實現(xiàn)測項的腳本化編寫。播放器只要解析這樣一個簡單的json腳本,按照其中定義的指令順序執(zhí)行,即可達到運行測項的目標。這種簡單的腳本對測試人員的技術(shù)要求也很低。
舉一個示例如下,在這個例子中,將會執(zhí)行啟播,然后等待10秒后,停止播放。用類似的思路,可以快速擴展已有測項。
{
"source":"/sdcard/test.mp4"
"commands": [
{
"command":"play",
"value":0
},
{
"command":"sleep",
"value":10000
},
{
"command":"stop",
"value":0
}
]
}