使用 CasperJS 进行简单的 UI 测试

看到了一篇有关casperjs不错的文章,转载到自己博客学习一下:
摘要
无论你开发大或小的应用, 从安全来讲测试是一个很重要的组成部分.
但是如何可靠持续的测试, 尤其是当你的人员不能有效的测试应用的每一次改变? 所以呢,把这个工作交给软件是最合适的了.
这么多年来, 开发者开发了很多应用和技术来满足这个需求. 当然, 它们运行的非常好. 但是我们总是寻找更新的, 更简单的 (有时候是更’酷’的) 方式来做我们的工作. 所以最近我开始学习一种更有前途的新技术: PhantomJS.
—————————————————————————————
PhantomJS是什么?
PhantomJS 是一个无界面的,包含了WebKit浏览器引擎JavaScript API的脚本解释器. 速度快并且支持各种web标准: DOM 操作, CSS 选择器, JSON, Canvas 和SVG.
PhantomJS 的创建者是 Ariya Hidayat. 它是一个非常棒的技术,但是通过网站上的了解和所有的APIs文档, 我遇到了 CasperJS.
CasperJS是什么?
Casper 是一个用JavaScript编写的基于PhantomJS的导航脚本和测试工具.它充许我们像PHPUnit或 JUnit一样测试我们的网站,测试我们的代码.
它是一个非常棒的工具 – 一是它是非常简单的,用JavaScript编写,满足各种各样的测试需求,一是它可以方便的和我们的开发环境集成. 完美的组合前端和后端.
—————————————————————————————
在本篇文章中,我将浏览一下CasperJS的基础用法。我将扮演一个典型的用户访问New Relic(新的遗址)网站的一页,特别是‘真实用户监控’部分。
我之所以选择这一页是因为它有大量方面对一个标准网站或应用极为常见,如图像,表单,按钮,链接和文本。它内容丰富并且有许多东西可供我们处理与测试。现在,我确信New Relic的勤快的伙计已经做过这些,但我也非常相信他们不会介意我为这个网站建立一个简单的测试集和断言。
特征
CasperJS具有一系列特征。 本文中,我会聚焦于 测试人员 API。它具有一些列功能与断言,都是你期望一个好的测试API所具有的,包括:
* assertTextExists (文本存在断言)
* assertTitle (标题断言)
* assertHttpStatus (HTTP状态断言)
* assertDoesntExist (不存在断言)
* assertUrlMatch (Url匹配断言)

我将使用这些断言来显示CasperJS是如何工作的。它也包含一组其他特性,但我不会去深入探讨——仅仅足够做一个工作示例而已。不过,我鼓励你研究一下精彩的在线API文档。它阅读起来令人愉悦,因为它相当清晰和简洁。
准备
如果你没有准备好,在我们继续以前,先安装 PhantomJS 或 Casper 。 现在,让我们马上开始吧。
开始
当我第一次加载New Relic网站的’真实用户监控’页面,看起来像下面图片这样(自撰写本文以后它已经变化了)。我突出了注册表格的起点。
这里写图片描述
如果你点击了这个表单里的任何元素,它其余的部分就会显露出来,看起来就是下图这样。
这里写图片描述
测试将着眼于表单,但我们也要看看title标签,表单左边的图片,及其上的文字。
代码
首先,为节省时间,我初始化了两个变量:一个用来存储URL,一个用来存储网站名称,因为我要在测试中的‘success’信息里显示它们。

var url = 'http://newrelic.com/product/real-user-monitoring';
var siteName = 'NewRelic';

Casper带有4个内建记录级别:
* debug
* info
* warning
* error

默认情况下,CasperJS会在‘error’级别过滤日志。所以如果你开始记录日志后没有看到任何东西,可能就是这个原因。为确保显示日志输出,我把它设置为‘debug’。而且我关闭了‘verbose’选项,如果它激活,我们会看到关于所有东西的信息,这会相当干扰。

var casper = require('casper').create({
    verbose: false,
    logLevel: 'debug'
});

你可以在Casper API页面上发现其它配置选项。comment函数,如下面演示的,使我们能记录输出——在这种情况下是输出到控制台。我在这里使用一个简单的消息说明测试开始了:

casper.test.comment('Starting Testing');

函数‘casper.start’开始运行测试:

casper.start(url, function() {
    this.test.assert(
        this.getCurrentUrl() === url, 'url is the one expected'
    );

    this.test.assertHttpStatus(200, siteName + ' is up');

这是我所做的:我加载在‘url’中指定的URL,并假定我们可以载入想要的网址。在成功加载页面之后,开始调用一些断言来确认所载入的页面上的内容是我们所期望的。
在这种情况下,我对返回的状态码进行了一个快速检查,它应该是200,我得到的也是200。让我们进行另一个断言:

this.test.assertTitle(
    'Real User Monitoring, End User Experience Monitoring : New Relic',
    siteName + ' has the correct title'
);

上面这个测试非常简单。它断言载入的页面的标题应该是什么,并输出一个含有该信息的消息。
在下面的代码里,我首先检查确认存在一个ID为‘nr-signup-form’的表单。如果这个表单不存在,那对表单内的元素进行检查就没有意义了,对吧?

this.test.assertExists(
    'form[id="nr-signup-form"]',
    siteName + ' has a form with name "nr-signup-form"'
);

现在,在我继续之前,我要提到的是,当我断言元素存在或不存在于加载的页面上时,我可以用两种不同的方法:
*XPath
*CSS选择器

现在让我们用断言来搜索输入域控件:

this.test.assertExists(
    {type: 'xpath', path: '//input[@id="FullName"]' },
    'the element exists'
);

this.test.assertExists(
    {type: 'xpath', path: '//input[@id="Company"]' },
    'the element exists'
);

this.test.assertExists(
    {type: 'xpath', path: '//input[@id="Email"]' },
                'the element exists'
);

this.test.assertExists(
    {type: 'xpath', path: '//input[@id="Password"]' },
    'the element exists'
);

this.test.assertExists(
    {type: 'xpath', path: '//input[@id="PromoCode"]' },
    'the element exists'
);

在上面的五个断言中,我查找了五个输入域控件,它们的ID分别是‘FullName’, ‘Company’, ‘Email’, ‘Password’ 和‘PromoCode’。用XPath查找选择列表控件元素同样容易。

现在,这些测试还非常简单。那么,让我们来把它们变得复杂点。

this.test.assertExists(
    {
        type: 'xpath',
        path: '//button[@id="sign-up-button"
                and @class="small-button"
                and @type="submit"]'
    }, 'the element exists'
);

在上面的测试中,我搜索‘Create Free Account’按钮,它在页面中的位置如下图所示。
这里写图片描述
我在查询中使用了一些条件运算符。我们要寻找一个具有下列条件的按钮:
* ID 为 ‘sign-up-button’
* class 为‘small-button’
* type 为‘submit’
虽然看起来似乎我关注XPath比CasperJS更多,但为了更多的功能和配置,请耐心忍受我多说一点吧。

var x = require('casper').selectXPath;
var checkboxXpath = "//input[@type='checkbox' and
@id='checkbox1']/parent::*/a/label[
    contains(., 'Java') or
    contains(., 'Python') or
    contains(., 'Ruby') or
    contains(., 'PHP') or
    contains(., '.NET') or
    contains(., 'Node.js')
]";
this.test.assertExists(x(checkboxXpath), 'the element exists');

我在上面的测试中所做的,是通过把’x’初始化为‘selectXPath’助手来使XPath测试变得简化一点。我要查找那一页上所有选择应用程序类型的复选框,所以XPath查询查找复选框时用一个伴随的label标签来匹配所提供的应用程序语言的名称。
为专门显示我并非只会使用XPath(虽然它极其强大而且简单),下面的两个测试也使用CSS选择器来检查一个输入域控件和列表项目也存在。

this.test.assertVisible('input#Company');

this.test.assertExists('li.nav-enterprise', 'the element exists');

搜索表单元素和列表项目很简单,但若你的页面有很多资源,对于图片或Flash的载入又怎么检测呢?这有一个例子:

this.test.assertResourceExists(
    '/images/tshirt-dude-form.png', 'T-shirt Image exists'
);

对于上面的测试,我断言穿着所展示T恤的男人的照片已载入。 最后一个测试断言某些文本存在,在本情况中就是在穿着T恤的男人镜头上方的‘Sign up for free!’文本:

this.test.assertTextExists(
        'Sign up for free!', 'page body contains "Sign up for free!"'
    );

然后我们这样结束‘start’函数:

casper.test.comment('Ending Testing');

测试基本完成了,所以我输出另一个日志记录来让用户知道这一点:

casper.run(function() {
    this.test.done(16);
    this.echo('So the whole suite ended.');
    require('utils').dump(casper.test.getFailures());
    require('utils').dump(casper.test.getPasses());
    this.exit();
});

我可以写出我想要的所有测试,但若不调用“run”则什么都不会发生。所以“run”是揭开上述工作的序幕。我所做的是检查脚本是否已经运行了16个测试,并且在最后用‘this.echo()’输出最后一行文字表示整个测试已结束。
当我们运行测试时,有时得到最后结果的总结会挺好。用‘getFailures()’ 和 ‘getPasses()’函数,我们可以看到测试通过和失败的总结。跟在这一切最后,我调用“this.exit()”来清盘。这个可以退出CasperJS和PhantomJS,如果需要,可以指定一个退出编号。
把这个更进一步,这一次我调用‘casperjs’略有不同:我传递‘test’,如下所示,伴随着“xunit”开关。 这个将测试结果输出到一个 XUnit XML文件.

$ casperjs test mytest.js --xunit=log.xml

在CasperJS的下一个主要版本中,如果‘test’没被传递到命令中,你将无法运行和呈现测试。提前知道这个很重要,可以避免你的脚本被意外打断。

转自:http://www.oschina.net/translate/simpler-ui-testing-with-casperjs

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值