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)


35 則留言:

  1. 太感謝大師還在持續更新維修,應該還有很多潛水用戶不好意思浮出水面,相信用的人還是很多的!!!一天沒有偽娘不行啊

    回覆刪除
    回覆
    1. 感謝你一直以來的支持!! 也對閣下對偽娘的娘敬禮!!

      很久之前我更新還會去ptt發個文增加曝光度, 現在我都很少做了, 怕太高調被漫畫網站針對OTL

      嘛~不過就算被針對,下載器只要我還有在繼續使用, 就會一直維護下去啦:)

      刪除
  2. 7.1"狀態100%"仍是Ready能否設個秒數變Pause?
    每次就卡在那要人工手動處理

    ex有時會下到這種圖12bytes,內容是Unauthorized
    昨天下了12h有四張12bytes
    https://drive.google.com/open?id=1iYxcHjhplJ35sG1JY76SyDfTRhtotbss

    回覆刪除
    回覆
    1. 您好, 我的環境目前沒遇過Unauthorized的問題, 照理說Ready卡住只要失敗三次就會自動變pause, 沒變的情況通常是網站改版所以卡在奇怪的地方, 這個就只能case by case處理了...

      刪除
  3. 大大你好!萬分感謝你的無償付出讓我們能受惠!
    我是新使用者有一個問題,在E-Hentai打包時,常常會出現明明進度只完成了70-80%,
    但卻會彈出"all mission completed!" , 這是不是被它們封了ip的情況?
    已經連續好幾部都這樣, 有點煩腦T.T

    回覆刪除
    回覆
    1. 您好, 你可以看其他任務的狀態欄是不是都是pause, 如果是的話那八成就是被ban ip了。 你也可以直接用瀏覽器上去網站看看, 如果是ban ip應該網站也不能上去了。 如果不是則應該是其他問題, 可能就要麻煩您提供程式底下的log檔案我在分析看看。

      目前針對ban ip的處理方式, 下載器設定的地方有一個換ip的功能, 不過要使用的話前提是你的電腦網路環境是浮動ip, 這樣這功能才有辦法運作。

      如果網路環境不是浮動ip的話, 那基本上無解, 只能建議少量下載了。

      刪除
    2. 感謝你的回答,無償免費使用你的軟件還要嘛煩你真的不好意思~
      狀態欄是pause,而且我本身的ISP是固定IP所以無法更換IP
      但我直接用瀏覽器上去E站是可以的,打包的是這一部
      https://e-hentai.org/s/3c0d856890/1321264-1521
      到1434/1670 (85%) 老就停了不再動,是不是頁數太多被擋了?
      之後好幾部到70%左右也一樣停了,全部都過千頁

      log檔案上傳給你看看
      https://drive.google.com/file/d/1iSO4T7veVeifDw4tFZW-Cn9eXOY8jV7H/view?usp=sharing

      刪除
    3. 您好, 我測試了下該資源我有成功下載完, 不過這個頁數太多, 是有機會還沒下載完就被網站ban ip, log看起來也是被ban ip了。

      至於瀏覽器上去可以, 可能要看你的電腦是不是有雙網卡或是有設代理伺服器, 所以瀏覽器才能瀏覽網站可是下載器不能連到網站。

      另外想請問一下, pause後你有重設ready在重新下載嗎? 還有一種情況是某個圖檔暫時性失聯, 這種情況也會下載失敗, 只能過陣子在重新下載, 再麻煩您試試看。 還有問題的話我再研究看看。

      刪除
    4. 我應該沒有用雙網卡或是代理伺服器,
      而且後來我嘗試打包只有幾百頁的漫畫也能完成100%
      只有這幾個1000頁+的才會發生問題
      估計是被ban了,
      但很奇怪用瀏覽器(chrome)能直接上去看想打包幾千頁的那幾個漫畫....
      只能過陣子在重新下載了...感謝你~

      刪除
    5. 實際上, 下10本100頁的漫畫, 跟下一本1000頁的漫畫, 後者被ban ip的可能性的確比較高, 因為要抓1000頁的漫畫, 下載器得先跳轉25次(40*25)才能知道所有的頁數, 這過程會加速被網站察覺非法流量的可能, 所以遇到這種情況也只能等一陣子後將pause手動轉ready繼續下載了。 ban ip的問題現在就只能換ip, 沒有其他方法, 不然就是加大delay時間減少ban ip的機率。

      刪除
  4. 您好
    感謝您的程式
    我本身是固定ip
    已經被manhuagui ban了
    請問 他會在還回來嗎?
    大大有實測過嗎?
    謝謝

    回覆刪除
    回覆
    1. manhuagui大量下載有機會被ban, 我被ban過幾次都有回來, 不過我不確定時間大概多久。

      如果網路環境是固定IP的話, 建議manhuagui還是少量下載, 或是主要使用dm5為主。

      刪除
  5. 請問出現 並未將物件參考設定為物件的執行個體 改怎麼解決

    回覆刪除
    回覆
    1. 您好, 會有這個錯誤通常是下載器拿不到網站的資料, 可以麻煩你提供更詳細的資訊嗎?

      1. 出現問題的url
      2. log資料夾內的log錯誤訊息

      刪除
    2. ERROR 2019/02/17 08:21:34 MahoMangaDownloaderForm ? 並未將物件參考設定為物件的執行個體。

      刪除
    3. 開啟MahoMangaDownloader執行檔就出現這個不能開

      刪除
    4. 您好, 目前猜測可能是以下問題:
      1. 系統環境有問題
      2. 防毒軟體隔離了一些必要的dll

      麻煩確認下電腦是否有安裝:
      1. .Net framework 4.5.2 or later
      https://www.microsoft.com/zh-tw/download/details.aspx?id=42642

      2. Visual C++ 2013
      https://www.microsoft.com/zh-TW/download/details.aspx?id=40784

      另外可以的話, 麻煩測試一下關掉防毒軟體後, 解壓縮下載器並執行看能不能順利運行。

      如果一樣不能解決的話, 我再研究看看是什麼問題造成。

      刪除
    5. 我發現原因了,是 KB4483452 適用於 Windows 10 1809 版和 Windows Server 2019 的 .NET Framework 3.5 和 4.7.2 的累積更新 更新檔惹的禍,移除就好了

      刪除
    6. 您好. 問題有解決就好, 也謝謝你幫忙測試, 之後如果有人有一樣的問題, 我會先請他嘗試你提供的方法, 十分感謝~~~~~

      刪除
  6. 請問目前 看漫畫(manhuagui)還可以使用嗎?
    18號晚間開始不管下載什麼都會變pause
    不過直接連過去卻可以看 沒有被擋IP
    謝謝

    回覆刪除
    回覆
    1. 您好, 我剛剛測試是能正常下載的, 可以請你看一下log資料夾裡面的log檔案寫的錯誤訊息是什麼嗎?

      另外可以的話麻煩提供其中一個不能下載的網址, 我在測試看看。

      刪除
    2. 謝謝您的回應!
      狀況為原本的IP在17號下載到被ban&一天內無法連進去網頁
      但開跳版後可以繼續下載&連進去網頁

      現在的情況為原本IP不能下載 但可以連進去網頁
      而開跳版也不能下載 但可以連進去網頁
      剛剛再試一下還是一樣狀況
      會顯示為 第1頁/總頁數 pause


      LOG內寫的是
      ERROR 2019/02/20 20:25:10 ImgFile download_file System.UriFormatException: Invalid URI: The URI scheme is not valid.
      at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
      at FileIO.ImgFile.download_file(String download_url, String path, String file_name_no_extension, List`1 headers, Image_Format img_format)
      以及
      WARN 2019/02/20 20:25:12 DownloadProcess DoWorker Download Img exceed retry count
      兩條一直重覆

      剛剛測試的漫畫為
      https://tw.manhuagui.com/comic/22153/
      麻煩您了,謝謝

      刪除
    3. 補充:
      後來嘗試一下用另一台電腦下載manhuagui可以下載(同一條網路)
      但是原本那台電腦還是不可以(18號晚間前可以)
      嘗試程式重新下載也是不行 但像是99漫畫那些卻可以使用
      狀況大概是這樣,謝謝

      刪除
    4. 您好, 不好意思現在才看到, 看log原因出在下載器parse不到正確的url路徑, 比較可能的情況是ban ip, 如果你的網路是支援動態ip, 可即便同一條網路也可以拿到多個ip的話, 所以另外一台電腦才能下載, 而被ban的那一台則不行。

      如果你的網路是動態IP的話, 可以麻煩做個簡單測試嗎?
      麻煩執行User_Data資料夾裡的renew_ip.bat, 看windows有沒有得到新的ip, 如果有的話再重新測試看看, 看下載器是否能正常下載。

      刪除
    5. 謝謝您的回應
      嘗試一下上面步驟沒有獲得新的IP
      關係被BAN的部份
      一樣是只有下載器無法下載 直接連去網站沒有被擋
      所以應該不是IP被BAN的問題
      因為當初被BAN時 全部同一條網路的裝置是連網站都進不去的
      看漫畫的部份打算先用其他電腦來下載了
      目前打算等浮動IP更換後在看看能不能繼續使用
      謝謝您抽空回答我的問題 真的非常感謝您的幫忙

      刪除
    6. OK, 那有其他問題再跟我說, 像這種沒有辦法reproduce的問題真的很難處理> <

      另外我有想到一個問題, 看漫畫網站後來有增加tw子網域, 目前下載器是不支援TW子網域去新增漫畫的, 要加入下載時請先記得把tw換成www, 才可以正常新增漫畫跟下載。

      tw子網域支援會在下一版修正:)

      刪除
    7. 好的 謝謝您的回覆
      關於看漫畫的TW子網域 以前記得是某些漫畫可以用 某些不行
      後來是都用簡體的www網域來抓
      上面被BAN過後 測試是兩邊都不行就是了
      再次感謝您願意寫出這麼方便的程式給大家使用 謝謝您

      刪除
  7. 你好,這幾天在下載e紳士的漫畫時,常只下載前幾頁而已

    log檔出現錯誤如下

    ERROR 2019/03/17 10:35:54 ImgFile download_file System.AggregateException: 發生一或多項錯誤。 ---> System.Net.WebException: 在 WebClient 要求期間發生例外狀況。 ---> System.IO.IOException: 由於另一個處理序正在使用檔案 'C:\Download\_tmp_[?????] ?体?女?寮 4 (COMIC ?????? 2018年5月?) [中?翻?] [DL版]\3.jpg',所以無法存取該檔案。
    於 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    於 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    於 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
    於 System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken)
    --- 內部例外狀況堆疊追蹤的結尾 ---
    --- 內部例外狀況堆疊追蹤的結尾 ---
    於 System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
    於 System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
    於 System.Threading.Tasks.Task.Wait(TimeSpan timeout)
    於 FileIO.ImgFile.download_file(String download_url, String path, String file_name_no_extension, List`1 headers, Image_Format img_format)
    ---> (內部例外狀況 #0) System.Net.WebException: 在 WebClient 要求期間發生例外狀況。 ---> System.IO.IOException: 由於另一個處理序正在使用檔案 'C:\Download\_tmp_[?????] ?体?女?寮 4 (COMIC ?????? 2018年5月?) [中?翻?] [DL版]\3.jpg',所以無法存取該檔案。
    於 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    於 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    於 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
    於 System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken)
    --- 內部例外狀況堆疊追蹤的結尾 ---<---

    回覆刪除
    回覆
    1. 你好, 這情況是檔案被lock住了, 通常網路不穩下載timeout會比較容易發生, 目前解決方法只有下載器關掉, 然後把壞掉的圖檔砍掉, 再開啟下載器重新下載。

      刪除
  8. 您好,這兩天e紳士又經過一次頁面UI的改版,目前版本7.1_32位元的程式已經無法像改版前一樣用搜尋到了,重置cookie也一樣,不知道是否又需要新的版本了呢?

    回覆刪除
    回覆
    1. 您好, E變態更新後, 有兩個地方有改:
      1. 搜尋頁面的UI變了, 所以下載器的搜尋功能的parser壞了。
      2. 現在cookie的檢查機制多驗了一個sk key, 所以一堆本子舊的cookie會搜尋不到而且無法下載。

      目前這兩個功能我昨天有先修好, 不過怕他改版不太穩, 所以我會先測試個幾天 (以前遇過網站測試只改版一天就改回來的, 所以現在比較傾向過幾天後確定沒問題在更新), 預計這周五~周六會更新。

      刪除
  9. 我的 manhuagui 也被 ban 了 ...
    這次好像回不來了
    搜尋 manhuagui 被 ban 找到這 XD

    感謝大大分享!
    自動測試寫好真的讚
    學以致用!

    回覆刪除
    回覆
    1. manhuagui這網站真的很詭異, 我現在直接隨緣了, 真的找不到的才會試著載, 在不行就是用VPN在載了...。

      我自動測試也是寫爽的, 只有測試能不能正常下載, 這樣只要測試一出問題就代表網站八成又改版了, 這才是我主要目的XDD

      刪除