JestずPuppeteerWeb UIテストの自動化

この蚘事はむタリアのプログラマヌValentino Gagliardiによっお曞かれたした。 圌は、Puppeteerのリリヌス埌すぐに、このラむブラリずJestを䜿甚しおWebむンタヌフェむスのテストを自動化するこずに興味を持぀ようになったず蚀いたす。 その埌、圌は実隓を始めたした。



ここでは、Webフォヌムをテストする䟋によっお、PuppeteerずJestで䜜業する基本に぀いお説明したす。 たた、ナヌザヌむンタヌフェヌスを䜿甚しお、たたは䜿甚せずにChromiumを䜿甚する機胜、およびWebペヌゞのテストず䜜業環境の敎理のさたざたな偎面に関するいく぀かの有甚なこずに぀いおも説明したす。 Valentinoは、Puppeteerは比范的新しいツヌルであり、APIは倉曎される可胜性が高いものの、Web開発者の歊噚庫で正圓な䜍眮を占める可胜性があるず考えおいたす。

問題のテストのいく぀かの機胜に぀いお


最近、むンタヌフェむステストを曞いたのず同時に、 Kent S. Doddsがdata-*属性を䜿甚しおテストの安定性を改善するずいう蚘事に出䌚いたした。 これは、䞀蚀で蚀えば、ほずんどすべおのHTML芁玠に蚭定できるカスタム属性です。 JavaScriptプログラムずのデヌタ亀換を敎理するずきに特に圹立ちたす。

ケントの資料は非垞に時間通りに来たした。それは、次の構造を䜿甚したためです。

 await page.waitForSelector("#contact-form"); await page.click("#name"); await page.type("#name", user.name); 

ここでは、䞻にサヌバヌプログラミングを扱っおいるこずに泚意しおください。 そしお、私はただテストでのdata-*の䜿甚をキャンペヌンしおいたせんが、それにもかかわらず、これは玠晎らしいアプロヌチであるこずを認めなければなりたせん。 これは特に倧芏暡なアプリケヌションで圹立ちたすが、ここでは、単玔な䟋では、芁玠にアクセスする叀兞的な方法を䜿甚したす。

フィヌドバックフォヌムのテスト


したがっお、私たちの目暙は、私が取り組んでいるこのペヌゞのフィヌドバックフォヌムをテストするこずです。 フォヌムは次のずおりです。


次の芁玠が含たれたす。


テスト䞭、フォヌムの状態を確認する必芁がありたす。぀たり、サむト蚪問者がフォヌムを䜿甚しお䌚瀟にリク゚ストを送信できるこずを確認する必芁がありたす。

プロゞェクトのセットアップ


始めるために、テストの自動化に䜿甚するツヌルを詳しく芋おみたしょう。


Jestは、Facebookが開発したテストフレヌムワヌクです。 Jestは、自動テスト甚のプラットフォヌムず、ステヌトメントを䜜成できるベヌスラむブラリExpectを提䟛したす。

PuppeteerはNode.jsのラむブラリで、ナヌザヌむンタヌフェむスなしでChromiumブラりザを制埡できたす。 このツヌルは非垞に新しいため、詊しおみお、特定のプロゞェクトで必芁かどうか、必芁に応じお既存の゚コシステムに統合する方法に぀いお考えおみたしょう。

Fakerは、ランダムデヌタを生成できるNode.jsのラむブラリです。 それらの䞭には、名前、電話番号、䜏所がありたす。 ちなみに、これはPHPのFakerのようなものです。

実隓するプロゞェクトが既にある堎合は、次のコマンドで必芁なラむブラリをむンストヌルできたす。

 npm i jest puppeteer faker --save-dev 

Puppeteerのむンストヌルには時間がかかりたす。これは、ずりわけ、ラむブラリのむンストヌル䞭にChromiumブラりザヌもむンストヌルされるためです。

Chromiumは、Google Chromeの基盀であるオヌプン゜ヌスのりェブブラりザです。 ChromiumずChromeの機胜はほが同じですが、䞻な違いはラむセンス機胜にありたす。

必芁なものがすべおむンストヌルされたら、 package.json Jestを構成したす。 testコマンドは、Jest実行可胜ファむルを指す必芁がありたす。

 "scripts": { "test": "jest" } 

さらに、Jestでは、この構造を䜿甚するこずを奜みたす。

 import puppeteer from "puppeteer"; 

そこで、JestにBabelが必芁です。

 npm i babel-core babel-jest babel-preset-env --save-dev 

Babelのむンストヌル埌、プロゞェクトフォルダヌに次の内容の.babelrcファむルを䜜成したす。

 { "presets": ["env"] } 

これで準備が完了し、テストの䜜成を開始できたす。

テストを曞く


プロゞェクトフォルダに新しいディレクトリを䜜成したす。 testたたはspecず呌ぶこずができたす。 次に、このディレクトリでform.spec.jsファむルを䜜成したす。

ここで、むンポヌトセクションから始めお、テストコヌドを郚分的に怜蚎するこずを提案したす。 以䞋に、このすべおのコヌド党䜓を瀺したす。

たず、FakerずPuppeteerをむンポヌトしたす。

 import faker from "faker"; import puppeteer from "puppeteer"; 

次に、フォヌムのURLを蚭定したす。 おそらく、本番サむトに接続する代わりに、開発䞭のロヌカルで䜿甚可胜なフォヌムのバヌゞョンをテストするこずにしたす。

 const APP = "https://www.change-this-to-your-website.com/contact-form.html" 

次に、Fakerを䜿甚しお、ダミヌナヌザヌを䜜成したす。

 const lead = { name: faker.name.firstName(), email: faker.internet.email(), phone: faker.phone.phoneNumber(), message: faker.random.words() }; 

次に、Puppeteerで䜜業するために必芁ないく぀かの倉数を定矩したす。

 let page; let browser; const width = 1920; const height = 1080; 

次に、Puppeteerの動䜜を蚭定したす。

 beforeAll(async () => { browser = await puppeteer.launch({   headless: false,   slowMo: 80,   args: [`--window-size=${width},${height}`] }); page = await browser.newPage(); await page.setViewport({ width, height }); }); afterAll(() => { browser.close(); }); 

ここでは、Jest beforeAllおよびafterAllを䜿甚しafterAll 。 テストを実行する前に、Puppeteerを䜿甚しおブラりザヌを起動する必芁があるため、最初のものが必芁です。 ブラりザを起動した埌、新しいペヌゞを開くこずができたす。 テストが完了したら、ブラりザを閉じる必芁がありたす。 これは、 browser.close()コマンドを䜿甚しおafterAllメ゜ッドで実行されたす。

afterAllずafterAllだけに限定されないこずに泚意しおください。 Jestのその他の機胜に぀いおは、このラむブラリのドキュメントをご芧ください。 いずれの堎合でも、個々のテストごずにブラりザヌを開いたり閉じたりするのではなく、1぀のブラりザヌむンスタンスを䜿甚しおテストスむヌト党䜓を実行するこずをお勧めしたす。

ここで、䞊蚘のコヌドスニペットに぀いおいく぀かコメントしたいず思いたす。 ぀たり、 headless: falseパラメヌタヌを䜿甚しおブラりザヌをりィンドりモヌドで起動するこずに泚意しおください。 この堎合、これは、ビデオの画面で䜕が起こっおいるかを蚘録し、テストプロセスを衚瀺できるようにするために行われたす。 説明したツヌルを䜿甚しお実際のテストを実行するず、通垞、䜕が起こっおいるのかを芳察する必芁はありたせん。 むンタヌフェヌスなしでブラりザを起動するには、 launch()メ゜ッドを呌び出すずきに䜿甚したパラメヌタを削陀するだけです。

同じこずはsetViewPort()コマンドにもsetViewPort()たすが、このコマンドも削陀できたす。 たたは、さらに良いこずに、2぀の異なるテスト環境をセットアップできたす。 1぀は芖芚的なデバッグに䜿甚されたすこれに぀いおは以䞋で説明したす、2぀目はナヌザヌむンタヌフェむスなしでブラりザヌを操䜜するためです。

次に、テストコヌドを蚘述したす。

 describe("Contact form", () => { test("lead can submit a contact request", async () => {   await page.waitForSelector("[data-test=contact-form]");   await page.click("input[name=name]");   await page.type("input[name=name]", lead.name);   await page.click("input[name=email]");   await page.type("input[name=email]", lead.email);   await page.click("input[name=tel]");   await page.type("input[name=tel]", lead.phone);   await page.click("textarea[name=message]");   await page.type("textarea[name=message]", lead.message);   await page.click("input[type=checkbox]");   await page.click("button[type=submit]");   await page.waitForSelector(".modal"); }, 16000); }); 

Jestでasync / awaitコンストラクトを䜿甚する可胜性に泚意しおください。 ここでは、Node.jsの最新バヌゞョンの1぀を䜿甚しおテストが実行されるこずを前提ずしおいたす。

これらのテストを怜蚎しおください。 ゜フトりェア制埡ブラりザが実行する手順は次のずおりです。


Jasmine test()関数は、2番目のパラメヌタヌずしお、タむムアりト16000が枡されたこずに泚意しおください。 これにより、ブラりザがペヌゞでどのように機胜するかを正確に監芖できたす。

画面に衚瀺されるブラりザを䜿甚しおテストし、タむムアりトを蚭定しないず、次の゚ラヌが発生したす。

 Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL 

むンタヌフェむスなしでブラりザを起動しおテストを実行する堎合、タむムアりトを削陀できたす。

これですべおの準備が敎い、次のコマンドでテストを開始できたす。

 npm test 

その埌、ブラりザを監芖するだけで、ブラりザ自䜓がペヌゞで動䜜したす。


興味がある堎合、この画面のビデオは、 recordmydesktopず次のコマンドを䜿甚しおFedoraで蚘録されたした。

 recordmydesktop --width 1024 --height 768 -x 450 -y 130 --no-sound 

ただし、それだけではありたせん。

他のむンタヌフェヌス芁玠のテスト


フォヌムを理解したので、他のペヌゞ芁玠をテストできたす。

<title></title>しお、状況を確認したしょう。 ご存じのずおり、意味のあるペヌゞタむトルが必芁です。

 describe("Testing the frontend", () => { test("assert that <title> is correct", async () => {   const title = await page.title();   expect(title).toBe(     "Gestione Server Dedicati | Full Managed | Assistenza Sistemistica"   ); }); //      }); 

ナビゲヌションバヌはどうですか 圌女はペヌゞに存圚する必芁がありたす。 この堎合、JestずPuppeteerに確認しおください。

 // test("assert that a div named navbar exists", async () => {   const navbar = await page.$eval(".navbar", el => (el ? true : false));   expect(navbar).toBe(true); }); // 

特定の芁玠に含たれるべきテキストが含たれおいるかどうかも確認できたす。

 // test("assert that main title contains the correct text", async () => {   const mainTitleText = await page.$eval("[data-test=main-title]", el => el.textContent);   expect(mainTitleText).toEqual("GESTIONE SERVER, Full Managed"); }); // 

怜玢゚ンゞン最適化のためにペヌゞをテストするのはどうですか たずえば、 正芏リンクを確認したす。

 describe("SEO", () => { test("canonical must be present", async () => {   await page.goto(`${APP}`);   const canonical = await page.$eval("link[rel=canonical]", el => el.href);   expect(canonical).toEqual("https://www.servermanaged.it/"); }); }); 

同じ原則により、他の倚くのテストを䜜成できたす。

その結果、すべおのテストが正垞に完了したした。これは、緑色の心地よいメッセヌゞで刀断できたす。


芖芚的なデバッグ


Puppeteerを䜿甚するず、ナヌザヌむンタヌフェヌスを䜿甚しお、たたは䜿甚せずに起動したChromiumで䜜業を自動化できるず既に述べたした。 次のコヌドスニペットを思い出しおください。

 beforeAll(async () => { browser = await puppeteer.launch({     //       headless: false,     slowMo: 80,     args: [`--window-size=1920,1080`]   }); page = await browser.newPage(); /// }); 

さらに、グラフィカルむンタヌフェむスでブラりザヌを起動するずきは、Jasmineタむムアりトパラメヌタヌを枡す必芁があるこずに泚意する必芁がありたす。 そうしないず、テストがすぐに予期せず終了したす。 タむムアりトは、 test()メ゜ッドの2番目の匕数です。

 describe("Contact form", () => { test(   "lead can submit a contact request",   async () => {   /////    },   16000 // <<< - Jasmine ); }); 

自動テストでは、ブラりザりィンドりを衚瀺する必芁はありたせん。そうしないず、少なくずもいく぀かの深刻なテストスむヌトの実行に時間がかかりたす。 ただし、コヌドから制埡されたブラりザヌで䜕が起こるかを芋るず䟿利な堎合がありたす。 むンタヌフェむスのあるブラりザずないブラりザを䜿甚しお、テストを簡単に切り替える方法は

この問題は、補助関数を䜜成するこずで解決できたす。 これを実行しお、 testingInit.jsファむルに入れたしょう。

 export const isDebugging = () => { let debugging_mode = {   puppeteer: {     headless: false,     slowMo: 80,     args: [`--window-size=1920,1080`]   },   jasmine: 16000 }; return process.env.NODE_ENV === "debug" ? debugging_mode : false; }; 

次に、テストコヌドを䜿甚しおファむルからアクセスし、最初にむンポヌトしおから、ブラりザの起動時に䜿甚したす。

 /// import { isDebugging } from "./testingInit.js"; /// beforeAll(async () => { browser = await puppeteer.launch(isDebugging().puppeteer)); // <<<   page = await browser.newPage(); /// }); 

タむムアりトを蚭定するずきに同じ関数が圹立ちたす。

 describe("Contact form", () => { test(   "lead can submit a contact request",   async () => {   /////    }, isDebugging().jasmine // <<< - Jasmine ); }); 

その埌、むンタヌフェヌスのないブラりザヌでテストを開始するには、次のコマンドを実行するだけで十分です。

 npm test 

ビゞュアルモヌドでテストを実行するには、次を実行する必芁がありたす。

 NODE_ENV=debug npm test 

たずめ


ただ、PuppeteerたたはそのAPIを䜿甚するこずに䞍安があるかもしれたせん。 分かりたした。 そしお、このプロゞェクトの目新しさがその実甚的な適甚性に疑問を抱いおいるなら、たずえばサむプレスをご芧ください 。 ただし、Puppeteerは開発者に真に無限の可胜性を䞎えたす。 このラむブラリに基づいおテストフレヌムワヌクが䜜成されおいたす。 もちろん、時間の経過ずずもに、Puppeteer APIは倉曎される可胜性がありたすが、ここで説明した基本的なこずはどこにも行き圓たりたせん。 さらに、PuppeteerはJestずも盞性が良いこずに泚意しおください。 さらに、倚くはPuppeteer E2Eテストを実行したす 。

芪愛なる読者 Webむンタヌフェヌスのテストをどのように自動化したすか

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


All Articles