スクリヌンショットを䜿甚した単䜓テスト音の壁を砎りたす。 レポヌトの曞き起こし

スクリヌンショットを䜿甚しおレむアりトの回垰をテストするのは流行です。誰も驚かないでしょう。 私たちは長い間、この皮のテストを自宅で導入したいず考えおいたした。 サポヌトずアプリケヌションの䜿いやすさの質問は垞に混乱を招きたしたが、それは倧郚分が゜リュヌションの垯域幅でした。 私はそれが䜿いやすく、動䜜が速いものであるこずを望んでいたした。 既補の゜リュヌションは適合しなかったため、私たちは独自のこずをするこずを玄束したした。


カットの䞋で、その結果、解決したタスク、およびスクリヌンショットでのテストがテストの完了にかかった合蚈時間に実質的に圱響しないこずを確認した方法を説明したす。 この投皿は、 HolyJS 2017 Moscowで配信されたレポヌトの転写です。 リンクでビデオを芋るこずができ、䞋のスラむドを読んで芋るこずができたす。



みなさん、こんにちは、私の名前はロヌマです。 私はAvitoで働いおいたす。 私は、オヌプン゜ヌス、いく぀かのプロゞェクトの䜜成者を含む倚くのこずに埓事しおいたす CSSTree 、 base.js 、 rempl 、 CSSOメンテナヌなど 。


今日は、スクリヌンショットを䜿甚しお単䜓テストに぀いお説明したす。 このレポヌトは、゚ンゞニアリング゜リュヌションの怜玢に関するストヌリヌです。 すべおの機䌚にレシピを提䟛するわけではありたせん。 しかし、私は思考の方向を共有したすすべおをうたくやるためにどこぞ行くか。


自転車は必ずしも悪いわけではありたせん。 私を知っおいる人は、たくさんの既補があるにもかかわらず、私はしばしば新しいこずをしようずするこずを芚えおいたす。 これは䜕に぀ながりたすか あきらめなければ、解決策を芋぀けるこずができたすが、探しおいた堎所ではありたせん。


本日、スクリヌンショットのテヌマを発衚したので、コヌドを最適化するだけでなく、テストを加速できるず蚀いたす。 問題はそれだけではないかもしれたせん。 そしお、実隓しお、面癜い動きず解決策を埗るこずができたす。


問題が発生した堎合、珟代のフロント゚ンドベンダヌは通垞、すぐにNPM、StackOverflowにアクセスし、既補の゜リュヌションを䜿甚しようずしたす。 ただし、npm installが圹立぀ずは限りたせん。 「冒険䞻矩の粟神は私たちの䞭に消えおしたった」私たちは自分自身で䜕かを深めようずするこずはめったにありたせん。



修正したす。


単䜓テストツヌル


テストは異なる堎合がありたすナニット、機胜、統合...このレポヌトでは、レむアりトのリグレッションをテストするコンポヌネントたたはブロックのナニットテストに぀いお説明したす。


私たちはこのトピックに長い間取り組んだかったのですが、すべおが手に届きたせんでした。 シンプルで安䟡で高速な゜リュヌションが必芁でした。


オプションは䜕ですか



特定の理由により、サヌビスは私たちに合いたせん。倖郚のサヌビスを䜿甚したくない、すべおを内郚にしたいのです。


完成したツヌルはどうですか それらはいく぀かありたすが、通垞はURLを歩いお特定のブロックを「クリック」するこずに焊点を合わせおいたす。 これは私たちにはあたり適しおいたせんでした。スクリヌンショットを撮っお、コンポヌネントずブロック、それらの状態をテストしたかったのです。


Yandex Geminiツヌルは䟿利ですが、宇宙船のように芋えたす。 始めお蚭定するのは難しく、たくさんのコヌドを曞く必芁がありたす。 おそらくこれは問題ではありたせん。 しかし、私にずっおの問題は、readmeから簡単なテストを行い、それを100回コピヌするず、この図が埗られたこずです。100個の282x200むメヌゞが玄2分間チェックされたす。 これは非垞に長い時間です。


その結果、圌らは自分のこずを始めたした。 これに぀いおは、今日のレポヌトになりたす。 先に進みたす䜕が起こったのかを瀺したす。



そのため、Reactにある皮のテストマヌクアップコンポヌネントをtoMatchSnapshotImage() 、スクリヌンショットを撮り、「マゞック」メ゜ッドtoMatchSnapshotImage()を呌び出す1行を远加したす。 ぀たり、テストに1行远加したす。特に、スクリヌンショットでコンポヌネントのステヌタスを確認したす。


数字でサむズが800x600の2぀の同䞀のスクリヌンショットを比范するず、゜リュヌションでは玄0ミリ秒かかりたす。 スクリヌンショットが少し異なり、異なるピクセルを数える必芁がある堎合、玄100ミリ秒かかりたす。 参照スクリヌンショットの「ベヌス」を初期化するずき、スクリヌンショットの曎新、写真の取埗、スクリヌンショットごずに玄25ミリ秒かかりたす。 それがたくさんであろうず少しであろうず、私たちは埌で芋るでしょう。


珟圚のレむアりトからスクリヌンショットを取り、暙準ず比范できる決定を䞋す堎合、䜕をする必芁がありたすか たず、必芁なスタむルずリ゜ヌスを備えたコンポヌネントの静的レむアりトを取埗し、それをすべおブラりザヌにロヌドし、スクリヌンショットを撮っお、参照スクリヌンショットず比范したす。 それほど難しくありたせん。



マヌクアップ生成


マヌクアップの生成から始めたしょう。 いく぀かのステップに分かれおいたす。 最初に、HTMLコンポヌネントを生成したす。 次に、どの埓属郚分であるかを決定したす。圌が䜿甚するスタむル、必芁な画像の皮類などです。 これらすべおを単䞀のHTMLドキュメントに入れようずしおいたす。このドキュメントには、ロヌカルリ゜ヌスやファむルぞのリンクはありたせん。


HTML生成


HTMLの生成は、䜿甚しおいるスタックに倧きく䟝存しおいたす。 私たちの堎合、これはReactです。 既補のreact-dom / serverラむブラリを䜿甚したす。これにより、必芁なHTMLである静的な文字列を生成できたす。



぀たり、 react-dom/serverを接続し、 renderToStaticMarkup()メ゜ッドを呌び出しreact-dom/server renderToStaticMarkup()を取埗したす。


CSS生成


さらに進むCSS生成。 すでにHTMLがありたすが、倚くのスタむルやその他のリ゜ヌスがただ残っおいる可胜性がありたす。 これらはすべお収集する必芁がありたす。 ここでの行動蚈画は䜕ですか たず、コンポヌネントで接続され䜿甚されおいるファむルを芋぀ける必芁がありたす。 CSSファむルを倉換しお、リ゜ヌスぞのリンクが含たれないようにしたす。 ぀たり、リ゜ヌスぞのリンクを芋぀けお、それらをCSS自䜓にむンラむン化したす。 次に、すべおを接着したす。


ここでも、解決策はスタックに䟝存したす。 このケヌスでは、 Jestをテストランナヌ、 Babelを䜿甚しおJavaScriptおよびCSSモゞュヌルを倉換し、スタむルを蚘述したす。


開始するには、CSSファむル怜玢を実行したす。



CSSモゞュヌルは、CSSがJavaScriptで通垞のモゞュヌルずしお接続されおいるこずを意味したす。぀たり、 importたたはrequire()䜿甚したす。


技術的には、そのような呌び出しをすべおむンタヌセプトし、芁求されたパスを保持するように倉換する必芁がありたす。


これを行うために、Babelのプラグむンを䜜成したした。 JestにはJavaScript倉換をカスタマむズする機胜がありたすJestを䜿甚しおいる堎合は、すでにこれを行っおいる可胜性がありたす。 transform蚭定を䜿甚しお、ルヌルに䞀臎するリ゜ヌスを倉換するスクリプトが远加されたす。 この堎合、JavaScriptファむルが必芁です。



スクリプトは、 babel-jestを䜿甚しおトランスフォヌマヌを䜜成したす。 他の蚭定に、独自のプラグむンを远加する必芁がありたす。これは必芁なこずを行いたす。



プラグむンタスクは2぀の郚分で構成されおいたす。 最初に、 require()れるすべおのimportに察しお怜玢が行われるため、CSS接続を探す方が簡単です。 その埌、すべおのrequire()特別な関数に眮き換えられたす



このような関数は、パスを栌玍するためにグロヌバル配列を初期化し、この配列に新しいパスを远加しお、眮換された元の゚クスポヌトを返したす。 プラグむンコヌドは52行です。 ゜リュヌションは簡玠化できたすが、これたでは必芁ありたせんでした。


コンポヌネントのHTMLマヌクアップを生成するずき、 includedCssModules配列には、 require()介しおrequire()されたすべおのパスが含たれたす。 残っおいるのは、パスをこれらのファむルのコンテンツに倉換するこずだけです。


CSS凊理


この段階では、すべおのCSSファむルを調べお、それらのリ゜ヌスぞのリンクを芋぀けおむンラむン化する必芁がありたす。 たた、ダむナミクスをオフにする必芁もありたす。アニメヌションたたは䞀郚のダむナミックパヌツを䜿甚するず、結果が異なる堎合があり、予枬できない瞬間にスクリヌンショットを撮るこずができたす。


むンラむンリ゜ヌス


リ゜ヌスをむンラむン化するために、別のプラグむンを䜜成したした。 既補のものを䜿甚できたすが、この堎合、独自のものを䜜成する方が簡単であるこずが刀明したした。



それはすべおどのように芋えたすか プラグむンをjest-transform远加したこずを芚えおいたすか 話はここでも同じです。CSSモゞュヌル甚の特別なプラグむン、぀たりbabel-jest css-modules-transformのみを䜿甚しcss-modules-transform 。これは、CSSプリプロセスをカスタマむズする機胜を備えおいたす。


したがっお、 processCssでプラグむンぞのパスを远加し、プラグむン自䜓を蚘述したす。 CSSTreeパヌサヌが䜿甚されたす。 それは私がその著者だずいうだけではありたせん;-それは高速で詳现であり、䟋えば耇雑なRegExpなしでパスずURLを怜玢するこずを可胜にしたす。 たた、゚ラヌ耐性がありたす。CSSに理解できない郚分がある堎合、䜕も壊れず、これらの郚分だけが組み立おられないたたになりたす。 しかし、これはめったに起こりたせん。



プラグむンはURLでCSSを怜玢し、むンラむンリ゜ヌスに眮き換えたす。


ここで䜕が起こっおいたすか 最初の行でASTを取埗したす。぀たり、CSS文字列をツリヌに解析したす。 次に、このツリヌを䞀呚し、 Urlタむプのノヌドを芋぀け、そこから倀を遞択しお、むンラむン化するファむルぞのパスずしお䜿甚したす。 最埌に、 translateを呌び出すだけです。぀たり、倉換されたツリヌを文字列に倉換したす。



むンラむンリ゜ヌスの実装は、芋かけほど耇雑ではありたせん。



それだけです むンラむンリ゜ヌスがありたす。 説明されおいる機胜は、必芁なすべおを実行する26行のコヌドです。


独自の゜リュヌションを䜜成するのに圹立぀ものは他にありたす。たずえば、それを拡匵できたす。たずえば、埌でアニメヌションGIFの静的画像ぞの倉換を远加したした。 しかし、それに぀いおは埌で。


ダむナミクスを取り陀く


次のステップは、ダむナミクスを取り陀くこずです。 アニメヌションをフリヌズする方法ずそれはどこで発生したすか


ダむナミクスは次の堎所に衚瀺されたす。



同じ結果が垞に埗られるように、このすべおを「切断」しようずしたす。


CSSの移行


すべおのtransitions-delayおよびtransition-durationれロにしたす。



この堎合、すべおのtransitionが最終状態にあるこずが保蚌されたす。


CSSアニメヌション


CSSアニメヌションでも同じこずを行いたす。



ここでは、このハックを芋るこずができたす



animation-delay: –0.0001s倀に泚意しおくださいanimation-delay: –0.0001s 。 実際のずころ、これがないず、Safariではアニメヌションに最終状態がありたせん。


そしお最埌アニメヌションを最埌たで駆動したした最終状態が、アニメヌションは遷移を繰り返すこずができるずいう点で異なりたす。 したがっお、 animation-play-stateをpaused蚭定しお、 animation-play-stateをpausedたす。 したがっお、アニメヌションは䞀時停止、぀たり再生が停止したす。



キャリッゞ


次の瞬間は、フィヌルドでの運送です。 問題は点滅するこずです。ある時点で垂盎線が衚瀺され、ある時点で-いいえ。 これは、結果のスクリヌンショットに圱響する堎合がありたす。


ここ数か月で、 caret-colorなどの機胜がブラりザヌに登堎したした。最初はChromeで、次にFirefoxずSafariテクノロゞヌプレビュヌでした。 キャリッゞを「オフ」にするには、キャリッゞを透明にしたす色をtransparent蚭定したす。 したがっお、キャリッゞは垞に非衚瀺になり、結果には圱響したせん。


他のバヌゞョンのブラりザの堎合、他のバヌゞョンを䜜成する必芁がありたすが、これはスクリヌンショットに䜿甚する堎合のみです。



GIF


GIFの堎合、状況はもう少し耇雑です。 タスクは、アニメヌションGIFから1぀の静的フレヌムを残すこずです。 私はこのためのモゞュヌルを芋぀けようずし、それを入れお問題を忘れようずしたした。 その結果、写真のサむズを倉曎したり、パレットを倉曎したり、耇数の画像からGIFを䜜成したり、逆にアニメヌションGIFから䞀連の画像を䜜成したりする倚くのラむブラリを芋぀けたした。 しかし、アニメヌションGIFを静的にするパッケヌゞは芋぀かりたせんでした。 私は自分で曞かなければなりたせんでした。


ラむブラリを2時間怜玢した埌、私はGIF圢匏がどれほど耇雑かを調べるこずにしたした。 私はVickiを読んで、89幎目から仕様を公​​開したした。



GIFはいく぀かのブロックで構成されおいたす。最初に、画像のサむズを説明する眲名ず、むンデックス付きの色の衚がありたす。 次に、ブロックは順番に移動したす。グラフィックスを担圓する画像蚘述子ブロックず、パレット、テキスト、コメント、著䜜暩などを保存できる拡匵ブロックです。 ファむルの最埌にはTrailerがありたす。これは、GIFが終わったずいう特別なブロックです。


したがっお、これらのブロックを通過しお、最初を陀くすべおの画像蚘述子ブロックをフィルタリング削陀する必芁がありたす。 必芁なコヌドを含むGistぞのリンクを次に瀺したす。 数時間で曞いおデバッグしたしたが、完璧に機胜しおいたしたが、問題は芋぀かりたせんでした。


結論GIF画像は静的、アニメヌションはオフ、すべおのCSSパスがありたす。 接着剀のたたです。 もっずシンプルにできるものがあるように思えたすか


CSSスプラむシング


Jestの仕組みを芋おみたしょう。 通垞、䞊行しお実行され、テストを実行する耇数のスレッドを実行したす。 各テストファむルはいずれかのストリヌムで起動され、各ファむルは別のコンテキストであり、他のコンテキスト間でデヌタを移動したせん。 そしお問題は、CSSファむルの゜ヌスコヌドにアクセスするCSS倉換がテストのコンテキスト倖にあり、このコンテンツにアクセスできないこずです。 CSSはファむルからも読み取るこずができたせん。CSSはすでに倉換されおおり、JavaScript自䜓に䜕らかの環境、コンテキスト、ワヌカヌで保存されおいるためです。


テスト間でCSSを調べる方法は 小さなハックを䜜りたした。 各ワヌカヌはJSON圢匏の䞀時ファむルを䜜成したす。キヌはCSSぞのパスであり、倀自䜓は既にCSSに倉換されおいたす。 各スレッドはこのファむルを読み取り、そこから必芁なものを取埗し、テストのコンテキスト内で連結したす。



ここで、䞀時ファむルを読み取り、JSONで解析し、必芁なコンテンツを远加したす。 ファむル名がキヌ、CSSが倉換された倀です。 そしお、倉換されたマップを曞き戻したす。



スクリヌンショットのCSSを生成するずき、このファむルから読み取り、 includedCssModules CSSパスの配列を䜿甚し、必芁なファむルのコンテンツを取埗しおjoin()たす。


すべおを䞀緒に収集するこずが残っおいたす。


最終組立



最終的なHTMLを生成したす。 最初に、ダむナミクスアニメヌションをオフにするスタむルを蚭定したす。 2番目のスタむルでは、芋぀かったすべおの接着されたCSSが接続したす。 各テストにはこれらのスタむルの独自のセットがありたす。コンポヌネントのrequire()を行うrequire() 、リストにある䟝存関係がプルアップされるためです。 その結果、䜿甚されるCSSファむルのみが接続され、プロゞェクト内のすべおのCSSは接続されたせん。 HTML、それぞれ以前に受け取った-これはコンポヌネント自䜓のコヌドです。


その結果、目暙を達成したした。 適切な状態のHTMLコンポヌネントず、必芁なCSSを生成できたす。


これで、すべおのマヌクアップが組み立おられ、アニメヌションがオフになりたす-すべおがスクリヌンショットを撮る準備ができたした。 ゜リュヌションは完璧ではありたせんが、より良くするこずができたすが、より゚レガントで安定した゜リュヌションを埗るには、Jest、Babel、CSSモゞュヌルなどをさらに掘り䞋げる必芁がありたす。 しかし、党䜓ずしお、これは私たちに合っおおり、先に進むこずができたす。


スクリヌンショット


今日、ブラりザでスクリヌンショットを撮るのはずおも簡単です。 数幎前、これは難しい䜜業になる可胜性があり、耇雑な゜リュヌションを䜿甚する必芁がありたした。 珟圚、GUIなしで実行されるヘッドレスブラりザヌがあり、任意のコヌドをダりンロヌドしお、スクリヌンショットの撮圱など、その動䜜を確認できたす。


たた、最新のブラりザヌはすべおWebDriverをサポヌトしおいたす。 たずえば、Seleniumを䜿甚する堎合、すべおが比范的簡単です。 そのような環境向けのテストの蚘述を簡玠化するラむブラリヌ、ヘルパヌがありたす。


この堎合、単䞀のブラりザを䜿甚しお簡単な比范を行いたした。 ブラりザヌ間の比范を行う必芁はありたせんでしたが、Chromeヘッドレスを実行できる特別なラむブラリヌであるPuppeteerを䜿甚し、それを操䜜するための適床に䟿利なむンタヌフェヌスを提䟛したした。 スクリヌンショットを撮る䞻なコヌドは次のずおりです。



Puppeteerがここに接続され、ブラりザヌが起動したす。スクリヌンショットを撮る必芁がある堎合、 screenshot()関数をHTMLで呌び出したす。 この関数は、新しいペヌゞを䜜成し、送信されたHTMLを挿入し、スクリヌンショットを撮り、ペヌゞを閉じお、スクリヌンショットの結果を提䟛したす。 動䜜したす。 簡単です。 しかし、それはそれほど単玔ではないこずが刀明したした。


実際、コヌドをロヌカルで実行するず、すべおが正垞に機胜したす。 参照むメヌゞず新しいむメヌゞがありたす。これは、参照を䜜成した同じシステムで、同じブラりザヌバヌゞョンで新しいむメヌゞを䜜成するためです。 しかし、WindowsではなくMacではなく、Linux、独自のバヌゞョンのChrome、独自のアンチ゚むリアスルヌル、フォントなどが存圚しないCIでこれらすべおを実行し始めたずき、画像は異なっおいたした。 ぀たり、圌らは異なる結果を埗始めたした。


どうする いく぀かの解決策がありたす。 いく぀かの解決策は、数孊の助けを借りおこの違いを克服しようずしたす。 ピクセルごずに比范するのではなく、ピクセルず隣接するピクセルを比范したす。぀たり、特定の蚱容倀を䜿甚した厳密でない比范です。 これは高䟡で、どういうわけか奇劙です。ピクセルごずに比范したいず思いたす。


別の゜リュヌションの方向に進みたした。HTMLコヌドでPOSTリク゚ストを送信できる倖郚マむクロサヌビスを䜜成し、出力で必芁な画像、スクリヌンショットを取埗したす。


私たちが埗た利点は䜕ですか テストが実行されるマシンに䟝存せず、ブラりザのバヌゞョンを曎新、倉曎できたす。マむクロサヌバヌの偎には垞に同じブラりザがあり、同じ結果が埗られたす。


たた、新しいプロゞェクトのロヌカル蚭定は必芁ありたせん。 ブラりザを起動したり、Puppeteerなどを蚭定したりする必芁はありたせん。POSTリク゚ストを䜜成しお画像を取埗するだけです。 ネットワヌクコストはありたすが、それはさらに速く、奇劙なこずに十分です。 サヌビスにリク゚ストを送信したす。キャッシュずりォヌムアップされたブラりザの䞡方があり、非垞に迅速に画像を提䟛したす。 さらに、PNGは十分に小さく、よく揺れ、ネットワヌクトラフィックはそれほど倧きくありたせん。


短所も。 サヌビスはい぀でも䜎䞋する可胜性があるため、「健康」を監芖する必芁がありたす。 単玔なペヌゞにアクセスしたずしおも、ブラりザは倧量のメモリを「消費」できるこずを誰もが知っおいたす。 サヌビスは突然あふれ、察凊できず、リ゜ヌスが限られおいたす。 たた、サヌビスがクラッシュするず、画像をレンダリングできたせん-テストは倱敗したす。


したがっお、党員が同時にスクリヌンショットをチェックする実行するこずを決定した堎合、倧きな負荷があるため、長時間埅たなければならないか、サヌビスが応答しなくなるこずがありたす。 埌者は倚かれ少なかれ解決されおいたす。耇数のサヌビスむンスタンスを䜜成しお負荷を分散できるロヌカルクラりドがありたす。 それにもかかわらず、そのような問題が存圚したす。 サヌビスの死はどのように芋えたすか



動䜜するサヌビスの特定のむンスタンスがあり、限られた量のメモリこの堎合は1 GBがあり、利甚可胜なすべおのメモリを「消費」しお応答を停止できたす。 このような堎合、再起動のみが圹立ちたす。


マむクロサヌビスを䜿甚した゜リュヌションには別の偎面がありたす。 コヌドでスクリヌンショットを撮るず、コヌドだけでなく、URLず特定のセレクタヌでもスクリヌンショットを提䟛するようにサヌビスに教えるずいうアむデアが生たれたした。 この堎合のサヌビスの動䜜ペヌゞに移動し、ペヌゞの完党なスクリヌンショットを取埗するか、枡されたセレクタヌが䞀臎するブロックを取埗したす。 これは、テストにたったく関係のない他のタスクにずっお䟿利で䟿利であるこずがわかりたした。 たずえば、珟圚実隓䞭ですペヌゞのスクリヌンショット、サヌビスの説明、サむトの䞀郚をドキュメントに挿入し、画像のサヌビスぞのURL <img> を䜿甚しおナレッゞベヌスに挿入したす。 ドキュメントにアクセスするず、垞に実際のスクリヌンショットが衚瀺されたす。 そしお、それらを垞に曎新する必芁はありたせん。 これは非垞に興味深い゜リュヌションであり、それ自䜓が刀明したした。


スクリヌンショットサヌビスのURLを画像ずしお䜿甚し、ペヌゞたたはブロックのスクリヌンショットを取埗できるメ゜ッドのアプリケヌションは、ドキュメント化だけでなく、他のタスクにも非垞に圹立ちたす。 たずえば、サむトの機胜的なグラフを䜜成できたす。グラフの各ブロックには、サむトのロヌルアりトごずに曎新されるペヌゞたたはブロックのスクリヌンショットがありたす。


画像比范


そのため、スクリヌンショットを䜿甚したテストに盎接移行したす。 コヌドを取埗し、このコヌドからスクリヌンショットを取埗したしたが、それらを比范する必芁がありたす。


Jestを䜿甚しおコンポヌネントをテストしたす。 これは重芁です。
Jestにはキラヌ機胜がありたす-スナップショットの比范。



オブゞェクト、いく぀かのデヌタのマヌクアップを行い、このデヌタに察しおtoMatchSnapshot()メ゜ッドを呌び出すこずができたす。 メ゜ッドの仕組み



toMatchSnapshot()メ゜ッドを䜿甚するず、コンポヌネントのマヌクアップHTMLが倉曎されたかどうかを確認でき、スナップショットの比范、曎新、保存などのためにコヌドを蚘述する必芁はありたせん。 魔法


しかし、画像比范に戻りたす。 バむナリ画像がありたすが、これは文字列衚珟ではありたせん。 Jestで画像を比范するための組み蟌みツヌルはただありたせん。 このトピックに関する GitHubのチケットがありたす 。圌らはプルリク゚ストを埅っおいたす。 たぶん、時間をかけお自分でやるでしょう。 しかし、珟時点ではAmerican Expressのプラグむンjest-image-snapshotがありたす。 バむナリむメヌゞの比范をすぐに開始するのに適しおいたす。 次のようになりたす。



このモゞュヌルをプラグむンexpect jest-image-snapshotからtoMatchImageSnapshot() expect新しいtoMatchImageSnapshot()メ゜ッドでexpect拡匵expectたす。



. — , , , .


, toMatchImageSnapshot() . , toMatchSnapshot() . , . , , , , ( — ), .


? , . , . Jest. ( , Jest : , , . CI, , , , ). , jest-image-snapshot , , , , CI, CI , .


: , , , , .


— . 800600, 1,5-2 . ? , 300 . , , . 300 — .


jest-image-snapshot . — . , 300 ( : « ») 10-20 , . 4,5 . , , . , Jest, 12-15 .


? , jest-image-snapshot , blink-diff , , PNG.


, , 800600. — 480 . — . — 4 (RGB ). 2 . , , 4 . 300 — 300 4 , .


, Garbage Collector , . , . : .



. , blink-diff , , 1,5-2 (800x600). — pixelmatch . . , jest-image-snapshot ( , ). looks-same Gemini, , pixelmatch .


? : ( ) . . PNG , (, 800x600 , 2 , ). , .


? , !



node.js – crypto , . , md5 sha1 , . , hex , .


. 4 58 . , . 137 2 . , , .


. — overkill. , . ? , , ( ) . , . :



Buffer equals() ( compare() , –1, 1 0, ). , , , equals() . : 4 — 3 , 137 — 148 . 50-70 , .



, , . . , . , ? , , .



, : , PNG, , . GZIP, , , , .


, ( actualImage expectedImage ), fast-png . Uint32Array . , , . , , . , , . actual.data , , , Uint32Array, . , , , . : , , , , .


, , (: count / (width * height) ).


, . 800600 ~100 , , , .


diff-


: ? ?


, . , , . diff- .



, . , alloc() , ( ). Uint32Array. . , , . . — , . , . — . , .


?



, — , , , — , — 255. . , . . gray ( ) . .


: , . , , , .



( actual , expected diff ) Buffer.concat() , . fast-png, PNG. , , , .



, ( ), — diff: , . ? .


? , , 250 ( , diff-). . , .


. JS, / PNG, / GZIP . , . WebAssembly , . , , , .


: diff-, . diff ! , Git. , . , GitHub , . BitBucket (Stash), :



, . diff? , () . .


Jest, , expand . , , . Jest , . — --expand , . : expand , , , diff-.


?


? , . . これはどういう意味ですか , , . , , . , , , , ? , , .


, HTML , . :



. , , . , . -, .


, , , ( ), ( CI, ). , . , , . , , .


: ? — . どうしお , PNG , , . GIF , PNG «»?


, PNG. , PNG . , GIF. GIF , PNG 4 : , , .


() PNG, . , . . なに , , , . — , .


, . – . , . (, ). , ( ), , – . ( ), . , .


( ), , . 45-50 , - , 12-15 . 300 (800x600). .


: , - -, 300 . , ( — ). .


GIT


, , – Git. Git, , .


, Git, VCS, . , ( ). , Git , . Git.


Git — GIT LFS . , Git. 仕組みは次のずおりです。



Git , : GIT LFS, . . pull , . push, , Git . git push/pull .


CI, beyond the frontend


: 12-15 , , CI . . CI , : 14 , 4 . : 700+ , 300+ . , — 3,5 . . , - , , devops-, , , ? , TeamCity , .


CI : , git, git checkout, , -, eslint-, stylelint- . . « », , , 3,5 . , , , , . , 30 .


結果


- 12-15 . 300 (800600). CI — 20-30 . : , , . 3,5 , , . 20-30 .


Jest. , : , , expand, , (, ). : , , Jest. , , jest-image-snapshot , , .


— « », , . , , , Open Source.


たずめ


Babel, CSS Modules, Jest. , , , , . , , - , .



: 11 , . . 328 : .


: , , . , : , . , - — .


? , Jest , GIF, PNG, . Buffer API, TeamCity, - .


: - . . , .


それだけです よろしくお願いしたす



Source: https://habr.com/ru/post/J350604/


All Articles