如何編寫 FFmpeg 自動化測試用例(一)

2021-03-02 流媒體技術

今天有個為 FFmpeg 貢獻高質量 patch 的朋友問到了一個問題,如何編寫一個 FATE 測試用例,當時簡單地回復了操作步驟,那麼接下來我將會在這裡詳細介紹一下如何編寫 FFmpeg 的自動化測試用例。

一. 測試用例結果參考數據說明

首先看一下測試用例參考數據內容大概的展現形態

bogon:ffmpeg_up liuqi$ cat tests/ref/fate/hls-segment-size#tb 0: 1/44100#media_type 0: audio#codec_id 0: pcm_s16le#sample_rate 0: 44100#channel_layout 0: 4#channel_layout_name 0: mono0,          0,          0,     1152,     2304, 0x907cb7fa0,       1152,       1152,     1152,     2304, 0xb8dc75250,       2304,       2304,     1152,     2304, 0x3e7d69050,       3456,       3456,     1152,     2304, 0xef47877b0,       4608,       4608,     1152,     2304, 0xfe916b7e0,       5760,       5760,     1152,     2304, 0xe3d08cde0,       6912,       6912,     1152,     2304, 0xff7f86cf0,       8064,       8064,     1152,     2304, 0x843e6f950,       9216,       9216,     1152,     2304, 0x81577c260,      10368,      10368,     1152,     2304, 0x04a085d50,      11520,      11520,     1152,     2304, 0x1c5a76f50,      12672,      12672,     1152,     2304, 0x4ee786230,      13824,      13824,     1152,     2304, 0x8ec861dc0,      14976,      14976,     1152,     2304, 0x0ca179d80,      16128,      16128,     1152,     2304, 0xc6da750f0,      17280,      17280,     1152,     2304, 0xf6bf79b50,      18432,      18432,     1152,     2304, 0x97b88a430,      19584,      19584,     1152,     2304, 0xf13c7b9c0,      20736,      20736,     1152,     2304, 0xdfba83af0,      21888,      21888,     1152,     2304, 0xc9467d4b0,      23040,      23040,     1152,     2304, 0xbbb58e2b0,      24192,      24192,     1152,     2304, 0x3a1078ea0,      25344,      25344,     1152,     2304, 0xe9587a5c此後省略好幾百行0,     880128,     880128,     1152,     2304, 0x3cb185300,     881280,     881280,     1152,     2304, 0x5a0c5e7bbogon:ffmpeg_up liuqi$

從內容上看,這是一個音頻數據的測試文件,timebase是1/44100,採樣率是44100,媒體類型是音頻,音頻格式是pcm_s16le,音頻通道布局是mono。然後下面就是每一幀音頻數據的輸出信息,一共 6 列,分別代表,

當前 packet 的流所在的索引就是 packet->stream_index

當前 packet 的 dts

當前 packet 的 pts

當前 packet 的 duration

當前 packet 的數據包大小

當前數據包的 crc 值

二. 實際操作

那麼這一堆數據是怎麼生成的呢?下面從FATE中找到一個樣例看一下

tests/data/hls_segment_size.m3u8: TAG = GENtests/data/hls_segment_size.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data  $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \  -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_segment_size 300000 -map 0 \  -hls_list_size 0 -codec:a mp2fixed -hls_segment_filename $(TARGET_PATH)/tests/data/hls_segment_size_%d.ts \  $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 2>/dev/null
FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-segment-sizefate-hls-segment-size: tests/data/hls_segment_size.m3u8fate-hls-segment-size: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 -vf setpts=N*23

從例子中可以看到,首先是生成一個m3u8列表,也就是這一段

tests/data/hls_segment_size.m3u8: TAG = GENtests/data/hls_segment_size.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data  $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \  -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_segment_size 300000 -map 0 \  -hls_list_size 0 -codec:a mp2fixed -hls_segment_filename $(TARGET_PATH)/tests/data/hls_segment_size_%d.ts \  $(TARGET_PATH)/tests/data/hls_segment_size.m3u8

這一段最終執行時也就是這樣的

/Users/liuqi/project/ffmpeg_up/dash/ffmpeg \  -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_segment_size 300000 -map 0 \  -hls_list_size 0 -codec:a mp2fixed -hls_segment_filename /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size_%d.ts \  /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size.m3u8 2>/dev/null

然後是下面那一段生成framecrc數據的操作

FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-hls-segment-sizefate-hls-segment-size: tests/data/hls_segment_size.m3u8fate-hls-segment-size: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 -vf setpts=N*23

內容也比較好理解,首先是執行一句tests/data/hls_segment_size.m3u8,在make fate-hls-segment-size的時候首先會執行tests/data/hls_segment_size.m3u8,然後會執行這一句

CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_segment_size.m3u8 -vf setpts=N*23

這裡的framecrc是一個shell封裝函數,這個函數是封裝在tests/fate-run.sh文件中

124 ffmpeg(){125     dec_opts="-hwaccel $hwaccel -threads $threads -thread_type $thread_type"126     ffmpeg_args="-nostdin -nostats -cpuflags $cpuflags"127     for arg in $@; do128         [ x${arg} = x-i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"129         ffmpeg_args="${ffmpeg_args} ${arg}"130     done131     run ffmpeg${PROGSUF}${EXECSUF} ${ffmpeg_args}132 }133134 framecrc(){135     ffmpeg "$@" -bitexact -f framecrc -136 }137138 ffmetadata(){139     ffmpeg "$@" -bitexact -f ffmetadata -140 }141142 framemd5(){143     ffmpeg "$@" -bitexact -f framemd5 -144 }145146 crc(){147     ffmpeg "$@" -f crc -148 }149150 md5pipe(){151     ffmpeg "$@" md5:152 }153154 md5(){155     encfile="${outdir}/${test}.out"156     cleanfiles="$cleanfiles $encfile"157     ffmpeg "$@" $encfile158     do_md5sum $encfile | awk '{print $1}'159 }

最後拼出來的fate執行的效果大概是這樣的

/Users/liuqi/project/ffmpeg_up/dash/ffmpeg -nostdin -nostats -cpuflags all -flags +bitexact -hwaccel none -threads 1 -thread_type frame+slice -i /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size.m3u8 -vf setpts=N*23 -bitexact -f framecrc -

然後將最後一個字符'-'替換成自己的文件名即可,那麼這裡可以替換成tests/ref/fate/hls-segment-size,也就基本上大功告成了。

然後剩下的FATE相關信息,可以參考FFmpeg的官方文檔:

FFmpeg Automated Testing Environment
Table of Contents1 Introduction2 Using FATE from your FFmpeg source directory3 Submitting the results to the FFmpeg result aggregation server4 Uploading new samples to the fate suite5 FATE makefile targets and variables5.1 Makefile targets5.2 Makefile variables5.3 Examples1 IntroductionFATE is an extended regression suite on the client-side and a means for results aggregation and presentation on the server-side.
The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary. The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server.
In any way you can have a look at the publicly viewable FATE results by visiting this website:
http://fate.ffmpeg.org/
This is especially recommended for all people contributing source code to FFmpeg, as it can be seen if some test on some platform broke with their recent contribution. This usually happens on the platforms the developers could not test on.
The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server. If you want to submit your results be sure to check that your combination of CPU, OS and compiler is not already listed on the above mentioned website.
In the third part you can find a comprehensive listing of FATE makefile targets and variables.
2 Using FATE from your FFmpeg source directoryIf you want to run FATE on your machine you need to have the samples in place. You can get the samples via the build target fate-rsync. Use this command from the top-level source directory:
make fate-rsync SAMPLES=fate-suite/make fate SAMPLES=fate-suite/The above commands set the samples location by passing a makefile variable via command line. It is also possible to set the samples location at source configuration time by invoking configure with
./configure make fate-rsyncmake fateYet another way to tell FATE about the location of the sample directory is by making sure the environment variable FATE_SAMPLES contains the path to your samples directory. This can be achieved by e.g. putting that variable in your shell profile or by setting it in your interactive session.
FATE_SAMPLES=fate-suite/ make fateDo not put a 』~』 character in the samples path to indicate a home directory. Because of shell nuances, this will cause FATE to fail.
To use a custom wrapper to run the test, pass
3 Submitting the results to the FFmpeg result aggregation serverTo submit your results to the server you should run fate through the shell script tests/fate.sh from the FFmpeg sources. This script needs to be invoked with a configuration file as its first argument.
tests/fate.sh /path/to/fate_configA configuration file template with comments describing the individual configuration variables can be found at doc/fate_config.sh.template.
The mentioned configuration template is also available here:
slot= repo=git://source.ffmpeg.org/ffmpeg.git samples= workdir= comment= build_only= ignore_tests=
arch=cpu=cross_prefix=as=cc=ld=target_os=sysroot=target_exec=target_path=target_samples=extra_cflags=extra_ldflags=extra_libs=extra_conf=
makeopts= Create a configuration that suits your needs, based on the configuration template. The slot configuration variable can be any string that is not yet used, but it is suggested that you name it adhering to the following pattern 『arch-os-compiler-compiler version』. The configuration file itself will be sourced in a shell script, therefore all shell features may be used. This enables you to setup the environment as you need it for your build.
For your first test runs the fate_recv variable should be empty or commented out. This will run everything as normal except that it will omit the submission of the results to the server. The following files should be present in $workdir as specified in the configuration file:
configure.logcompile.logtest.logreportversionWhen you have everything working properly you can create an SSH key pair and send the public key to the FATE server administrator who can be contacted at the email address fate-admin@ffmpeg.org.
Configure your SSH client to use public key authentication with that key when connecting to the FATE server. Also do not forget to check the identity of the server and to accept its host key. This can usually be achieved by running your SSH client manually and killing it after you accepted the key. The FATE server’s fingerprint is:
『RSA』d3:f1:83:97:a4:75:2b:a6:fb:d6:e8:aa:81:93:97:51
『ECDSA』76:9f:68:32:04:1e:d5:d4:ec:47:3f:dc:fc:18:17:86
If you have problems connecting to the FATE server, it may help to try out the ssh command with one or more -v options. You should get detailed output concerning your SSH configuration and the authentication process.
The only thing left is to automate the execution of the fate.sh script and the synchronisation of the samples directory.
4 Uploading new samples to the fate suiteIf you need a sample uploaded send a mail to samples-request.
This is for developers who have an account on the fate suite server. If you upload new samples, please make sure they are as small as possible, space on each client, network bandwidth and so on benefit from smaller test cases. Also keep in mind older checkouts use existing sample files, that means in practice generally do not replace, remove or overwrite files as it likely would break older checkouts or releases. Also all needed samples for a commit should be uploaded, ideally 24 hours, before the push. If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg-devel.
rsync -vauL
rsync -vanL
rsync -vaL 5 FATE makefile targets and variables5.1 Makefile targetsfate-rsyncDownload/synchronize sample files to the configured samples directory.
fate-listWill list all fate/regression test targets.
fateRun the FATE test suite (requires the fate-suite dataset).
5.2 Makefile variablesVVerbosity level, can be set to 0, 1 or 2.
0: show just the test arguments1: show just the command used in the test2: show everythingSAMPLESSpecify or override the path to the FATE samples at make time, it has a meaning only while running the regression tests.
THREADSSpecify how many threads to use while running regression tests, it is quite useful to detect thread-related regressions.
THREAD_TYPESpecify which threading strategy test, either 『slice』 or 『frame』, by default 『slice+frame』
CPUFLAGSSpecify CPU flags.
TARGET_EXECSpecify or override the wrapper used to run the tests. The TARGET_EXEC option provides a way to run FATE wrapped in valgrind, qemu-user or wine or on remote targets through ssh.
GENSet to 『1』 to generate the missing or mismatched references.
HWACCELSpecify which hardware acceleration to use while running regression tests, by default 『none』 is used.
KEEPSet to 『1』 to keep temp files generated by fate test(s) when test is successful. Default is 『0』, which removes these files. Files are always kept when a test fails.
5.3 Examplesmake V=1 SAMPLES=/var/fate/samples THREADS=2 CPUFLAGS=mmx fate

三 結語

其實要看過程的話,make 自己的tag就可以了,例如這樣

bogon:dash liuqi$ make fate-hls-segment-size V=1
/Users/liuqi/project/ffmpeg_up/dash/ffmpeg \ -f lavfi -i "aevalsrc=cos(2*PI*t)*sin(2*PI*(440+4*t)*t):d=20" -f hls -hls_segment_size 300000 -map 0 \ -hls_list_size 0 -codec:a mp2fixed -hls_segment_filename /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size_%d.ts \ /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size.m3u8 2>/dev/nullTEST hls-segment-sizesrc/tests/fate-run.sh fate-hls-segment-size "" "" "/Users/liuqi/project/ffmpeg_up/dash" 'framecrc -flags +bitexact -i /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size.m3u8 -vf setpts=N*23' '' '' '' '1' '' '' '' '' '' '' '' '' '' '' /Users/liuqi/project/ffmpeg_up/dash/ffmpeg -nostdin -nostats -cpuflags all -flags +bitexact -hwaccel none -threads 1 -thread_type frame+slice -i /Users/liuqi/project/ffmpeg_up/dash/tests/data/hls_segment_size.m3u8 -vf setpts=N*23 -bitexact -f framecrc -bogon:dash liuqi$

讀這篇內容需要一些基礎:

Makefile 基本原理和用法

bash 腳本基本用法

相關焦點

  • Web 自動化神器 TestCafe—用例編寫篇
    使用 TestCafe 編寫測試用例,必須要先使用 fixture 聲明一個測試夾具,然後在這個測試夾具下編寫測試用例,在一個編寫測試用例的 js 或 ts 文件中,可以聲明多個測試夾具import 'testcafe'fixture `登錄功能測試`上面是官方文檔中的
  • 如何更好的設計測試用例
    這就要求我們編寫的測試用例足夠詳細、測試用例的組織要有調理、分主次,單靠Word、Excel或者OneNote這樣通用的工具是遠遠無法完成的,需要更多專用的測試用例管理工具來輔助,例如 Visual Studio 2010引入Microsoft Test Manager。
  • 基於自動化用例的精準測試探索
    (3)自動化用例作用無發有效發揮:對於web/api或app 後端服務系統,測試人員對除手工測試外,嘗試最多的測試手段改進就是接口自動化建設,但自動化建設很少有公司在這個方向做的特別好,投放產出比(ROI)特別高的,其根本原因就是自動化的一個核心指標:穩定性太差,隨著項目的迭代,自動化用例積累越來越多,從幾百到幾千,想要這些自動化用例以CI級別觸發(代碼提交一次即觸發一次),用例全部通過穩定在
  • 如何使用Postman編寫Testlink測試用例
    本文共520字  閱讀約需1分鐘(後臺回復「破解補丁」可獲取一份最新IDEA破解補丁)Postman2Testlink通過Postman快速操作testlink測試用例、測試套件、測試計劃、添加關鍵詞、添加自定義欄位等等。
  • 測試用例的作用
    測試用例是測試設計的主要內容,測試人員按照測試用例執行測試,沒有測試用例測試就無法開展。
  • 測試用例設計總結
    一、什麼是測試用例  測試用例(Test Case)是為某個特殊目標而編制的一組測試輸入、執行條件以及預期結果,以便測試某個程序路徑或核實是否滿足某個特定需求,通俗的講:就是把我們測試系統的操作步驟用按照一定的格式用文字描述出來。
  • 如何做好軟體系統自動化測試?
    Q1:面向技術和支持團隊;這一象限中主要包含單元測試和組件測試。該象限中的測試幫助團隊獲得代碼級別的快速反饋,一般藉助xUnit測試框架,要求完全自動化。Q2:面向業務和支持團隊;這一象限中包含功能測試,原型測試和仿真測試等。該象限中的測試大多也可以自動化,但是需要藉助面向領域專門的測試工具。
  • 什麼是自動化測試?
    二、 自動化測試的基本流程以及注意事項如圖1所示,自動化測試的基本流程主要包含需求分析,自動化測試計劃設計,用例設計,自動化測試框架設計與開發,腳本開發,環境搭建,整體聯調運行等。1) 需求分析:分析哪些點需要進行自動化,在需求分析階段參與進來,在被測代碼開發階段輸出依賴點,保證自動化開發時效率更高,代碼改動更小;2) 用例設計:建議先根據測試點設計所有用例,然後分別查看是否可以實現自動化,最後正向補充可能遺漏的自動化場景;3) 自動化測試框架設計與開發:自動化測試框架與軟體架構類似,定義了在使用該套腳本時需要調用哪些文件
  • 你還在問:安全測試要寫測試用例麼?黑客都在用測試用例找漏洞了
    眾所周知,系統測試是需要編寫測試用例的,它是保證測試執行正確性、有效性的基礎。但是,大家可能很難想像神秘的黑客在挖掘漏洞的時候會提前編寫測試用例,然後按照用例去執行。因為他的漏洞挖掘思路是存在腦海中,並且不斷地根據實際情況進行調整的。
  • 直接告訴你編寫接口自動化用例時會遇到哪些問題
    本篇文章分享幾個接口自動化用例編寫過程遇到的問題總結,希望能對初次探索接口自動化測試的小夥伴們解決問題上提供一小部分思路。1、sql語句內容出現錯誤空格,由於有些欄位判斷是變量,需要將sql拼接起來,但是在拼接字符串時沒有加空格導致報錯錯誤狀態,列印出來就好排查啦,一看and和時間連起來了,果然是這裡出錯修改後,能夠讀到資料庫中內容了2.sql語句格式錯誤
  • 淺談BDD下的自動化測試框架
    本文將通過簡單的例子,向大家展示如何使用Cucumber 描述需求,編寫、執行測試用例,並輸出測試報告。由此BDD的優勢也就體現出來了:更關注業務,以用戶使用產品的角度,描述用戶行為以及預期結果不同角色的人都可以參與需求定義及討論,最終達成一致理解使用同一種語言描述需求,及測試用例,很大程度上避免了因理解差異導致實現功能與需求不一致的問題 我們在前面提到過,BDD最終形成的文檔即是需求文檔,也是測試規範,那麼我們如何基於這些測試規範實現自動化測試呢
  • 我是如何從功能測試成功轉型自動化測試人員的?
    我先基於自己的理解,按照原型圖,設計編寫用例。考核通過後,回到了自己組幹活。重點是開發同事總誇他細心、定位問題快,尤其在測試用例編寫和業務測試方面,我很是羨慕。有時崇拜,也許將會是你進步的巨大助力。成長一般都是從「copy」開始。
  • 【用例設計】如何寫一份漂亮的測試用例?
    ,它直接體現測試設計的思想,一份漂亮的測試用例不僅僅是設計思路的優,更是便於流轉和執行,具有可讀性、傳遞性。  首先,一份漂亮的測試用例-需有一個用例模板  模板的作用:將測試用例的結構形式固定化、標準化,對編寫者啟引導作用,保證一份測試用例數據完整。
  • 技術中臺之DevOps自動化測試實踐
    Devops作為技術中臺的重要組成部分之一,其下「自動化測試」功能也是不可或缺的一環,如何結合DevOps自身提供的自動化測試功能,做好DevOps的接口自動化呢?首先要先了解DevOps為自動化測試提供了哪些功能,如何使用該功能進行自動化測試,以及如何設計測試框架等等,本文將會為大家一一解答。
  • 5分鐘了解自動化測試,自動化優勢、劣勢、工具和框架選擇全剖析
    一、自動化測試基礎知識什麼是自動化測試1、把人為驅動的測試行為改成機器執行,通過設計的測試用例,由機器按照測試用例的執行步驟對其進行自動操作,輸出結果,由測試人員進行比較。2、自動化測試往往通過一些測試工具或框架,編寫自動化測試用例,來模擬手工測試。3、自動化測試能極大的節省人力、時間和硬體資源,提高測試效率。
  • 關於測試用例編寫你不得不了解的那些事兒!
    對於一個軟體測試人員來說,編寫測試用例是不可或缺的一項技能,但怎麼寫好一個需求的測試用例卻不是很容易,特別對於新手來說,更是不容易,我也是從新手一步步走過來的,下面我就把我的經驗總結出來供大家參考吧。測試用例是什麼這個問題很簡單但卻不能不知道,剛入行,我們會很懵,弄清楚這個問題,對我們接下來寫測試用例非常有幫助。
  • 你不知道的用例編寫方法
    作為一名測試人員,總會有需要進行用例編寫的時候,在進行用例編寫時都遇到過什麼問題呢?  小編詢問了一些測試人員,結合自己遇到的問題,總結了一些,一般會有以下幾個方面的問題:  1) 不知如何著手進行,千頭萬緒,不知如何理  2) 用例覆蓋度不高,不知該如何提高  3) 培訓機構學來的知識不知道如何使用  4) 用例結構不清晰,容易遺漏,且維護麻煩  這些問題都是作為一名測試人員
  • 為什麼需要前端自動化測試呢?
    同時受需求變化的影響變大,重複利率降低同時編寫測試用例的時間變長 、執行的時間也響應變長另一方面,由上至下,發先的bug數量逐漸變小。所以,從發先bug數量/編寫測試用例時間&重複利用率的緯度上講,單元測試的收益最大,越向上收益越小。這也是大部分項目中採用的自動化測試,是在單元測試這一層的原因。
  • 測試用例的管理
    隨著軟體系統規模的持續增大,業務複雜度的持續增加,軟體測試的複雜度也隨之越來越大。而軟體測試工作複雜度的直接體現,就是測試用例編寫、維護、執行和管理,所以編寫易讀、易維護和易管理的測試用例可以有效的降低測試工作的複雜度。本文主要系統的介紹了測試用例的幾種管理方法,包括每種的特點,適用場景以及實例。
  • 移動端自動化測試策略
    在設計移動端自動化測試策略的時候,我們可以思考以下幾個問題,看我們能否給出合理的理由:為什麼要做移動端自動化測試,自動化測試的價值在哪裡你的項目中質量內建成熟度如何?如果單元測試足夠覆蓋的情況下,是否還有必要做端到端自動化測試?是否已經有移動端專項測試體系了,如性能,安全,兼容性,穩定性等?