2013-02-12 95 views
16

我們最近升級到JavaScript縮小庫的較新版本。如何測試JavaScript縮小輸出

經過測試團隊進行大量質量保證工作後,發現我們minifier的新版本存在一個問題,它改變了代碼塊背後的意圖和含義。

(生命的教訓:除非你真的相信你需要新的版本不升級JS minifiers)

的minifier用於客戶端以沉重強調DOM相關活動的JavaScript代碼,幾乎沒有儘可能多的「商業邏輯」。

什麼是由minifier升級打破了簡單的例子:

function process(count) 
{ 
    var value = ""; 
    value += count; //1. Two consecutive += statements 
    value += count; 
    count++;  //2. Some other statement 
    return value; //3. Return 
} 

正確當時精縮到以下幾點:

function process(n){var t="";return t+n+n,n++,t} 

雖然我們可以寫一些單元測試來捕捉一些的問題潛在地,由於JavaScript在DOM交互(數據輸入等)方面很重要,所以在沒有用戶測試(非自動化)的情況下進行徹底測試是非常困難的。我們曾想過使用像Esprima這樣的JS to AST庫,但考慮到可以對縮小代碼進行更改的性質,它會產生太多的誤報。

我們也考慮嘗試編寫具有代表性的測試,但這似乎是一個永無止境的任務(可能會遺漏案例)。

供參考:這是一個非常複雜的Web應用程序,包含幾十萬行JavaScript代碼。

我們正在尋找一種測試縮小過程的方法,因爲「只需再次測試一切,徹底並重複測試」。我們希望在這個過程中應用更多的嚴謹/科學。

理想情況下,如果我們有更好的科學測試方法,我們可以嘗試使用多個minifier而不用擔心每次都會以新的細微方式破壞我們的代碼。

更新:

一個想法,我們必須是:

  1. 採取縮小與舊版本
  2. 美化它
  3. 縮小與新版本,
  4. 美化,並
  5. 視覺差異。

它似乎確實是一個好主意,但差異非常普遍,diff工具幾乎將每一行標記爲不同。

+3

您使用哪種微粉機? – Blender 2013-02-12 20:36:41

+0

我無法說明我與這個問題有多大關係。示例代碼充其量是歡鬧的。 – Arindam 2013-02-12 20:36:44

+0

@ Blender-Microsoft Ajax Minifier 4.74在這種情況下。 – WiredPrairie 2013-02-12 20:41:02

回答

0

你可以看看像Selenium Web Driver這樣的東西,它允許你在各種環境下自動測試web應用程序。有一些雲託管的虛擬機解決方案用於多環境測試,所以當它在Webkit中工作時不會被抓到,但在IE中不會被捕獲。

+1

我們實際上使用它來今天進行一些自動化測試。我們的應用程序工作流程具有高度的互動性,所以它有很多工作。這涵蓋了基礎知識 - 但我們正在尋找更深入(更科學)的東西,理想情況。 – WiredPrairie 2013-02-13 17:37:58

1

你有沒有考慮過單元測試框架,比如QUnitjs?編寫單元測試將是一項相當大的工作,但最終你會有一個可重複的測試過程。

+1

這是一個有趣的想法,考慮某些情況下 - 因爲我們的Web應用程序非常豐富,單元測試JavaScript UI的東西已被證明是困難的。你有什麼意見來補充你已經做了什麼來使用單元測試框架來測試JS/DOM重度交互嗎? – WiredPrairie 2013-02-13 18:17:06

0

你絕對應該考慮使用源地圖來幫助調試JavaScript的最小化。源地圖還可以與JavaScript的超集一起使用,例如CoffeeScript或我最喜歡的TypeScript。

我用封編譯器不僅minifies,也將創建源地圖。更不用說它是最積極的並且產生最小的文件。最後,你必須知道縮小的過程以及編寫兼容的代碼,你的示例代碼可以使用一些重構。

退房這篇文章來源地圖:如何編寫用於縮小率更好的代碼 http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

還檢查出關閉編譯器的文檔,它有建議: https://developers.google.com/closure/compiler/

+0

在某些情況下,我可能很有興趣切換源代碼地圖調試,但我們如何做我們正在尋找的比較?你認爲我們可以隨時比較兩個版本嗎? (源代碼只是最初導致此問題的代碼塊的一個非常簡單的示例。) – WiredPrairie 2013-02-15 11:48:25

+0

我認爲您需要儘可能多地瞭解您的情況,因此源地圖只能提供幫助。在一天結束時,沒有任何東西可以替代測試和任何大型網絡應用程序。你絕對需要使用單元測試,自動化測試(我使用Canoo Webtest/http://webtest.canoo.com/)和手冊。 至於直接比較你的老粉碎機和你的新粉碎機在做他們的工作,我不認爲有任何好的方法來做到這一點。他們根據意圖做了不同的事情,所以產出會有所不同,在我看來,一對一是一種有爭議的事情。 – chris 2013-02-15 21:15:39

0

不是一個測試解決方案,但如何切換到TypeScript來編寫像你的大JS應用程序?

我打字稿及默認的最低引擎測試了它,它工作正常。

假設你count arg是一個數字。

類型的腳本將是:

class ProcessorX { 
    ProcessX(count: number): string { 
     var value = ''; 
     value += count.toString(); 
     value += count.toString(); 
     count++; 
     return value; 
    } 
} 

將會產生JS是這樣的:

var ProcessorX = (function() { 
    function ProcessorX() { } 
    ProcessorX.prototype.ProcessX = function (count) { 
     var value = ''; 
     value += count.toString(); 
     value += count.toString(); 
     count++; 
     return value; 
    }; 
    return ProcessorX; 
})(); 

然後精縮到:

var ProcessorX=function(){function n(){}return n.prototype.ProcessX=function(n){var t="";return t+=n.toString(),t+=n.toString(),n++,t},n}() 

這是對jsfiddle

如果您的countstring,那麼這個fiddle

+0

較新的縮小器不再有問題。 – WiredPrairie 2013-02-20 20:00:04

0

我們使用在高級模式下關閉編譯器,既minifies和修改代碼,因此我們編譯我們的單元測試一樣,所以你可以考慮涅槃你一起測試你的代碼,並像運行它。

+0

如果您的測試由於縮小而在其中產生了錯誤,那麼測試測試的內容是什麼? – Sammaye 2013-04-11 17:27:09

+0

編譯器顯然有針對它編寫的測試,我們想要避免的是人們試圖解決像someObj ['someFunc']()這樣的函數,因爲這將違反高級優化,並且是一個非常常見的JavaScript成語。在我們的迴歸測試中,另一件事(特別是完整棧的閉包)我們要確保通過重命名映射引用css名稱。 – lennel 2013-04-14 09:35:40

1

聽起來好像是你需要開始使用CI(持續集成環境)內的自動單元測試。 QUnit已經被拋棄了,但是真正的QUnit是一個相當弱的測試系統,它的斷言至少是準系統(它甚至沒有真正使用好的基於斷言的語法)。它只能勉強符合TDD的要求,也不能很好地處理BDD。

我個人建議JasmineJsTestDriver(它可以使用其他UT框架,或它自己的,並且非常快速...雖然它有一些穩定性問題,我真的希望他們會修復),並設置單位可以通過多重比較檢查縮小過程的測試。

一些比較可能會需要是:

  • 原代碼&其功能的行爲與預期
  • 相比縮小的代碼(這是BDD進來,期望在精縮相同的功能性能/結果代碼)
  • 我甚至會更進一步(取決於您的縮小方法),並進行測試,然後美化縮小並進行另一次比較(這會使您的測試更加穩健並更有效)。

這些類型的測試是爲什麼你可能會受益於像Jasmine這樣的BDD-capable框架,而不是純粹的TDD(ala你發現的視覺差異的結果是一團糟),因爲你正在測試行爲和比較以及功能/行爲的先前/後期狀態,而不僅僅是如果a在分析後是真實的並且仍然是真實的。

建立這些單元測試可能需要一段時間,但它是一個迭代方法,用一大堆代碼庫......快速和早期測試你的初始關鍵點或脆弱點,然後將測試擴展到一切(我的方式總是把我的團隊設置爲:從現在開始的任何事情都不被認爲是完整的,並且RC除非它有單元測試......任何沒有單元測試並且必須被更新/觸摸/維護的舊的必須有單元測試他們很感動,這樣你就可以不斷改進和縮小未經測試的代碼數量,同時增加代碼覆蓋率)。一旦你在CI中進行了單元測試並運行,你就可以將它們綁定到你的構建過程中:沒有單元測試的失敗構建,或者當單元測試失敗時發出警報,主動監視每次檢查,等等等自動生成文檔與JSDoc3等等

您正在描述的問題是CI和單元測試是什麼建立的,更具體地說,在你的情況下,該方法最大限度地減少了代碼庫......這個大小並沒有讓它變得更加複雜,只是讓持續時間更長,讓測試工作變得更長。

然後,將其與JSDoc3相結合,並且您的樣式優於大多數前端商店的90%。它在這一點上對工程師來說非常強大和有用,並且變得自我延續。

我真的可以繼續談論這個話題,對於你如何接近它並讓一個團隊在它背後凝聚力並使之自我形成和自我延續,以及最重要的是存在很多細微差別編寫可測試的代碼......但從概念層面... 編寫單元測試並自動化它們。總是。

太長時間的前端開發者一直半開發,沒有應用實際的工程嚴謹和紀律。隨着前端越來越強大,越來越熱,它必須改變,並且正在發生變化。爲前端/ RIA應用提供經過良好測試,覆蓋範圍廣泛,自動化測試和持續集成的概念是這一變化的巨大需求之一。