Web自動(dòng)化之Headless Chrome測(cè)試框架集成

使用Selenium操作headless chrome 推薦

簡(jiǎn)介

WebDriver是一個(gè)W3C標(biāo)準(zhǔn), 定義了一套檢查和控制用戶代理(比如瀏覽器)的遠(yuǎn)程控制接口,各大主流瀏覽器來實(shí)現(xiàn)這些接口以便調(diào)用控制接口來操作瀏覽器。

Selenium是一整套的Web自動(dòng)化測(cè)試解決方案罗售,配合WebDrive規(guī)范宠页,實(shí)現(xiàn)了對(duì)各種用戶代理的適配(比如瀏覽器,PhantomJS等)贾虽,通過操作瀏覽器的WebDriver接口來實(shí)現(xiàn)帶瀏覽器的Web自動(dòng)化杆怕。

使用selenium-webdriver

const webdriver = require('selenium-webdriver'),
    By = webdriver.By;

const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .build();


driver.get('https://www.baidu.com').then((args) => {
    // 獲取百度搜索按鈕的 文本
    driver.findElement(By.id('su')).then((element) => {
        return element.getAttribute('value')
    }).then((btnName) => {
        console.log(btnName)
    });

    // 獲取百度首頁 title
    driver.getTitle().then((title) => {
        console.log(title);
    });
});


driver.quit();

使用browserstack-webdriver

只是獲取driver的方式不一樣糠溜,其他調(diào)用完全一樣

const webdriver = require('browserstack-webdriver'),
    By = webdriver.By;

// Input capabilities
const capabilities = {
    'browserName' : 'firefox',
    'browserstack.user' : BROWSERSTACK_USERNAME,
    'browserstack.key' : BROWSERSTACK_KEY
}

const driver = new webdriver.Builder().
usingServer('http://hub.browserstack.com/wd/hub').
withCapabilities(capabilities).
build();


driver.get('https://www.baidu.com').then((args) => {
    // 獲取百度搜索按鈕的 文本
    driver.findElement(By.id('su')).then((element) => {
        return element.getAttribute('value')
    }).then((btnName) => {
        console.log(btnName)
    });

    // 獲取百度首頁 title
    driver.getTitle().then((title) => {
        console.log(title);
    });
});


driver.quit();

使用 chromedriver

chromedriver是一個(gè)編碼輔助笤虫,自動(dòng)配置環(huán)境變量旁瘫,不需要手動(dòng)下載和配置環(huán)境變量,通過安裝chromedriver同時(shí)在代碼中引入

require('chromedriver')
更換獲取源的URL(使用如下任意一種就行)
  • 安裝過程添加參數(shù)琼蚯,默認(rèn)下載地址為http://chromedriver.storage.googleapis.com

    npm install chromedriver --chromedriver_cdnurl=https://npm.taobao.org/mirrors/chromedriver
    
  • 添加如下內(nèi)容到.npmrc文件

chromedriver_cdnurl=https://npm.taobao.org/mirrors/chromedriver
  • 添加環(huán)境變量CHROMEDRIVER_CDNURL
CHROMEDRIVER_CDNURL=https://npm.taobao.org/mirrors/chromedriver npm install chromedriver
更換安裝的chromedriver文件路徑
  • 安裝過程使用配置參數(shù)
npm install chromedriver --chromedriver_filepath=/path/to/chromedriver_mac64.zip
  • 添加如下內(nèi)容到.npmrc文件
chromedriver_filepath=/path/to/chromedriver_mac64.zip
  • 添加環(huán)境變量
CHROMEDRIVER_FILEPATH=/path/to/chromedriver_mac64.zip

使用mocha + chai

簡(jiǎn)介

mocha是一個(gè)可以運(yùn)行在瀏覽器端和NodeJS環(huán)境的JavaScript測(cè)試框架酬凳,區(qū)別于類庫,框架定義好了流程凌停,并調(diào)用你的代碼粱年。

chai是一個(gè)斷言庫,判斷結(jié)果是否符合預(yù)期罚拟。

實(shí)例代碼

const chai = require('chai');

const chromeDriver = require('selenium-webdriver/chrome')

const webdriver = require('selenium-webdriver'),
    By = webdriver.By;

const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(new chromeDriver.Options().addArguments(['headless']))
    .build();

describe('首頁加載測(cè)試',function(){
    // 獲取百度搜索按鈕的 文本
    describe('按鈕文本',function(){
        it('按鈕文本必須等于',function(done){
            driver.get('https://www.baidu.com').then(function(){
                driver.findElement(By.id('su')).then((element) => {
                    return element.getAttribute('value')
                }).then((btnName) => {
                    console.log(btnName);
                    chai.expect(btnName).to.equal('百度一下');
                    done();
                });
            });
        })

    });

    // 獲取百度首頁 title
    describe('首頁標(biāo)題',function(){
        it('首頁標(biāo)題應(yīng)該為',function(done){
            driver.get('https://www.baidu.com').then(function(){
                driver.getTitle().then((title) => {
                    console.log(title);
                    chai.expect(title).to.equal('百度一下台诗,你就知道');
                    done();
                });
            });
        });
    });

    after(function(){
        driver.quit();
    })
});

使用Karma + mocha + chai

簡(jiǎn)介

Karma是一個(gè)用JavaScript實(shí)現(xiàn)的測(cè)試執(zhí)行器,實(shí)現(xiàn)了如下內(nèi)容

  • 對(duì)各種常見框架赐俗、庫的適配參考
  • 各種常見代碼預(yù)處理或轉(zhuǎn)譯參考
  • 各種執(zhí)行的測(cè)試報(bào)告方案參考
  • 各種瀏覽器或類瀏覽器的適配參考
  • 各種編輯器的適配拉队,內(nèi)容變更,立即重新執(zhí)行
  • 覆蓋率統(tǒng)計(jì)

安裝相應(yīng)的依賴庫

npm i --save-dev karma karma-chrome-launcher karma-mocha karma-chai
npm i --save-dev mocha chai

生成配置文件

在工程目錄下執(zhí)行如下命令

./node_modules/.bin/karma init

一路按照提示操作即可阻逮,生成的配置文件在工程目錄下karma.conf.js粱快,內(nèi)容大致如下:

// Karma configuration
// Generated on Mon Jul 10 2017 19:49:48 GMT+0800 (CST)

module.exports = function(config) {
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',
    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],
    // list of files / patterns to load in the browser
    files: [
    ],
    // list of files to exclude
    exclude: [
    ],
    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },
    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],
    // web server port
    port: 9876,
    // enable / disable colors in the output (reporters and logs)
    colors: true,
    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,
    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,
    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],
    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,
    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
調(diào)整配置支持headless chrome

可以到這里,查看chrome相關(guān)的karma-launcher,有ChromeHeadlessChromeCanaryHeadless這兩個(gè)headless驅(qū)動(dòng)可以選擇叔扼。

調(diào)整配置支持ES6事哭,添加webpack
npm i webpack karma-webpack babel-core babel-loader babel-preset-es2015
調(diào)整配置增加測(cè)試覆蓋度
npm i babel-plugin-istanbul
最終的到的Karma配置文件

karma.conf.js

// Karma configuration
// Generated on Mon Jul 10 2017 19:49:48 GMT+0800 (CST)

module.exports = function(config) {
    config.set({
        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',
        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['mocha','chai'],
        // list of files / patterns to load in the browser
        files: [
            'test/**/*.js'
        ],
        // list of files to exclude
        exclude: [
        ],
        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            'test/**/*.js': ['webpack']
        },
        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['progress', 'coverage'],
        coverageReporter: {
            type: 'html',
            dir: 'coverage/'
        },
        // web server port
        port: 9876,
        // enable / disable colors in the output (reporters and logs)
        colors: true,
        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,
        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,
        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['ChromeHeadless'],
        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true,
        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity,
        webpack: {
            module: {
                loaders: [{
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    query: {
                        presets: ['es2015'],
                        plugins: ['istanbul']
                    }
                }]
            }
        }
    })
}

編寫代碼

src/index.js

const isType = (data, type) => {
    return ['[object ', type, ']'].join('') === Object.prototype.toString.call(data)
};

const isFunction = (data) => {
    return isType(data, 'Function')
};

const isArray = (data) => {
    return isType(data, 'Array')
};


module.exports = {
    isType,
    isFunction,
    isArray
}

編寫測(cè)試用例

test/index.js

const typeUtil = require('../src/index')

describe('index.js: ', () => {
  it('isFunction() should work fine.', () => {
    expect(typeUtil.isFunction(function(){})).to.equal(true)
    expect(typeUtil.isFunction(Object.prototype.toString)).to.equal(true)
  });

  it('isArray() should work file.', () => {
      expect(typeUtil.isArray([])).to.equal(true)
      expect(typeUtil.isArray({})).to.equal(false)
  })
});

運(yùn)行測(cè)試

  • 在當(dāng)前目錄下運(yùn)行./node_modules/.bin/karma start
  • 或者添加如下代碼到package.json
  "scripts": {
    "test": "karma start"
  }

? 然后運(yùn)行npm run test

查看結(jié)果

  • 命令行能看到運(yùn)行結(jié)果
  • 在工程目錄下的coverage目錄能看到相應(yīng)的覆蓋率報(bào)告

存在的問題

Karma是將測(cè)試Case在瀏覽器中運(yùn)行并查看結(jié)果,當(dāng)頁面的url 改變的時(shí)候瓜富,會(huì)影響到整個(gè)Karma的執(zhí)行鳍咱,會(huì)有類似Some of your tests did a full page reload!這樣的提示。上面打開百度首頁檢查按鈕和title的例子在Karma中還沒有找到合適的方式寫出來与柑。

參考資料

  1. Automated testing with Headless Chrome
  2. 使用HeadlessChrome做單頁應(yīng)用SEO
  3. 基于HeadlessChrome的網(wǎng)頁自動(dòng)化測(cè)試系統(tǒng)-FinalTest
  4. 使用 headless chrome進(jìn)行測(cè)試
  5. 使用 headless chrome進(jìn)行測(cè)試
  6. UI自動(dòng)化測(cè)試之Headless browser容器化
  7. 初探 Headless Chrome
  8. Karma原理及論文
  9. karma入門
  10. karma 測(cè)試框架的前世今生
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旅急,一起剝皮案震驚了整個(gè)濱河市幔翰,隨后出現(xiàn)的幾起案子榔袋,更是在濱河造成了極大的恐慌让蕾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件结蟋,死亡現(xiàn)場(chǎng)離奇詭異脯倚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嵌屎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門挠将,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胳岂,“玉大人,你說我怎么就攤上這事舔稀∪榉幔” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵内贮,是天一觀的道長(zhǎng)产园。 經(jīng)常有香客問我,道長(zhǎng)夜郁,這世上最難降的妖魔是什么什燕? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮竞端,結(jié)果婚禮上屎即,老公的妹妹穿的比我還像新娘。我一直安慰自己事富,他們只是感情好技俐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著统台,像睡著了一般雕擂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贱勃,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天井赌,我揣著相機(jī)與錄音,去河邊找鬼贵扰。 笑死仇穗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的戚绕。 我是一名探鬼主播仪缸,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼列肢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宾茂,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤瓷马,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后跨晴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欧聘,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年端盆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怀骤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片费封。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒋伦,靈堂內(nèi)的尸體忽然破棺而出弓摘,到底是詐尸還是另有隱情,我是刑警寧澤痕届,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布韧献,位于F島的核電站,受9級(jí)特大地震影響研叫,放射性物質(zhì)發(fā)生泄漏锤窑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一嚷炉、第九天 我趴在偏房一處隱蔽的房頂上張望渊啰。 院中可真熱鬧,春花似錦申屹、人聲如沸绘证。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迈窟。三九已至,卻和暖如春忌栅,著一層夾襖步出監(jiān)牢的瞬間车酣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工索绪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留湖员,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓瑞驱,卻偏偏與公主長(zhǎng)得像娘摔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唤反,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容