Web自动化之Headless Chrome测试框架集成

使用Selenium操作headless chrome 推荐

简介

WebDriver是一个W3C标准, 定义了一套检查和控制用户代理(比如浏览器)的远程控制接口,各大主流浏览器来实现这些接口以便调用控制接口来操作浏览器。

Selenium是一整套的Web自动化测试解决方案,配合WebDrive规范,实现了对各种用户代理的适配(比如浏览器,PhantomJS等),通过操作浏览器的WebDriver接口来实现带浏览器的Web自动化。

使用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的方式不一样,其他调用完全一样

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是一个编码辅助,自动配置环境变量,不需要手动下载和配置环境变量,通过安装chromedriver同时在代码中引入

require('chromedriver')

更换获取源的URL(使用如下任意一种就行)

安装过程添加参数,默认下载地址为http://chromedriver.storage.googleapis.com

npm install chromedriver --chromedriver_cdnurl=https://npm.taobao.org/mirrors/chromedriver
  • 添加如下内容到.npmrc文件
chromedriver_cdnurl=https://npm.taobao.org/mirrors/chromedriver
  • 添加环境变量CHROMEDRIVER_CDNURL
CHROMEDRIVER_CDNURL=https://npm.taobao.org/mirrors/chromedriver npm install chromedriver

更换安装的chromedriver文件路径
  • 安装过程使用配置参数
npm install chromedriver --chromedriver_filepath=/path/to/chromedriver_mac64.zip
  • 添加如下内容到.npmrc文件
chromedriver_filepath=/path/to/chromedriver_mac64.zip
  • 添加环境变量
CHROMEDRIVER_FILEPATH=/path/to/chromedriver_mac64.zip

使用mocha + chai

简介

mocha是一个可以运行在浏览器端和NodeJS环境的JavaScript测试框架,区别于类库,框架定义好了流程,并调用你的代码。

chai是一个断言库,判断结果是否符合预期。

实例代码

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('首页加载测试',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('首页标题',function(){
        it('首页标题应该为',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

简介

Karma是一个用JavaScript实现的测试执行器,实现了如下内容

  • 对各种常见框架、库的适配参考
  • 各种常见代码预处理或转译参考
  • 各种执行的测试报告方案参考
  • 各种浏览器或类浏览器的适配参考
  • 各种编辑器的适配,内容变更,立即重新执行
  • 覆盖率统计

安装相应的依赖库

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

生成配置文件

在工程目录下执行如下命令

./node_modules/.bin/karma init

一路按照提示操作即可,生成的配置文件在工程目录下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'],
    // 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
  })
}
调整配置支持headless chrome

可以到这里,查看chrome相关的karma-launcher,有ChromeHeadlessChromeCanaryHeadless这两个headless驱动可以选择。

调整配置支持ES6,添加webpack
npm i webpack karma-webpack babel-core babel-loader babel-preset-es2015
调整配置增加测试覆盖度
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
}

编写测试用例

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)
  })
});

运行测试

  • 在当前目录下运行./node_modules/.bin/karma start
  • 或者添加如下代码到package.json
  "scripts": {
    "test": "karma start"
  }

然后运行npm run test

查看结果

  • 命令行能看到运行结果
  • 在工程目录下的coverage目录能看到相应的覆盖率报告

存在的问题

Karma是将测试Case在浏览器中运行并查看结果,当页面的url 改变的时候,会影响到整个Karma的执行,会有类似Some of your tests did a full page reload!这样的提示。上面打开百度首页检查按钮和title的例子在Karma中还没有找到合适的方式写出来。

参考资料

  1. Automated testing with Headless Chrome
  2. 使用HeadlessChrome做单页应用SEO
  3. 基于HeadlessChrome的网页自动化测试系统-FinalTest
  4. 使用 headless chrome进行测试
  5. 使用 headless chrome进行测试
  6. UI自动化测试之Headless browser容器化
  7. 初探 Headless Chrome
  8. Karma原理及论文
  9. karma入门
  10. karma 测试框架的前世今生

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏.net core新时代

使用Nancy.Host实现脱离iis的Web应用

  本篇将介绍如何使用Nancy.Host实现脱离iis的Web应用,在开源任务管理平台TaskManagerV2.0代码里面已经使用了Nancy.Host实现...

2537
来自专栏互联网杂技

react+redux+webpack教程3

现代web页面里到处都是ajax,所以处理好异步的代码非常重要。 这次我重新选了个最适合展示异步处理的应用场景——搜索新闻列表。由于有现成的接口,我们就不用自己...

36410
来自专栏更流畅、简洁的软件开发方式

Attribute(特性),怎么用才更好?

前几年:   2008年的某一天,我坐火车去北京。硬卧上铺,一晚上就到北京了。爬到上铺之后发现,旁边上铺有一老兄抱着一个笔记本,一开始还以为是看电影呢,仔细一...

2309
来自专栏jojo的技术小屋

原 荐 svga 动画

作者:汪娇娇 时间:2017年12月26日 对于一些小的简单的动画,借助css、js差不多就能实现,而且还不能保证还原度百分百(还能接受); 对于那些复杂的动画...

3834
来自专栏北京马哥教育

专为渗透测试人员设计的Python工具大合集

如果你对漏洞挖掘、逆向工程分析或渗透测试感兴趣的话,我第一个要推荐给你的就是Python编程语言。Python不仅语法简单上手容易,而且它还有大量功能强大的库和...

3117
来自专栏JackieZheng

学习SpringMVC——从HelloWorld开始

前言:   时隔十二年,中国女排最终过关斩将,用3:1的成绩证明了自己的实力,霸气夺冠,为中国赢得了一枚意义非常的金牌。这是一次全民的狂欢,一场视听盛宴,带给我...

1917
来自专栏BestSDK

开发必备,小程序常见错误与解决方法

也接触了不少人解决问题的过程里,有一些比较难以排查的可能性列举在这,方便大家看一下: 特别提示:为了排除问题所在,建议针对问题制作最简demo,以便最小化缩小其...

3627
来自专栏刘望舒

有关Android插件化思考

最近几年移动开发业界兴起了「 插件化技术 」的旋风,各个大厂都推出了自己的插件化框架,各种开源框架都评价自身功能优越性,令人目不暇接。随着公司业务快速发展,项目...

571
来自专栏SDNLAB

码农学ODL之OpenDaylight与OpenStack的集成

OpenDaylight和OpenStack的集成一直是热门话题,OpenDaylight官网也提供了相应的文档(https://wiki.opendaylig...

3205
来自专栏一枝花算不算浪漫

SpringBoot actuator 应用监控。

今天在阅读 《SpringCloud微服务实战》一书时看到了SpringBoot actuator相关知识,并且自己也本地调试实践。觉得SpringBoot这一...

361

扫码关注云+社区