2019年1月5日 星期六

[MahoMangaDownloader] 增加自動測試功能

非常少見的不是下載器更新文!!  (先吐槽自己一下XD)

值得慶賀的是, MahoMangaDownloader終於把自動測試的功能做好了, 這代表我以後改版都可以脫離該死的手動測試網站, 也不用擔心哪一天網站改版導致下載器失靈又不知道, 拖到使用者通知我才能開始修了。

為什麼手動測試麻煩得要死, 而且漫畫網站那麼常改版我又不做自動測試呢?  原因很簡單.....因為我真的太懶了, 有時間都花在宅休閒上, 找到事情想做通常也是新的東西, 下載器認真說已經maintain好幾年了, 對一個一直沒新功能只是在maintain的專案, 提不起勁寫自動測試也是很合理的吧?

關於上面這問題, 一定會有人覺得, 明明手動測試才是麻煩得要死, 尤其網站改版又這麼頻繁, 會想做自動測試才是合理的吧?  這個答案沒錯, 所以這邊我必須坦白的是.....

其實這幾年改版我手動測試都是選擇性隨便做一做而已!!! (吶喊 + 土下座謝罪)


那為什麼現在才要真的開始做自動測試了?  理由很簡單: 

"公司要求RD開TDD(Test-driven development)的study group, 所以目前第一階段在看單元測試的書"

我想說既然都要開始K單元測試了, 那我乾脆也趁這機會把這塊肉刺拔掉吧, 這樣以後下載器要維護也方便得多, 也可以當作寫測試的練習, 利益剛好一致那就來做吧!!


------ 我是分隔線 ------


好吧, 既然真的決定要寫測試了, 那要寫什麼測試?  最重要的當然還是每次網站改版, 導致下載器parser失靈不能載漫畫最重要了, 目前程式跟下載有關的function其實就是這三個:



GetSource是負責取得這部漫畫有那些篇章(話數); GetPageUrlList則是取得該章漫畫有幾頁以及對應的url; 而GetDownloadImg則是依據給的url去取得正確的圖源位址並下載到電腦裡。

這三個function會由各個漫畫網站的class去負責實作, 然後再由MangaFactory class依據漫畫網站生成實例:


如果要滿足我們最底限的需求, 只要測試這三個function是不是都能正常工作, 如果網站改版導致下載器不能下載的話, 運行測試時就會失敗, 這樣就能知道哪個網站有改版需要重新改寫parser了。

至於測試部分的程式也非常簡單, 如下所示:

建構式 (建立MangaFactory實例, 目前做的測試算是integration test, 畢竟下載相關的function也跟一些檔案有關(e.g. cookie), 所以會需要做一些設定初始化去取得需要的資料。):


在來就是針對上述三個function提供測試資料, 目前做法是每個支援網站都挑三組漫畫出來, 並測試這三個function運行測試是否都能PASS, 如果PASS就代表下載器目前還是能正常下載各個漫畫網站的漫畫, 由於都長差不多, 這邊就只貼GetSource的test case:



在來就是跑運行啦!!  不過非常殘念的是, 有一半以上的測試都fail了, 原因在於如果是有隱藏圖源的漫畫網站, 我是使用CefSharp這個Chromium核心的瀏覽器套件去取得圖源位址, 而Chromium是用C++ & 一些其他語言實作出來, 並不是純.Net的程式, 以下兩個原因導致NUnit在運行時會出問題:

1. CefSharp的相關dll一定要跟呼叫他的main process在同一個資料夾位置, 而NUnit的test runner在運行測試時的process卻在不同地方。

2. unit test是跑在分離式的AppDomain, 而CefSharp只能運作在default AppDomain。

我試著不用NUnit改用MSTest結果也是一樣,  如果不能用現有框架, 那最慘情況就是我得浪費時間自己手動刻整個測試程式框架, 不過幸好有在CefSharp github issue找到workaround方法, 雖然沒辦法用Visual Studio的test adapter去跑unit test, 但是使用NUnit console下cmd的方式直接跑test dll是可行的, 這樣test runner process就跟CefSharp的dll放在一起, 而且他也提供AppDomain設定的參數, 問題就解決了!! (雖然看不到精美的GUI測試結果很可惜就是了XD  CefSharp不能跑unit test的issue詳細可以參考這裡)。



測試程式搞定了, 在來就是每天讓他跑自動測試啦,  由於我很久之前就有設定下載器的專案在VSTS CI上了, 在來只要將出build的設定從有改變就出build, 改成每日定時出build, 在把測試的cmd加進build steps就大功告成了!!




目前設定每天早上六點會定時出build, 最近一次在CI上的測試結果也都正常, 這下終於能丟掉手動測試了!!!   YA!!!

最後就是慣例的只要不是下載器更新文最後就要來張宅圖啦~~!!!  爆肝完就是要來瓶維士比(雖然我沒喝過就是了XD)