前端自动化测试漫长路之——Selenium初探

引言

最近想解决前端开发或测试中的两个问题:一是界面UI的布局适配,可否在测试的过程当中,经过命令操做真机打开相应页面而后截屏,经过对图片识别分类,发现有问题的图片,而后及时修复;二是页面性能分析,不少时候页面只能在指定的Webview中使用,可否直接经过命令打开指定的页面,分析页面在真实APP中的性能,并生成报告。这两个问题的前提就是经过命令直接操做手机App,带着问题找线索,因而我就结识了Selenium,下面将结合实例和你们分享一下。javascript

Selenium是什么?

先看一下官网的解释:html

Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
Selenium has the support of some of the largest browser vendors who have taken (or are taking) steps to make Selenium a native part of their browser. It is also the core technology in countless other browser automation tools, APIs and frameworks.前端

从上面的话咱们能够知道3个点:java

  1. 利用Selenium能够自动化操做浏览器,来实现web程序的自动化测试;
  2. Selenium是一个综合性的项目,提供了提供了不一样语言版本的类库和工具,来支持浏览器的自动化;
  3. 主流浏览器基于W3C规定的的Web Driver规范,提供了相应的Web Driver,而标准的主要技术支持来源于Selenium项目。

一图胜千言,Selenium在自动化测试中扮演的角色以下图所示:
node

Selenium如何用?

咱们的诉求是经过脚本控制本地和手机上的浏览器,甚至APP中的Webview,Selenuim正好提供了WebDriver API供咱们使用。从上面能够知道Selenium支持多种语言,如python、go、javascript等,对于前端而言,首选固然是javascript。如下是相关的操做步骤:python

环境准备

该环节主要是两步:android

  1. 在项目中下载selenium-webdriver
npm install selenium-webdriver --save
  1. 下载浏览器提供的WebDriver,并将该命令文件放置在系统变量PATH下
    我使用的是chrome的WebDriver,针对不一样的chrome版本,须要下载不一样版本的WebDriver,不然程序会报错。网上有好心人已经整理出了chrome的WebDriver与chrome的版本映射表,能够点击查看

代码编写

selenium-webdriver的说明文档至关的赞,在selenium-webdriver包的目录下有几个文件:chrome.js、edge.js、ie.js、phantom.js等,这些都是selenium-webdriver针对不一样的浏览器的webdriver的调用作了封装,打开chrome.js,在文件的开头有详细的文档说明。
chrome.js中提到了3种使用场景:分别是Headless Chrome、Customizing the ChromeDriver Server、Working with Android。而我须要的场景就是Working with Android。
实例代码以下:git

let chrome = require('selenium-webdriver/chrome');
let {Builder} = require('selenium-webdriver');
let driver = new Builder()
          .forBrowser('chrome')
          .setChromeOptions(new chrome.Options()
              .androidPackage('com.example')
              .androidActivity('com.example.Activity'))
          .build();

其中须要要点就是指定要操做的浏览器类型、APP包的名字、android程序的Activity名字。通常webview的内核都是基于webkit的,指定浏览器类型为chrome便可,APP的包名和Activity名字能够经过命令工具aapt获取,关于aapt的详细介绍能够参考这篇博客
经过以上两步,就能够经过node执行相应的js文件,实现经过命令来控制APP了,这里是几个我测试的demo,供你们下载github

selenium-webdriver运行原理

上面的操做涉及到了两个核心,即浏览器提供的webdriver和浏览器(chrome/chromium)。selenium-webdriver的做用就是利用webdriver将浏览器启动起来,并实现一系列自动操做。但究竟webdriver和浏览器是怎样一个协同关系呢,从chrome.js文件的注释中能够找到一些线索。web

By default, every Chrome session will use a single driver service, which is started the first time a Driver instance is created and terminated when this process exits. The default service will inherit its environment from the current process and direct all output to /dev/null. You may obtain a handle to this default service using getDefaultService getDefaultService() and change its configuration with setDefaultService setDefaultService().

从上面能够知道,selenium-webdriver先经过webdriver启动了一个driver service,该service又启动chrome,分别起在不一样的端口。
经过查阅资料,能够知道driver service在开启chrome的同时,为chrome安装了一个Chrome Automation Extension扩展程序,该扩展程序的描述是:Exposes extension APIs for automating Chrome,经过查看其源码,能够看到launchApp、getWindowInfo等函数,主要是提供了一些操做chrome的相关方法。
一图胜千言,selenium-webdriver的工做原理以下图所示,该图来源于网络

Tips:
上面知道了driver service与chrome之间的关系,知道默认状况下driver service的生命周期和测试的Chrome session是同步的,意味着每次测试都须要开启一个driver service,若是频繁的开启和关闭service,势必会形成资源浪费。
针对这个状况,官方的描述是这样的:

The ChromeDriver class starts the ChromeDriver server process at creation and terminates it when quit is called. This can waste a significant amount of time for large test suites where a ChromeDriver instance is created per test.

官方针对该状况提出了两个解决办法:

  1. Start the ChromeDriver server separately before running your tests, and connect to it using the Remote WebDriver.
    即测试以前先单独启动driver server,而后使用Remote WebDriver链接上driver server所在的端口。官方提供了一个python的示例:
import time
from selenium import webdriver
import selenium.webdriver.chrome.service as service
service = service.Service('/path/to/chromedriver')
service.start()
capabilities = {'chrome.binary': '/path/to/custom/chrome'}
driver = webdriver.Remote(service.service_url, capabilities)
driver.get('http://www.google.com/xhtml');
time.sleep(5) # Let the user actually see something!
driver.quit()
  1. Use the ChromeDriverService. This is available for most languages and allows you to start/stop the ChromeDriver server yourself.
    可本身建立一个driver,同时为这个driver指定相应的service。这样不只能够为driver提供个性化的服务(如log日志),还能够控制service的生命周期。
    代码以下:
let chrome = require('selenium-webdriver/chrome');
let service = new chrome.ServiceBuilder()
    .loggingTo('/my/log/file.txt')
    .enableVerboseLogging()
    .build();
let options = new chrome.Options();
// configure browser options ...
 let driver = chrome.Driver.createSession(options, service);

小结

前端自动化测试的道路是漫长的,对selenium的挖掘才刚刚开始。本文并无解决引言中提到的两个问题,selenium-webdriver只是解决了第一步,即经过命令行来操做app,后面将继续学习,继续总结分享。

相关文章
相关标签/搜索