[Puppeteer]Puppeteer+Mocha+Chai實現端到端測試

項目

將單元測試框架mocha,斷言chaipuppeteer結合起來做端到端測試:

  • 將打開百度首頁
  • 搜索Puppeteer,確定有搜索內容
  • 清空輸入,返回百度首頁

puppeteer實現自動化

  • 安裝puppeteer

    npm install puppeteer@2.1.1
    
  • 根據用戶操作,找標籤選擇器
    F12->點擊箭頭->更具頁面找標籤
    在這裏插入圖片描述

  • 找到標籤後,先驗證下,頁面是否存在這個標籤

document.querySelector()
document.querySelectorAll()

在這裏插入圖片描述

  • 輸入node 1.js 執行
    設定了headless: true,所以不會打開瀏覽器,直接運行出結果
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: true,
        devtools: false,
        timeout: 20000,
    });

    const page = await browser.newPage();
    await page.goto('http://www.baidu.com/');
    const title = await page.title()
    console.log(title);
    await page.type('input[id="kw"]', 'puppeteer');
    await page.click('input[id="su"]');
    await page.waitFor(2000);
    await page.waitForSelector('div[class="result c-container "]');
    const links = await page.evaluate(() => {
        return Array.from(document.querySelectorAll('div[class="result c-container "]'));
    });
    console.log(links.length);
    await page.waitFor(2000);
    await page.$eval('input[id="kw"]', input => input.value = '');
    await page.click('input[id="su"]');
    await page.waitFor(2000);


})();

知識點補充

  • 等待某個 DOM 節點
    在對頁面進行操作前,必須等DOM 加載完成才能操作,比如,你要點擊圖片,但是圖片沒加載出來。下面這個是等待搜索結果節點節點出現:

    await page.waitForSelector('div[class="result c-container ');
    
  • 如果加載時間不夠,需要用時間間隔

    await page.waitFor(500);
    
  • 獲取節點集合
    下面是獲取搜索結果列表,兩種寫法都可以

     const links = await page.evaluate(() => {
        return Array.from(document.querySelectorAll('div[class="result c-container "]'));
    });;
    const links = await page.$$eval('div[class="result c-container ', els => Array.from(els).map(el=> el));
    
  • 使用了eval,清空input框

await page.$eval('input[id="kw"]', input => input.value = '');

Mocha+Chai實現測試

將上面的代碼,加入 Mocha+Chai,進行測試

  • 安裝Mocha+Chai,看這
  • 代碼,注意運行的時候,使用的是mocha 2.js -t 30000
    const puppeteer = require('puppeteer');
    const { expect } = require('chai');
    
    describe('Baidu search', () => {
        let browser;
        let page
        before(async () => {
            browser = await puppeteer.launch();
            page = await browser.newPage();
            await page.goto('http://www.baidu.com/');
        });
    
        after(async () => {
            await browser.close();
        });
    
    
        it('page title', async () => {
            expect(await page.title()).to.eql('百度一下,你就知道');
        });
    
        it('get the list number of results', async () => {
            await page.type('input[id="kw"]', 'puppeteer');
            await page.click('input[id="su"]');
            await page.waitFor(2000);
            await page.waitForSelector('div[class="result c-container "]');
            const links = await page.evaluate(() => {
                return Array.from(document.querySelectorAll('div[class="result c-container "]'));
            });
            expect(links.length).to.be.greaterThan(0);
        });
    
        it('back to BaiDu page ', async () => {
            await page.waitFor(2000);
            await page.$eval('input[id="kw"]', input => input.value = '');
            await page.click('input[id="su"]');
            await page.waitFor(2000);
            expect(await page.title()).to.eql('百度一下,你就知道');
        });
    
    });
    

這份代碼實現了,驗證首頁是否打開,搜索是否有信息,搜索清空後,點擊提交,是否返回首頁。
browser和page定義在外面,這樣,其他函數可以使用到。

優化代碼

爲了增加代碼的可維護性,可理解性。我們一些操作封裝起來,使用的時候直接調用它。
執行的時候使用mocha 3.test.js -t 30000

  • 3.js
    這個裏面寫了獲取標題,搜索,獲取搜索條數,返回首頁幾個方法

    class BaiDu {
    
        constructor(page) {
            this.page = page;
        }
    
        async getTitle() {
            return this.page.title();
        }
    
        async search(word) {
            await this.page.type('input[id="kw"]', word);
            await this.page.click('input[id="su"]');
        }
    
        async getNumber(page) {
            await this.page.waitForSelector('div[class="result c-container "]');
            const links = await this.page.evaluate(() => {
                return Array.from(document.querySelectorAll('div[class="result c-container "]'));
            });
            return links.length;
        }
    
        async back() {
            await this.page.$eval('input[id="kw"]', input => input.value = '');
            await this.page.click('input[id="su"]');
            await this.page.waitFor(2000);
        }
    }
    
    module.exports = BaiDu;
    
  • 3.test.js
    引入BaiDu ,直接調用BaiDu的方法,獲取結果,進行驗證

    const puppeteer = require('puppeteer');
    const { expect } = require('chai');
    const BaiDu = require('./3.js');
    
    
    describe('Baidu search', () => {
    
        let browser;
        let page;
    
        before(async () => {
            browser = await puppeteer.launch();
            page = await browser.newPage();
            await page.goto('http://www.baidu.com/');
        });
    
        after(async () => {
            await browser.close();
        });
    
        it('page title', async () => {
            const baiDu = new BaiDu(page);
            expect(await baiDu.getTitle()).to.eql('百度一下,你就知道');
        });
    
        it('get the list number of results', async () => {
            const baiDu = new BaiDu(page);
            await baiDu.search('puppeteer');
            expect(await baiDu.getNumber()).to.be.greaterThan(0);
        });
    
        it('back to BaiDu page', async () => {
            const baiDu = new BaiDu(page);
            await baiDu.back();
            expect(await baiDu.getTitle()).to.eql('百度一下,你就知道');
        });
    
    });
    
  • 結果
    在這裏插入圖片描述

本節代碼

相關鏈接

3分鐘學會Mocha+Chai單元測試
3分鐘入門Puppeteer
Puppeteer實現自動網賺?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章