聊聊多浏览器的智能化实验

如果你碰着前端工程师同伴,那聊聊阅读器的兼容性准是没错,这和碰着英国同伙就谈气象是一个事理。大部门法式员同伙们一定会捶胸顿足,连连抱怨,不外假如对方临时语塞,或许半吐半吞,请拍拍他 / 她肩膀说:
“没事,过两年出了新阅读器又是一条英雄。”
前端之殇
在前端界,阅读器兼容性是让工程师们头疼的成绩,对付履历丰富的人来讲,很清晰阅读器有哪些坑,然则对付大部门法式员,最可骇的是代码明显在这个阅读器运转得很好,然则到了另一个阅读器中就不克不及失常运转了。对付这部门的法式员,保证代码能失常运转的方法便是能及早发明成绩,而后将其办理。

 
平日环境下,发明兼容性成绩的方法莫过于将法式在各个阅读器中履行一遍,但这是极端挥霍人力和光阴的,最省力的方法也必要在每次版本的更迭时反复一遍测试工作。对付分歧的兼容性请求,测试必要的光阴各不相同,如果只支撑最新版本的阅读器,那末便测试 3、4 个阅读器便可,然则对付兼容性请求高的法式,有能够要测试 10 个阅读器以上。
对付中小型公司来讲,假如没有专职的测试职员,如许的测试耗时是致命的。若停止严厉测试,则会拖慢名目进度,倘使马马虎虎,那法式的品质便无奈包管。
本文将作为多阅读器主动化测试的第一篇文章,将以名目 A 作为例子,给读者重新先容若何停止当地多阅读的主动化测试工作,包含测试的事理、测试框架的拔取、测试工程的搭建和完成等。鄙人一篇文章中将先容若何应用云办事完成更多阅读器的测试工作。别的“从入门到不废弃”系列将给读者们带来更多从零开端的前端实践案例,诸如前端组件库计划与实行、名目主动化构建等案例,迎接人人存眷本系列的其余文章。
小窥测试
测试是一个庞大的主题,包含各类分类的测试,诸如黑盒测试/白盒测试、单位测试 / 集成测试 / 端到端测试等。平日法式员在测试本身的代码的时刻用得最多的便是单位测试,然则因为测试也是必要价值,许多人是不喜欢写测试的,乃至是一点都不写。固然本日咱们不是要伐罪诸位,而是盼望读者能从文中受害,从一个测试小白能够本身着手搭建本身的测试工程。
在多阅读器的主动化测试,咱们多数是停止端到端的测试工作,一小部门是大粒度的单位测试。端到端测试测试模仿用户的行动。在 Web 应用法式中,他们会启动办事器,关上阅读器,模仿用户的行动停止点击、输出、提交等举措,断言阅读器中发生了特定的工作或许是得到了等待的成果,从而让咱们信任功效能够失常的运转。而单位测试依据代码单位的大众 API 运转它们。这些测试必要创立一个类的实例,应用特定的输出挪用它的方法,断言被挪用的方法达到了预期的后果。
鄙人文中咱们会看到这两种测试的实践,固然有时刻辨别度并不大,能够无奈显著地辨别哪些是端对端测试哪些是单位测试,有时刻他们是混杂起来的,不外只需记着咱们的目标是包管功效能够失常运转就足够了。
在阅读器的测试中,Selenium 堪称是最紧张的对象之一。简略来讲 Selenium的感化是 “Automate Browsers”——让阅读器能够主动化起来的对象。它供应了同一的接口,让用户能够应用分歧的编程语言,挪用其接口来模仿用户的操纵,比方点击,挪动等操纵。基本上统统人工操纵的行动都能够经由进程 Selenium 的 API 停止触发操纵。咱们将 Selenium 看做是人手的署理,帮法式员完成统统用手干的活。
测试的技巧计划抉择
在停止名目实践前,很紧张的一项工作是抉择适合的技巧栈。比如在前端开辟时应当抉择 React,Vue 照样 Angular 作为框架异样,前端的测试工作也必要抉择一套技巧栈。
许多时刻人人在订定技巧栈时轻易走偏,在抉择技巧框架时不是抉择最适合的框架,而是抉择最热点的框架。固然一定水平上热点的框架能反响其受迎接水平,能够是因为其出众的长处,如较高的开辟效力、高效的衬着特征或许是活泼的社区。在前端开辟中,很轻易有如许的感触感染,便是只需半个月没有存眷业界的最新静态,就感到恍若隔世,新的办理计划层见叠出,让人喘不外气。
就作者自己履历来讲,已经过了忙乱的年事,再也不会盲目地追随新技巧,而转向存眷技巧面前办理的痛点,就似乎 2C 创业者们嘴上老说的用户痛点异样。

在先容本文触及名目标技巧栈以前,必要提示诸位,此处的技巧抉择并不一定完整适用于诸位的名目,请列位三思而测。今朝市场上有众多的测试框架,测试断言库乃至是全套的测试办理计划。Karma、Jasmine 和 Mocha 是人人熟知的测试框架,而 chai, should.js 是风行的断言库,别的在分歧的技巧社区另有自成一套的测试技巧,比如 React 社区中的 Jest 和 Enzyme 都是受开辟者喜爱的测试框架和库,近来一些新的并行测试办理计划也日渐风行,如 AVA 、Intern 。本文中的实践来自于名目 A,在名目测试后期咱们阐发了测试需要,咱们盼望全部测试计划能满意一下请求:
支撑端到端测试
对接云测试办事方便
当地测试和云测试切换方便
供应封装的阅读器操纵接口
测试用例能够疾速迁移到其余框架下履行
考量了以上的需要,咱们觉得 NightWatch.js 是一款非常适合的测试办理计划。固然其余的测试框架也基天性满意需要,然则从方便易用性上斟酌,咱们末了采纳了 NightWatch.js,该计划不只供应简略单纯封装的阅读器署理操纵 API, 还给咱们供应了方便便捷的云测试设置装备摆设(下一篇文章将侧重先容此内容),就凭这两点就已经非常吸引咱们了。对付前端测试老手,激烈保举试用此框架,让你能够敏捷完成已经畏而却步的测试工作。
名目实践
名目 A 的当地测试实践是必要分别在两台电脑上的多阅读器中履行测试,两台电脑分别是 Windows 体系和 Mac 体系,包含了 IE 、Firefox(windows / mac)、Chrome(windows / mac)、Safari 等最新的支流阅读器。两台机子的测试是分别履行的,咱们经由进程 Jenkins 分别按期履行机子上的测试义务,将测试成果经由进程邮件的方法反馈给开辟职员。 Jenkins 是一个连续集成的平台,对于假如应用 Jenkins 请列位本身 谷歌。

在接下来的文章中,咱们将只先容在一台机子上的工程实践,对付多个机子的测试必要将以下的工程安排到分歧的机子,再应用诸如 Jenkins 之类的对象停止按期履行就能够够。
开端工作前,咱们必要将技巧干系明了于心。咱们在 Nightwatch 框架下应用 Selenium 中的 driver对阅读器停止操纵。分歧的阅读器有分歧的 Driver,全部技巧栈图如图1所示:

 
在图中 Test Runner 即为 Nightwatch,咱们应用 Nightwatch 供应封装过的 API 停止 Test Case 的誊写。上面咱们将从零开端手把手教你若何应用 Nightwatch 启动你的第一个 Test case。
01装置测试所需包
在本身的前端名目中装置 Nightwatch.js,并将其保存在 package.json的 devDependencies 中。
npm install nightwatch --save-dev
02增长 npm script 进口
在 npm scripts 中参加 test 指令进口,该条指令的详细工作是应用 test.conf.js 的设置装备摆设,履行名为 ‘A’ 、’B’ 、’C’ 的设置装备摆设项(若为了直观反省测试的内容,可依据名目标测试阅读器和版本将名字设为 chrome52.0, safari9.0 如许的名字,此处设为 A , B , C 是防止人人误觉得是指令是主动依据名字去探求婚配的阅读器)。更多敕令的详解请参照 Nightwatch 文档。
"scripts": {
  ...
  "test": "./node_modules/.bin/nightwatch -c conf/test.conf.js -e A,B"
  ...
}
03设置装备摆设 Nightwatch
完成指令进口的设置装备摆设工作,接下来必要完成 test.conf.js 的设置装备摆设工作。在当地测试中,咱们应用 Selenium 对阅读器停止署理操纵。设置装备摆设应用当地 Selenium 操纵本机阅读器 Nightwatch 有三个重点:
Selenium 的设置装备摆设:设置装备摆设好 Selenium jar 包的门路,该包从 Selenium 的官网上下载,host 和 port 依照下文设置装备摆设誊写。
driver 的设置装备摆设:cli_args 是 Selenium 参数,在这咱们指定了 chromedriver 和 geckodriver 的门路,chromedriver 是用来操纵 chrome,geckodriver 用来操纵 safari 和 firefox(望文生义,geckodriver 支撑基于 gecko 的阅读器),都能够从网上停止下载。在名目A中,咱们将其下载到前端上面的 bin 目录下。
测试目标阅读器的设置装备摆设:也便是A和B,每个 Object 都是一个设置装备摆设项,A是测试Chrome阅读器,B是测试 Safari 阅读器,假如没有指定版本,就应用当地最新版,更多的设置装备摆设能够参考 Nightwatch 文档,能够指定体系、版本,并能够启动、禁用阅读器的某些特征,如 Cookie。
selenium : {
  "start_process" : true,
  "server_path":"./bin/selenium-server-standalone-3.4.0.jar",
  "host" : "127.0.0.1",
  "port" : 4444,
  "cli_args": {
    "webdriver.chrome.driver": "bin/chromedriver",
    "webdriver.gecko.driver" : "bin/geckodriver"
  }
},
test_settings: {
  A: {
    desiredCapabilities: {
      'browserName': 'chrome'
    }
  },
  B: {
    desiredCapabilities: {
      'browserName': 'safari'
    }
  }
}
诸位必要依据本身机子的实际环境停止设置装备摆设,假如是Windows体系,那末将没有safari阅读器,而应用 IE 阅读器,如许则会必要 IE 阅读器对应的 driver。
04誊写测试用例
在各项筹备工作终了后,就只差测试用例了,上面是名目 A 的一个测试用例的片断,用于检测页面上 id 为 testid 的 DOM 中的内容字符,咱们等待字符的长度为 32, 假如该字符为 32 个字符,那末测试经由进程,不然测试失败。
必要留意的是因为此 DOM 是静态拔出的,以是在断定其字符前,咱们应用 waitForElementVisible 来反省阅读器中 testid 的 DOM 能否已经表现,若在5秒内表现则停止上面的工作,假如没有表现,那末测试也会失败。
module.exports = {
  '@tags': ['unit'],
  'unit testing' : function (browser) {
    browser.url(`http://localhost:3010/test`)
      .waitForElementVisible('#testid', 5000)
      .getText("#testid",function(result){
        this.assert.equal(result.value.length,32);
      });
    browser.end();
  }
};
05. 运转测试
到此为止,咱们简略的测试工程已经搭建终了。如今咱们回过火去,履行咱们最开端设置装备摆设的 test 指令,启动测试义务。你必要在敕令中履行:
npm test
假如顺遂的话,此时你会看到阅读器主动地关上封闭,很快就能够从终端上看到以下的测试成果,图 2 展现的是多个测试用例胜利的成果,图 3 展现的是测试失败的成果(如碰到无奈测试或许别的非常环境请 谷歌。:D)。

 


 
从测试成果中能够反省测试用例的测试成果,包含测试的阅读器、未经由进程测试的信息概况等。至此,一个从零开端的当地测试实践教程停止。
当地测试与云测试
因为当地阅读器的范例无限,一样平常咱们更多地应用当地的多阅读器测试来完胜利效验证的工作,对付请求更严的兼容性测试,咱们将采纳云测试的方法。云测试即云办事供应商将向咱们供应更多的云主机,每台主机上运转着分歧版本的阅读器。经由进程应用云测试办事,咱们就能够将测试笼罩到更多范例、版本的阅读器。
在本篇文章的后半部门,咱们仍以名目 A 为例子,应用 Nightwatch 框架,在此文章的根基上先容云测试和云测试工程的搭建。
当地测试遥相呼应
因为一台盘算机支撑的阅读器品种无限,如一台 mac 上能够装置 safari, chrome, firefox, opera 等,并且平日只能装置一个版本的产物,以是当地测试多用于查验功效逻辑能否准确,或许是查验特定阅读器的特定功效。对付未知的兼容性测试,单凭当地测试是无奈停止的。下文中先容的方法将供应给测试者一种全新的测试体验,经由进程长途测试的方法对本身的代码停止测试。
长途测试必要搞清晰两个观点,一是客户端 (Client),一是办事端 (Server)。Client 是用于运转 test cases 代码的处所,Server 则是阅读器所在地。经由进程 Server 上的一些 servlet 来衔接 Client 和 Server 上的阅读器,完成将 test 中的用例行动在长途端的阅读器上履行。 经由进程阅读器和 test 履行宿主机的分别,使得test能在更多的阅读器上履行,并且更易于扩大测试阅读器的数目。鄙人文的实践傍边,读者会对 Client 和 Server 有更清晰的懂得,在此再也不赘述。
本身的云测试环境

既然测试代码要和阅读器环境朋分开来,那末咱们必要在前文的根基大将阅读器装置到其余的环境中,而不是将阅读器和测试的 Node 测试环境放在同一台机子。装置完成以后必要应用办事端的 Servlet 也便是 Selenium 供应的 webdriver server 将测试环境和阅读器衔接起来。详细的步调以下:
1探求到一台可用的主机: 无论是实体机照样虚构机都是能够的,不外必要主机能够接入到测试运转主机的收集。
2在主机上装置阅读器: 详细装置的阅读器范例和版本依据操纵体系和测试需要而定, 比方能够在 windows 操纵体系上装置 IE, firefox等阅读器,在 Linux 体系装置 chrome, firefox等阅读器, 在 Mac体系上装置 safari, chrome 等阅读器。
3下载对应阅读器的 driver 到Server主机上。因为 selenium 必要应用分歧的 driver 来启动分歧的阅读器,如同上一篇文章提到的bin目录下的 driver 可履行文件,此时要将必要测试阅读器对应的 driver 下载到 server 上,而后再经由进程测试工程的设置装备摆设奉告 selenium-server-standalone 这些 driver 在哪,从而履行它们来操纵阅读器。
chromedriver (用于 chrome)下载地点: https://sites.谷歌.com/a/chromium.org/chromedriver/
geckodriver (可用于 firefox, safari)下载地点:
https://github.com/mozilla/geckodriver/releases
4在主机上下载并启动 Selenium Server:该 Server 实际上是一个 Java 小法式,用于 client 和 server 之间的通讯(无关 selenium 事理的文章请存眷《搞不懂不甘心》系列)。起首在 Selenium 的官网上下载 selenium-server-standalone-{VERSION}.jar, 而后启动该 Jar 包。
java -jar selenium-server-standalone-{VERSION}.jar
假如主机没有装置 JRE,,则必要再装置 java 的运转环境或许是间接装置 jdk 。
5篡改测试名目标设置装备摆设文件:还记得启动测试时必要指定的设置装备摆设文件吗?这个设置装备摆设文件 test.conf.js 非常紧张,用于设置装备摆设 selenium 和测试的阅读器,当咱们转变应用长途server的阅读器作为测试目标时,固然必要篡改设置装备摆设文件。
咱们必要将设置装备摆设文件中的 selenium 项篡改成以下情势:
selenium : {
    "start_process" : true,
    //server的ip地点
    "host" : "192.168.10.1",
    "port" : 4444,
    "cli_args": {
      //chromedriver 在server主机上的文件门路
      "webdriver.chrome.driver": "/home/bin/chromedriver",
      //geckodriver 在server主机上的文件门路
      "webdriver.gecko.driver" : "/home/bin/geckodriver"
    }
  }
对付test_settings的设置请参照上文,而后依照本身装置的阅读器版本停止篡改。
6启动测试:统统筹备好了以后,在client主机上,也便是测试代码运转的机子上便可启动测试。
"scripts": {
  ...
  "test": "./node_modules/.bin/nightwatch -c conf/test.conf.js -e A,B"
  ...
}
本身搭建测试云环境的进程实在并不复杂,只必要在将 selenium server 和阅读器装置到其余主机便可,对付 client 上的代码不必要篡改,只必要篡改设置装备摆设中的 selenium 设置装备摆设。
然则很快测试者会发明,当咱们必要测试更多的机子,用手工的方法去保护这些 server 是一件费时辛苦的事,也耗费了公司的盘算资本。有无更好的方法让咱们既能够全面的测试本身的代码又能够不消费尽心理保护主机?谜底是有,请继承阅读。
云测试办事
对付繁琐反复的工程义务,商家们老是能想到赢利的方法,这不,对付上文咱们碰着的费事就有商家供应了响应的产物。该产物为测试者们供应无数个测试阅读器,测试者不必要关怀这些阅读器在何处运转,应当怎样保护,只必要一个办事地点,便能够将本身的测试页面跑在这些阅读器上。

 

实在这个办事地点和以前咱们本身搭建的 Server ip 相似,只不外假如应用本身的测试云,应用分歧的测试主机时,必要手动变动host。而这些商家供应了一个相似分销中间,用于流量散发,以是咱们只必要用一个地点便可完成应用分歧的主机停止测试。
今朝供应此类办事的商家有许多,如 browserstack、saucelabs、crossbrowsertesting 等,人人能够依据本身手头黄金和测试的必要抉择性价比高的办事。本文将应用 browserstack 作为例子为人人科普此类办事,不外它并非撸主的款项爸爸,请人人放下水文的猜忌。

 
依据咱们自行搭建云测试环境的履历,咱们将 browserstack 的测试后盾架构料想为下图所示。咱们不关怀该架构能否是实在的完成,然则这是正当的实践料想,盼望此图能让咱们对此办事有个也许的技巧懂得:

browserstack 为用户供应了主动化测试、及时交互测试、截图等办事,对于详细的办事细节请移步官网。本节将重要先容若何应用其主动化测试办事,会轻微说起及时交互测试的功效。
那接下来便开端咱们的云测试应用体验:
起首在其网站上注册账号,点击最上方的导航栏中的 Automate,跳转页面后在新页面左边最上方点击 ”Username and Access Keys”,便可看到用于应用云测试办事的用户名和key,咱们将应用此auth来篡改测试设置装备摆设。
如今回到咱们的测试名目,对 test.conf.js 的 selenium 项停止篡改,并增长 common_capabilities 项,用于设置装备摆设云办事的信息。
selenium : {
    ”start_process” : false,
    ”host” : “hub-cloud.browserstack.com”,
    ”port” : 80
  },
  common_capabilities: {
    ’build’: ‘nightwatch-browserstack’,
    // Browserstack 的 username 对应设置装备摆设项
    ’browserstack.user’: process.env.BROWSERSTACK_USERNAME’,
    // Browserstack 的 key 对应设置装备摆设项
    ’browserstack.key’: process.env.BROWSERSTACK_ACCESS_KEY,
    ’browserstack.debug’: true,
    ’browserstack.local’: true
  }
衔接云测试办事的设置装备摆设工作完成后,咱们必要指定测试的阅读器品种和版本。
假若有不指定的字段,云办事会有缺省值来添补,比方设置装备摆设中没有指定操纵体系,云办事则会主动抉择最快的一个测试机,而不论阅读器所在的操纵体系。再比方当没指定测试阅读器的版本时,云办事则会测试最新版本的阅读器。
官网上的文档供应了所有可供应测试的阅读器品种和版本,为了阐明方便,咱们如今只指定阅读器品种,不划定版本。
简要的阅读器设置装备摆设项以下:
 safari: {
      desiredCapabilities: {
        browserName: 'safari'
      }
    },
    ie: {
      desiredCapabilities: {
        browserName: 'ie'
      }
    },
    ...
    ios: {
      desiredCapabilities: {
        browserName: 'iPhone'
      }
    }
    ...
  }
以上工作做完以后便能够启动测试了,是不是so easy。
除敕令行前往的测试成果以外,browsertack 主动化测试还为咱们供应了测试回放等。假如发明测试失足,能够经由进程商家供应的在线及时测试来停止调试,这也是一个非常方便的功效。

WARDEN界面
对症下药地测试
阅读完主动化测试的文章,信任人人已经迫在眉睫想体验云测试的方便。在列位着手以前,有一些舒适提示必要奉告人人:
起首,这些云测试办事因为由外洋办事商供应,以是收集延时有些时刻会太高,测试能够会呈现超时的环境,请抉择收集较好的主机来运转测试用例。
其次,是因为主动化测试会让人人写测试用例上瘾,横竖测试扔下来测就好,然则撸主觉得测试职员照样要清晰地分别测试的粒度,有些测试用例比如细粒度的单位测试和端对端的测试,有许多测试笼罩的都是异样的代码,如许的测试实在是挥霍的,以是在明白目标以后,还必要经心计划测试用例。
末了,若有不懂请先 谷歌,其余不克不及 谷歌 的成绩迎接和撸主交换,文章若有错请指教。
潘潘,岂安科技软件工程师
同济大学卒业,曾在VMware等多家著名公司练习,3年全栈开辟履历,卖力岂安科技焦点产物早期的前端开辟和架构工作。