找回密码
 立即注册
首页 python Python-Web 查看内容
在几个浏览器和设备上手动运行测试,每天几次,可能会变得乏味且耗时。要有效地处理这个问题,您应该熟悉自动化工具。在本文中,我们将介绍可用的内容,如何使用任务运行程序,以及如何使用商业浏览器测试自动化应用程序(如Sauce Labs和Browser Stack)的基础知识。


先决条件:
熟悉核心HTMLCSSJavaScript语言; 了解跨浏览器测试的高级原则
目的:
了解自动化测试需要什么,如何使您的生活更轻松,以及如何利用一些使事情变得更容易的商业产品。


自动化简化了事情


在本单元中,我们详细介绍了您可以测试网站和应用程序的各种方法,并解释了跨浏览器测试工作在测试浏览器,可访问性注意事项等方面的范围。听起来很多工作,不是吗?


我们同意 - 测试我们在以前的文章中手动查看的所有内容可能是一个真正的痛苦。幸运的是,有一些工具可以帮助我们自动解决这些痛苦。我们可以通过两种主要方式自动执行我们在此模块中讨论过的测试:


  • 使用GruntGulp等任务运行程序npm脚本在构建过程中运行测试并清理代码。这是执行linting和minifying代码,添加CSS前缀或转换新生JavaScript功能以实现最大跨浏览器覆盖率等任务的好方法。
  • 使用像Selenium这样的浏览器自动化系统在已安装的浏览器上运行特定测试并返回结果,提醒您在浏览器出现时出现故障。商业跨浏览器测试应用程序(如Sauce LabsBrowser Stack)基于Selenium,但允许您使用简单的界面远程访问其设置,从而省去了设置自己的测试系统的麻烦。

我们将在下一篇文章中介绍如何设置自己的基于Selenium的测试系统。在本文中,我们将介绍如何设置任务运行器,并使用上述商业系统的基本功能。

注意:以上两个类别并不相互排斥。可以设置任务运行器以通过API访问Sauce Labs等服务,运行跨浏览器测试并返回结果。我们也将在下面看一下。


使用任务运行器自动化测试工具


正如我们上面所说,通过使用任务运行器来运行在构建过程中的某个点自动运行所需的所有内容,您可以大大加快常见任务,如linting和minifying代码。例如,这可能是每次保存文件时,或者在某个其他位置。在本节中,我们将介绍如何使用Node和Gulp自动执行任务,这是一个适合初学者的选项。


设置Node和npm


目前大多数工具都基于Node.js,因此您需要从nodejs.org安装它:


  • 从以上站点下载适用于您系统的安装程序。(如果已经安装了Node和npm,请跳转到第4点)
  • 像任何其他程序一样安装它。请注意,Node附带了Node Package Manager(npm),它允许您轻松安装软件包,与他人共享您自己的软件包,以及在您的项目上运行有用的脚本。
  • 安装完成后,通过在终端中键入以下内容来测试该节点,该终端返回已安装的Node版本和npm:
node -v
npm -v
如果您已安装Node / npm,则应将其更新为最新版本。要更新Node,最可靠的方法是从他们的网站下载并安装更新的安装程序包(请参阅上面的链接)。要更新npm,请在终端中使用以下命令:
npm install npm@latest -g
注意:如果上述命令失败并出现权限错误,则修复npm权限应该将您排除在外。


要在项目中开始使用基于Node / npm的包,您需要将项目目录设置为npm项目。这很容易做到。


例如,让我们首先创建一个测试目录,让我们玩,而不用担心会破坏任何东西。


使用文件管理器UI创建一个新目录,或者导航到所需位置并运行以下命令:
mkdir node-test

要使此目录成为npm项目,您只需要进入测试目录并初始化它,具体如下:
cd node-test
npm init

第二个命令将询问您很多问题,以找出设置项目所需的信息; 你现在可以选择默认值。

一旦提出所有问题,它将询问您输入的信息是否正常。键入yes并按Enter / Return,npm将package.json在您的目录中生成一个文件。

该文件基本上是项目的配置文件。您可以稍后自定义它,但现在它看起来像这样:
{
  "name": "node-test",
  "version": "1.0.0",
  "description": "Test for npm projects",
  "main": "index.js",
  "scripts": {
    "test": "test"
  },
  "author": "Chris Mills",
  "license": "MIT"
}
有了这个,你就可以继续前进了。


设置Gulp自动化


让我们看看设置Gulp并使用它来自动化一些测试工具。


  • 首先,使用上一节底部详述的过程创建一个测试npm项目。
  • 接下来,您将需要一些示例HTML,CSS和JavaScript内容来测试您的系统 - 在项目文件夹中具有名称的子文件夹中制作示例index.htmlmain.jsstyle.css文件的副本src。如果您愿意,可以尝试自己的测试内容,但请记住,这些工具不适用于内部JS / CSS - 您需要外部文件。
  • 首先,使用以下命令全局安装gulp(意思是,它将在所有项目中可用):


npm install --global gulp-cli

接下来,在npm项目目录root中运行以下命令,将gulp设置为项目的依赖项:
npm install --save-dev gulp

现在在项目目录中创建一个名为的新文件gulpfile.js。这是将运行我们所有任务的文件。在此文件中,输入以下内容:
var gulp = require('gulp');

gulp.task('default', function() {
  console.log('Gulp running');
});

这需要gulp我们之前安装的模块,然后运行一项基本任务,除了向终端打印消息外什么都不做 - 这对于让我们知道Gulp正在工作非常有用。每一口任务被写在相同的基本格式- gulp的task()运行方法,并给予两个参数-任务的名称,包含实际代码的回调函数运行到完成任务。

您可以使用以下命令运行gulp任务 - 立即尝试:
gulp

将一些实际任务添加到Gulp


要向Gulp添加一些实际任务,我们需要考虑我们想要做什么。在我们的项目上运行的一组合理的基本功能如下:


  • htmltidy,csslint和jshint到皮棉和报告/修复常见的HTML / CSS / JS错误(见一饮而尽-htmltidy大口喝,csslint吞掉-jshint)。
  • Autoprefixer扫描我们的CSS并仅在需要时添加供应商前缀(请参阅gulp-autoprefixer)。
  • babel将任何新的JavaScript语法功能转换为适用于旧版浏览器的传统语法(请参阅gulp-babel)。

有关我们正在使用的不同gulp包的完整说明,请参阅上面的链接。


要使用每个插件,您需要先通过npm安装它,然后在gulpfile.js文件顶部需要任何依赖项,然后将测试添加到它的底部,最后在任务中添加任务的名称default。

在继续之前,请将默认任务更新为:

gulp.task('default', [ ]);
gulp命令行上运行命令后,数组内部将显示您希望Gulp运行的所有任务的名称。


HTML的整洁使用以下行安装:

npm install --save-dev gulp-htmltidy

注意--save-dev将包作为依赖项添加到项目中。如果您查看项目的package.json文件,您将看到它的条目,因为它已添加到devDependencies属性中。


将以下依赖项添加到gulpfile.js
var htmltidy = require('gulp-htmltidy');

将以下测试添加到底部gulpfile.js:
gulp.task('html', function() {
  return gulp.src('src/index.html')
        .pipe(htmltidy())
        .pipe(gulp.dest('build'));
});
'html'default任务中作为数组添加到数组中。


在这里,我们抓住了我们的开发index.html文件 - gulp.src() 它允许我们抓取源文件来执行某些操作。


我们接下来使用该pipe()函数将该源传递给另一个命令以执行其他操作。我们可以根据需要将尽可能多的这些链接在一起。我们首先运行htmltidy()源代码,它会检查并修复文件中的错误。第二个pipe()函数将输出HTML文件写入build目录。


在文件的输入版本中,您可能已经注意到我们放了一个空<p>元素; htmltidy已经在创建输出文件时删除了它。


Autoprefixer和css-lint使用以下行安装:

npm install --save-dev gulp-autoprefixer
npm install --save-dev gulp-csslint

将以下依赖项添加到gulpfile.js:
var autoprefixer = require('gulp-autoprefixer');
var csslint = require('gulp-csslint');

将以下测试添加到底部gulpfile.js:
gulp.task('css', function() {
    return gulp.src('src/style.css')
        .pipe(csslint())
        .pipe(csslint.formatter('compact'))
        .pipe(autoprefixer({
            browsers: ['last 5 versions'],
            cascade: false
        }))
        .pipe(gulp.dest('build'));
});
'css'default任务中作为数组添加到数组中。


在这里我们获取style.css文件,在其上运行csslint(它将CSS中的任何错误列表输出到终端),然后通过autoprefixer运行它以添加使旧的CSS功能在旧版浏览器中运行所需的任何前缀。在管道链的末尾,我们将修改后的前缀CSS输出到build 目录。请注意,这仅在csslint未发现任何错误时有效 - 尝试从CSS文件中删除大括号并重新运行gulp以查看您获得的输出!


js-hint和babel使用以下行安装:

npm install --save-dev gulp-babel @babel/preset-env
npm install --save-dev @babel/core
npm install jshint gulp-jshint --save-dev

将以下依赖项添加到gulpfile.js:
var babel = require('gulp-babel');
var jshint = require('gulp-jshint');

将以下测试添加到底部gulpfile.js:
gulp.task('js', function() {
    return gulp.src('src/main.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(babel({
            presets: ['@babel/env']
        }))
        .pipe(gulp.dest('build'));
});
'js'default任务中作为数组添加到数组中。


在这里我们抓取我们的main.js文件,jshint在其上运行并使用结果输出结果到终端jshint.reporter; 然后我们将文件传递给babel,后者将其转换为旧式语法并将结果输出到build目录中。我们的原始代码包括一个胖箭头功能,这个功能已被babel修改为旧式功能。


更多想法完成所有这些设置之后,您可以gulp在项目目录中运行命令,并且应该得到如下输出:



然后,您可以通过在build目录中查看它们并build/index.html在Web浏览器中加载来尝试自动化任务输出的文件。

如果出现错误,请检查您是否已添加所有依赖项和测试,如上所示; 还尝试注释掉HTML / CSS / JavaScript代码部分,然后重新运行gulp以查看是否可以找出问题所在。

Gulp附带了一个watch()功能,您可以使用该功能观察文件并在保存文件时运行测试。例如,尝试将以下内容添加到您的底部gulpfile.js:

gulp.task('watch', function(){
  gulp.watch('src/*.html', ['html']);
  gulp.watch('src/*.css', ['css']);
  gulp.watch('src/*.js', ['js']);
});
现在尝试将gulp watch命令输入终端。Gulp现在将监视您的目录,并在您将更改保存到HTML,CSS或JavaScript文件时运行相应的任务。


注意*字符是通配符 - 这里我们说“在保存这些类型的任何文件时运行这些任务。您还可以在主要任务中使用通配符,例如,gulp.src('src/*.css')将获取所有CSS文件,然后运行管道任务在他们。


注意:上面我们的watch命令的一个问题是,当遇到CSS错误时,我们的CSSLint / Autoprefixer组合会抛出完整的错误,这会阻止监视工作。一旦遇到CSS错误,您将不得不重新启动手表,或者找到另一种方法来执行此操作。


你可以用Gulp做更多的事情。该咕嘟咕嘟插件目录有数以千计的插件进行搜索的。


其他任务选手


还有许多其他任务运行器可用。我们当然不是说Gulp是那里最好的解决方案,但它对我们有用,初学者也很容易接受。您也可以尝试使用其他解决方案:


  • Grunt的工作方式与Gulp非常相似,只不过它依赖于配置文件中指定的任务,而不是使用编写的JavaScript。有关详细信息,请参阅Grunt入门。
  • 您还可以使用位于package.json文件中的npm脚本直接运行任务,而无需安装任何类型的额外任务运行程序系统。这样做的前提是像Gulp插件这样的东西基本上是命令行工具的包装器。因此,如果您可以使用命令行计算出如何运行这些工具,则可以使用npm脚本运行它们。使用起来有点棘手,但对于那些拥有强大的命令行技能的人来说,这可能是有益的。为什么是npm脚本?提供了大量进一步信息的良好介绍。

使用商业测试服务加速浏览器测试


现在让我们来看看商业第三方浏览器测试服务以及他们可以为我们做些什么。


这些应用程序的基本前提是运行每个应用程序的公司都有一个庞大的服务器场,可以运行许多不同的测试。当您使用此服务时,您提供要测试的页面的URL以及信息,例如您希望在其中测试的浏览器。然后,应用程序使用您指定的操作系统和浏览器配置新VM,并返回测试以截图,视频,日志文件,文本等形式显示。

然后,您可以使用API​​以编程方式访问功能,这意味着此类应用程序可以与任务运行程序(例如您自己的本地Selenium环境和其他人)组合,以创建自动化测试。


注意:还有其他商业浏览器测试系统,但在本文中,我们将重点关注Sauce Labs和BrowserStack。我们并不是说这些都是最好的工具,但它们是很好的,对初学者来说很容易起床和运行。


酱汁实验室


Sauce Labs入门让我们开始一个Sauce Labs试用版。


  • 创建一个Sauce Labs试用帐户
  • 登录。这将在您验证电子邮件地址后自动执行。


基础知识:手动测试酱实验室仪表盘上有提供很多的选择。现在,请确保您在“ 手动测试”选项卡上。


  • 单击“ 开始新的手动会话”
  • 在下一个屏幕中,键入要测试的页面的URL(使用http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box-fixed.html,例如),然后使用不同的按钮和列表选择要测试的浏览器/操作系统组合。正如你所看到的,有很多选择!



  • 单击“开始会话”时,将出现一个加载屏幕,该屏幕会旋转运行您选择的组合的虚拟机。
  • 加载完成后,您可以开始远程测试在所选浏览器中运行的网站。




从这里您可以看到您正在测试的浏览器中的布局,移动鼠标并尝试单击按钮等。顶部菜单允许您:


  • 停止会话
  • 给别人一个URL,以便他们可以远程观察测试。
  • 将文本/备注复制到远程剪贴板。
  • 截取屏幕截图。
  • 在全屏模式下测试。


停止会话后,您将返回“手动测试”选项卡,在该选项卡中,您将看到您之前开始的每个手动会话的条目。单击其中一个条目可显示该会话的更多数据。在这里,您可以下载您拍摄的任何屏幕截图,观看会话视频,以及查看会话的数据日志。

注意:这已经非常有用,并且比自己设置所有这些模拟器和虚拟机更方便。


高级:Sauce Labs APISauce Labs有一个安静的API,允许您以编程方式检索帐户和现有测试的详细信息,并使用更多详细信息注释测试,例如通过单独的手动测试无法记录的通过/未通过状态。例如,您可能希望使用Sauce Labs远程运行您自己的一个Selenium测试,以测试某个浏览器/操作系统组合,然后将测试结果传递回Sauce Labs。


它有几个客户端,允许您使用您喜欢的环境调用API,无论是PHP,Java,Node.js等。


让我们简要了解一下我们如何使用Node.js和node-saucelabs访问API 。


  • 首先,设置一个新的npm项目来测试它,详见设置节点和npm。使用与以前不同的目录名称,sauce-test例如。
  • 使用以下命令安装Node Sauce Labs包装器:
    npm install saucelabs
  • 在项目根目录中创建一个名为的新文件call_sauce.js。给它以下内容:
var SauceLabs = require('saucelabs');

var myAccount = new SauceLabs({
  username: "your-sauce-username",
  password: "your-sauce-api-key"
});

myAccount.getAccountDetails(function (err, res) {
  console.log(res);
  myAccount.getServiceStatus(function (err, res) {
    // Status of the Sauce Labs services
    console.log(res);
    myAccount.getJobs(function (err, jobs) {
      // Get a list of all your jobs
      for (var k in jobs) {
        if ( jobs.hasOwnProperty( k )) {
          myAccount.showJob(jobs[k].id, function (err, res) {
            var str = res.id + ": Status: " + res.status;
            if (res.error) {
              str += "\033[31m Error: " + res.error + " \033[0m";
            }
            console.log(str);
          });
        }
      }
    });
  });
});
您需要在指定的位置填写您的Sauce Labs用户名和API密钥。可以从“ 用户设置”页面检索这些内容。现在填写这些。


确保一切都已保存,并运行您的文件,如下所示:
node call_sauce
高级:自动化测试
我们将在下一篇文章中介绍实际运行的自动化Sauce Lab测试。


BrowserStack


BrowserStack入门让我们开始使用BrowserStack试用版。


  • 创建BrowserStack试用帐户
  • 登录。这将在您验证电子邮件地址后自动执行。
  • 首次登录时,您应该进入实时测试页面; 如果没有,请单击顶部导航菜单中的实时链接。
  • 如果您使用的是Firefox或Chrome,系统会提示您在标题为“启用本地测试”的对话框中安装浏览器扩展程序 - 单击“ 安装”按钮继续。如果您使用的是其他浏览器,您仍然可以使用某些功能(通常通过Flash),但您将无法获得完整的体验。



基础知识:手动测试
BrowserStack Live仪表板允许您选择要测试的设备和浏览器 - 左栏中的平台,右侧的设备。当您鼠标悬停或单击每个设备时,您可以选择该设备上可用的浏览器。





点击其中一个浏览器图标将加载您选择的平台/设备/浏览器 - 现在选择一个,并尝试一下。




注意:某些移动设备选项旁边的蓝色设备图标表示您将在真实设备上测试; 没有该图标的选项将在模拟器上运行。


您会发现可以在地址栏中输入URL,并使用其他控件,就像您在真实设备上所期望的那样。您甚至可以执行从设备复制和粘贴到剪贴板,通过拖动鼠标向上和向下滚动,或在支持设备的触摸板上使用适当的手势(例如捏/缩放,两个手指滚动)(例如Macbook) )。请注意,并非所有设备都提供所有功能。


您还会看到一个允许您控制会话的菜单。





这里的功能如下:


  • 切换 - 切换到另一个平台/设备/浏览器组合。
  • 方向(看起来像重新加载图标) - 在纵向和横向之间切换方向。
  • 适合屏幕(看起来像一个全屏图标) - 尽可能使用设备填充测试区域。
  • 捕获一个错误(看起来像一个摄像头) - 获取屏幕截图,然后允许您注释并保存它。
  • 问题跟踪器(看起来像一副牌) - 查看以前捕获的错误/屏幕截图。
  • 设置(cog图标) - 允许您更改会话的常规设置。
  • 帮助(问号) - 访问帮助/支持功能。
  • Devtools - 允许您使用浏览器的devtools直接调试或操作测试浏览器中显示的页面。目前仅在iOS设备上测试Safari浏览器时才有效。
  • 设备信息 - 显示有关测试设备的信息。
  • 功能 - 显示当前配置支持的功能,例如复制到剪贴板,手势支持等。
  • 停止 - 结束会话。

注意:这已经非常有用,并且比自己设置所有这些模拟器和虚拟机更方便。


其他基本功能如果您返回主BrowserStack页面,您会在更多菜单选项下找到其他一些有用的基本功能:


  • 响应:输入URL并按Generate,BrowserStack将在具有不同视口大小的多个设备上加载该URL。在每个设备中,您可以进一步调整显示器大小等设置,以便更好地了解网站布局如何在不同的外形中工作。
  • 屏幕截图:输入URL,选择您感兴趣的浏览器/设备/平台,然后按生成屏幕截图 - Browserstack将在所有这些不同的浏览器中截取您的网站的屏幕截图,然后供您查看和下载。

高级:BrowserStack API
BrowserStack还有一个restful API,允许您以编程方式检索帐户计划,会话,构建等的详细信息。

它有几个客户端,允许您使用您喜欢的环境调用API,无论是PHP,Java,Node.js等。


让我们简要了解一下我们如何使用Node.js访问API。


首先,设置一个新的npm项目来测试它,详见设置节点和npm。使用与以前不同的目录名称,bstack-test例如。

在项目根目录中创建一个名为的新文件call_bstack.js。给它以下内容:
var request = require("request");

var bsUser = "BROWSERSTACK_USERNAME";
var bsKey = "BROWSERSTACK_ACCESS_KEY";
var baseUrl = "https://" + bsUser + ":" + bsKey + "@www.browserstack.com/automate/";

function getPlanDetails(){
    request({uri: baseUrl + "plan.json"}, function(err, res, body){
        console.log(JSON.parse(body));
    });
    /* Response:
    {
        automate_plan: <string>,
        parallel_sessions_running: <int>,
        team_parallel_sessions_max_allowed: <int>,
        parallel_sessions_max_allowed: <int>,
        queued_sessions: <int>,
        queued_sessions_max_allowed: <int>
    }
    */
}

您需要在指定的位置填写您的BrowserStack用户名和API密钥。这些可以从您的BrowserStack自动化仪表板中检索。现在填写这些。

确保一切都已保存,并运行您的文件,如下所示:
node call_bstack

下面我们还提供了一些其他现成的函数,在使用BrowserStack restful API时可能会发现这些函数很有用。
function getBuilds(){
        request({uri: baseUrl + "builds.json"}, function(err, res, body){
                console.log(JSON.parse(body));
        });
        /* Response:
        [ 
                { 
                        automation_build: { 
                                name: <string>,
                                duration: <int>,
                                status: <string>,
                                hashed_id: <string> 
                        } 
                },
                { 
                        automation_build: { 
                                name: <string>,
                                duration: <int>,
                                status: <string>,
                                hashed_id: <string> 
                        } 
                },
                ...
        ]
        */
};

function getSessionsInBuild(build){
        var buildId = build.automation_build.hashed_id;
        request({uri: baseUrl + "builds/" + buildId + "/sessions.json"}, function(err, res, body){
                console.log(JSON.parse(body));
        });
        /* Response:
        [
                { 
                        automation_session: { 
                                name: <string>,
                                duration: <int>,
                                os: <string>,
                                os_version: <string>,
                                browser_version: <string>,
                                browser: <string>,
                                device: <string>,
                                status: <string>,
                                hashed_id: <string>,
                                reason: <string>,
                                build_name: <string>,
                                project_name: <string>,
                                logs: <string>,
                                browser_url: <string>,
                                public_url: <string>,
                                video_url: <string>,
                                browser_console_logs_url: <string>,
                                har_logs_url: <string> 
                        } 
                },
                { 
                        automation_session: { 
                                name: <string>,
                                duration: <int>,
                                os: <string>,
                                os_version: <string>,
                                browser_version: <string>,
                                browser: <string>,
                                device: <string>,
                                status: <string>,
                                hashed_id: <string>,
                                reason: <string>,
                                build_name: <string>,
                                project_name: <string>,
                                logs: <string>,
                                browser_url: <string>,
                                public_url: <string>,
                                video_url: <string>,
                                browser_console_logs_url: <string>,
                                har_logs_url: <string> 
                        } 
                },
                ... 
        ]
        */
}

function getSessionDetails(session){
        var sessionId = session.automation_session.hashed_id;
        request({uri: baseUrl + "sessions/" + sessionId + ".json"}, function(err, res, body){
                console.log(JSON.parse(body));
        });
        /* Response:
        { 
                automation_session: { 
                        name: <string>,
                        duration: <int>,
                        os: <string>,
                        os_version: <string>,
                        browser_version: <string>,
                        browser: <string>,
                        device: <string>,
                        status: <string>,
                        hashed_id: <string>,
                        reason: <string>,
                        build_name: <string>,
                        project_name: <string>,
                        logs: <string>,
                        browser_url: <string>,
                        public_url: <string>,
                        video_url: <string>,
                        browser_console_logs_url: <string>,
                        har_logs_url: <string> 
                } 
        }
        */
}


高级:自动化测试
我们将在下一篇文章中介绍实际运行的自动BrowserStack测试。



分享至 : QQ空间
收藏

0 个回复

您需要登录后才可以回帖 登录 | 立即注册