• 前端分享学习博客,探究前端相关技术,推动天朝前端发展,有任何问题都可以留言一起探究
  • 由于站内自链接问题,部分pre中的代码首字母使用大写以过滤筛选
  • 欢迎友链互换,还有,如果有大神请不要黑我的站点(o´・ェ・`o)
  • 如果你觉得博客还不错,请Ctrl+D收藏( *︾▽︾)

CasperJS-自动化测试API

开始之前

自动化测试这个话题,相信很多人已经有了些许的了解,虽然叫自动化测试,当然也不是鼠标click一下就出一份报告,需要详尽的逻辑步骤配置,也就是写好脚本代码,模拟浏览器环境和操作,测出可能出现的问题;所以一开始有一个阻碍在这里,一个项目要写好一套测试脚本要花很多功夫,干嘛不让测试人员去手动测试?后面逐渐接触到一些测试场景和测试工具,觉得做这些工作还是很有必要的,理由就不累述了;如标题所述,把casperJS的坑先开好,扶好坐稳;

 

casperJS是什么?

CasperJS是一个开源的导航脚本处理和测试工具,基于PhantomJS(前端自动化测试工具)编写。CasperJS简化了完整的导航场景的过程定义,提供了用于完成常见任务的实用的高级函数、方法和语法;具体说明/安装/功能可参考官网

而这里测试主要用的就是CasperJS的测试功能,通过下面的test API和其他功能来完成诸如表单提交/文档检查/数据对比/Dom检查/条件匹配和数据抓取等一系列的测试功能;

具体测试实例就是使用CasperJS API 编写测试脚本,然后在命令行运行 casperjs test your_file.js,就会执行测试,这里casperjs test是固定格式(非测试脚本只要casperjs就行),your_file.js是测试实例,以官网为例(记得科学上网):

casper.test.begin('assertTitle() tests', 1, function(test) {
 casper.start('https://www.google.com.hk/', function() {
 test.assertTitle('Google', 'google.fr has the correct title');
//判定google.com.hk页面的title=='Google'
 }).run(function() {
 test.done();
 });
});

取名google.js,然后运行 casperjs test google.js,然后:

CasperJS-自动化测试API

最后一行就是测试结果,然后根据测试结果做相应的项目调整;

好了,下面是具体API:

assert()
语法:assert(Boolean condition[, String message])
判定所提供的条件严格地解析为布尔值true

casper.test.assert(true, "true's true");
casper.test.assert(!false, "truth is out");

assertNot()
语法:casper.test.assertNot(false, “Universe is still operational”);
判定传递的对象解析为一些错误的值

assertDoesntExist()
语法:assertDoesntExist(String selector[, String message])
判定在远程DOM环境中不存在与提供的选择器表达式匹配的元素

casper.test.begin('assertDoesntExist() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven"></div>');
 test.assertDoesntExist('.taxes');
 }).run(function() {
 test.done();
 });
});

assertExists()
语法:assertExists(String selector[, String message])
判定在远程DOM环境中存在与提供的选择器表达式匹配的元素

casper.test.begin('assertExists() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven">beer</div>');
 test.assertExists('.heaven');
 }).run(function() {
 test.done();
 });
});

assertEquals()
语法:assertEquals(mixed testValue, mixed expected[, String message])
判定两个值严格相等

casper.test.begin('assertEquals() tests', 3, function(test) {
 test.assertEquals(1 + 1, 2);
 test.assertEquals([1, 2, 3], [1, 2, 3]);
 test.assertEquals({a: 1, b: 2}, {a: 1, b: 2});
 test.done();
});

assertEval()
语法:assertEval(Function fn[, String message, Mixed arguments])
判定远程DOM中的代码评估严格地解析为布尔值true

casper.test.begin('assertEval() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven">beer</div>');
 test.assertEval(function() {
 return __utils__.findOne('.heaven').textContent === 'beer';
 });
 }).run(function() {
 test.done();
 });
});

assertEvalEquals()
语法:assertEvalEquals(Function fn, mixed expected[, String message, Mixed arguments])
判定远程DOM中代码评估的结果严格等于预期值

casper.test.begin('assertEvalEquals() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven">beer</div>');
 test.assertEvalEquals(function() {
 return __utils__.findOne('.heaven').textContent;
 }, 'beer');
 }).run(function() {
 test.done();
 });
});

assertElementCount()
语法:assertElementCount(String selector, Number count[, String message])
判定选择器表达式与给定数量的元素匹配

casper.test.begin('assertElementCount() tests', 3, function(test) {
 casper.start().then(function() {
 this.page.content = '<ul><li>1</li><li>2</li><li>3</li></ul>';
 test.assertElementCount('ul', 1);
 test.assertElementCount('li', 3);
 test.assertElementCount('address', 0);
 }).run(function() {
 test.done();
 });
});

assertExists()
语法:assertExists(String selector[, String message])
判定在远程DOM环境中存在与提供的选择器表达式匹配的元素

casper.test.begin('assertExists() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven">beer</div>');
 test.assertExists('.heaven');
 }).run(function() {
 test.done();
 });
});

assertDoesntExist()
语法:assertDoesntExist(String selector[, String message])
判定在远程DOM环境中不存在与提供的选择器表达式匹配的元素

casper.test.begin('assertDoesntExist() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="heaven"></div>');
 test.assertDoesntExist('.taxes');
 }).run(function() {
 test.done();
 });
});

assertFalsy()
语法:assertFalsy(Mixed subject[, String message])
判定所给的对象是false;

assertTruthy()
语法:assertTruthy(Mixed subject[, String message])
判定所给的对象是true

assertField()
语法:assertField(String|Object input, String expected[, String message, Object options])
判定给的表单域具有提供的输入名称或选择器表达式的值,除了表单,也可以检验select textarea:

casper.test.begin('assertField() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 this.fill('form[name="gs"]', { q: 'plop' }, false);
 test.assertField('q', 'plop');
 }).run(function() {
 test.done();
 });
});

// Path usage with type 'css'
casper.test.begin('assertField() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 this.fill('form[name="gs"]', { q: 'plop' }, false);
 test.assertField({type: 'css', path: '.q.foo'}, 'plop');
 }).run(function() {
 test.done();
 });
});

assertFieldName()
语法: assertFieldName(String inputName, String expected[, String message, Object options])
判定给的表单字段具有预设的值

casper.test.begin('assertFieldName() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 this.fill('form[name="gs"]', { q: 'plop' }, false);
 test.assertFieldName('q', 'plop', 'did not plop', {formSelector: 'plopper'});
 }).run(function() {
 test.done();
 });
});

assertFieldCSS()
语法: assertFieldCSS(String cssSelector, String expected, String message)
判定给的表单字段具有预设CSS选择器的提供的值

casper.test.begin('assertFieldCSS() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 this.fill('form[name="gs"]', { q: 'plop' }, false);
 test.assertFieldCSS('q', 'plop', 'did not plop', 'input.plop');
 }).run(function() {
 test.done();
 });
});

assertFieldXPath()
语法:assertFieldXPath(String xpathSelector, String expected, String message)
判定给的表单域具有给定的XPath选择器的值

casper.test.begin('assertFieldXPath() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 this.fill('form[name="gs"]', { q: 'plop' }, false);
 test.assertFieldXPath('q', 'plop', 'did not plop', '/html/body/form[0]/input[1]');
 }).run(function() {
 test.done();
 });
});

assertHttpStatus()
语法:assertHttpStatus(Number status[, String message])
判定当前的HTTP状态代码与作为参数传递的代码相同

casper.test.begin('casperjs.org is up and running', 1, function(test) {
 casper.start('http://casperjs.org/', function() {
 test.assertHttpStatus(200);
 }).run(function() {
 test.done();
 });
});

assertMatch()
语法:assertMatch(mixed subject, RegExp pattern[, String message])
判定所提供的字符串与提供的JavaScript RegExp模式相匹配

casper.test.assertMatch('Chuck Norris', /^chuck/i, 'Chuck Norris\' first name is Chuck');

assertTitle()
语法:assertTitle(String expected[, String message])
判定远程页面的标题等于预期的标题

casper.test.begin('assertTitle() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertTitle('Google', 'google.fr has the correct title');
 }).run(function() {
 test.done();
 });
});

assertTitleMatch()
语法:assertTitleMatch(RegExp pattern[, String message])
判定远程页面的标题与提供的RegExp模式匹配

casper.test.begin('assertTitleMatch() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertTitleMatch(/Google/, 'google.fr has a quite predictable title');
 }).run(function() {
 test.done();
 });
});

assertType()
语法:assertType(mixed input, String type[, String message])
判定提供的参数值类型是否跟设定的相同

casper.test.begin('assertType() tests', 1, function suite(test) {
 test.assertType(42, "number", "Okay, 42 is a number");
 test.assertType([1, 2, 3], "array", "We can test for arrays too!");
 test.done();
});

assertInstanceOf()
语法:assertInstanceOf(mixed input, Function constructor[, String message])
判定提供的参数是给定的构造函数

function Cow() {
 this.moo = function moo() {
 return 'moo!';
 };
}
casper.test.begin('assertInstanceOf() tests', 2, function suite(test) {
 var daisy = new Cow();
 test.assertInstanceOf(daisy, Cow, "Ok, daisy is a cow.");
 test.assertInstanceOf(["moo", "boo"], Array, "We can test for arrays too!");
 test.done();
});

assertUrlMatch()
语法:assertUrlMatch(Regexp pattern[, String message])
判定当前页面的URL与提供的RegExp模式相匹配

casper.test.begin('assertUrlMatch() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertUrlMatch(/^http:\/\//, 'google.fr is served in http://');
 }).run(function() {
 test.done();
 });
});

assertVisible()
语法:assertVisible(String selector[, String message])
判定至少一个与提供的选择器表达式匹配的元素是可见的

casper.test.begin('assertVisible() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertVisible('h1');
 }).run(function() {
 test.done();
 });
});

assertNotEquals()
语法: assertNotEquals(mixed testValue, mixed expected[, String message])
判定两个值不是严格相等的

casper.test.assertNotEquals(true, "true");

assertRaises()
语法:assertRaises(Function fn, Array args[, String message])
判定使用给定参数调用的函数会引发一个JavaScript错误

casper.test.assertRaises(function(throwIt) {
 if (throwIt) {
 throw new Error('thrown');
 }
}, [true], 'Error has been raised.');

casper.test.assertRaises(function(throwIt) {
 if (throwIt) {
 throw new Error('thrown');
 }
}, [false], 'Error has been raised.'); // fails

assertSelectorDoesntHaveText()
语法:assertSelectorDoesntHaveText(String selector, String text[, String message])
判定所给的文本在所有的元素匹配中都不存在

casper.test.begin('assertSelectorDoesntHaveText() tests', 1, function(test) {
 casper.start('http://google.com/', function() {
 test.assertSelectorDoesntHaveText('title', 'Yahoo!');
 }).run(function() {
 test.done();
 });
});

assertSelectorHasText()
语法:assertSelectorHasText(String selector, String text[, String message])
判定给定文本存在于与提供的选择器表达式匹配的元素中

casper.test.begin('assertSelectorHasText() tests', 1, function(test) {
 casper.start('http://google.com/', function() {
 test.assertSelectorHasText('title', 'Google');
 }).run(function() {
 test.done();
 });
});

assertResourceExists()
语法:assertResourceExists(Function testFx[, String message])
对所有加载的资源执行testFx函数,并至少有一个匹配时,测试通过

casper.test.begin('assertResourceExists() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertResourceExists(function(resource) {
 return resource.url.match('logo3w.png');
 });
 }).run(function() {
 test.done();
 });
});
//简写:
casper.test.begin('assertResourceExists() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertResourceExists('logo3w.png');
 }).run(function() {
 test.done();
 });
});

assertTextExists()
语法:assertTextExists(String expected[, String message])
判定body中纯文本内容包含给定的字符串

casper.test.begin('assertTextExists() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertTextExists('google', 'page body contains "google"');
 }).run(function() {
 test.done();
 });
});

assertTextDoesntExist()
语法: assertTextDoesntExist(String unexpected[, String message])
判定body中纯文本内容不包含给定的字符串

casper.test.begin('assertTextDoesntExist() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertTextDoesntExist('bing', 'page body does not contain "bing"');
 }).run(function() {
 test.done();
 });
});

assertAllVisible()
语法:assertAllVisible(String selector[, String message])
判定所有与提供的选择器表达式匹配的元素都是可见的

casper.test.begin('assertAllVisible() tests', 1, function(test) {
 casper.start('http://www.google.fr/', function() {
 test.assertAllVisible('input[type="submit"]');
 }).run(function() {
 test.done();
 });
});

assertNotVisible()
语法:assertNotVisible(String selector[, String message])
判定与提供的选择器表达式匹配的元素不可见

casper.test.begin('assertNotVisible() tests', 1, function(test) {
 casper.start().then(function() {
 this.setContent('<div class="foo" style="display:none>boo</div>');
 test.assertNotVisible('.foo');
 }).run(function() {
 test.done();
 });
});

begin()
语法:
begin(String description, Number planned, Function suite)
begin(String description, Function suite)
begin(String description, Number planned, Object config)
begin(String description, Object config)
开始一套<planned>测试(如果已定义)。套件回调将获取当前的Tester实例作为其第一个参数

function Cow() {
 this.mowed = false;
 this.moo = function moo() {
 this.mowed = true; // mootable state: don't do that
 return 'moo!';
 };
}

// unit style synchronous test case
casper.test.begin('Cow can moo', 2, function suite(test) {
 var cow = new Cow();
 test.assertEquals(cow.moo(), 'moo!');
 test.assert(cow.mowed);
 test.done();
});
note: 在给定的测试脚本突然中断的情况下,计划的参数特别有用,用户无需明白方法就可以知道错误的状态

一个更异步的例子:

casper.test.begin('Casperjs.org is navigable', 2, function suite(test) {
 casper.start('http://casperjs.org/', function() {
 test.assertTitleMatches(/casperjs/i);
 this.clickLabel('Testing');
 });

 casper.then(function() {
 test.assertUrlMatches(/testing\.html$/);
 });

 casper.run(function() {
 test.done();
 });
});
Important:必须调用done()才能终止测试用例。这是非常重要的,当进行异步测试时,确保它在所有实际执行时被调用;

begin()也可接受测试配置对象,可以加上set()和tearDown()方法:

casper.test.begin('Cow can moo', 2, {
 setUp: function(test) {
 this.cow = new Cow();
 },

 tearDown: function(test) {
 this.cow.destroy();
 },

 test: function(test) {
 test.assertEquals(this.cow.moo(), 'moo!');
 test.assert(this.cow.mowed);
 test.done();
 }
});

done()
语法:done()
标记完结一个以begin()开头处理的测试用例

casper.test.begin('my test suite', 2, function(test) {
 test.assert(true);
 test.assertNot(false);
 test.done();
});

异步用法:

casper.test.begin('Casperjs.org is navigable', 2, function suite(test) {
 casper.start('http://casperjs.org/', function() {
 test.assertTitleMatches(/casperjs/i);
 this.clickLabel('Testing');
 });

 casper.then(function() {
 test.assertUrlMatches(/testing\.html$/);
 });

 casper.run(function() {
 test.done();
 });
});

colorize()
语法:colorize(String message, String style)
渲染彩色输出,基本是对Casper.Colorizer方法的替代;

comment()
语法:comment(String message)
在控制台输出一个评论格式的提示信息

casper.test.comment("Hi, I'm a comment");

error()
语法:error(String message)
在控制台输出一个错误格式的提示信息

casper.test.error("Hi, I'm an error");

fail()
语法:fail(String message [, Object option])
将失败的测试条目添加到堆栈

casper.test.fail("Georges W. Bush");
casper.test.fail("Here goes a really long and expressive message", {name:'shortfacts'});

pass()
语法:pass(String message)
将成功的测试条目添加到堆栈

casper.test.pass("Barrack Obama");

formatMessage()
语法:formatMessage(String message, String style)
格式化一个消息,高亮某些部分。仅由测试仪内部使用

getFailures()
语法:getFailures()
检索当前测试用例的故障(1.1版本后已弃用)

casper.test.assertEquals(true, false);
require('utils').dump(casper.test.getFailures());
casper.test.done();

会给出以下提示:

$ casperjs test test-getFailures.js
Test file: test-getFailures.js
FAIL Subject equals the expected value
# type: assertEquals
# subject: true
# expected: false
{
 "length": 1,
 "cases": [
 {
 "success": false,
 "type": "assertEquals",
 "standard": "Subject equals the expected value",
 "file": "test-getFailures.js",
 "values": {
 "subject": true,
 "expected": false
 }
 }
 ]
}
FAIL 1 tests executed, 0 passed, 1 failed.

Details for the 1 failed test:

In c.js:0
 assertEquals: Subject equals the expected value
note:在CasperJS 1.1中,可以通过监听测试仪失败事件记录测试失败:
var failures = [];

casper.test.on("fail", function(failure) {
 failures.push(failure);
});

getPasses()
语法:getPasses()
在当前测试套件中检索成功测试用例的报告(1.1版本后已弃用)

casper.test.assertEquals(true, true);
require('utils').dump(casper.test.getPasses());
casper.test.done();

1.1版本可以这样使用:

var successes = [];

casper.test.on("success", function(success) {
 successes.push(success);
});

info()
语法:info(String message)
在控制台输出一个信息格式的提示

casper.test.info("Hi, I'm an informative message.");

renderResults()
语法:renderResults(Boolean exit, Number status, String save)
渲染测试结果,将结果保存在XUnit格式的文件中,并可选择退出phantomjs

casper.test.renderResults(true, 0, 'test-results.xml')
note:使用casperjs test命令时,不要调用此方法,它自动完成

setUp()
语法:setUp([Function fn])
在每次使用begin()定义的测试之前执行的函数

casper.test.setUp(function() {
 casper.start().userAgent('Mosaic 0.1');
});

要执行异步操作,要使用done参数:

casper.test.setUp(function(done) {
 casper.start('http://foo').then(function() {
 // ...
 }).run(done);
});
Warning:如果不打算以异步方式使用该方法,则不要指定完成的参数

skip()
语法:skip(Number nb, String message)
跳过一定数量的计划测试

casper.test.begin('Skip tests', 4, function(test) {
 test.assert(true, 'First test executed');
 test.assert(true, 'Second test executed');
 test.skip(2, 'Two tests skipped');
 test.done();
});

tearDown()
语法:tearDown([Function fn])
定义一个函数,将在使用begin()的每个测试后执行

casper.test.tearDown(function() {
 casper.echo('See ya');
});

要执行异步操作,请使用done参数:

casper.test.tearDown(function(done) {
 casper.start('http://foo/goodbye').then(function() {
 // ...
 }).run(done);
});
warning:如果不打算以异步方式使用该方法,则不要指定完成的参数;

 

以上是CasperJS中的tester module部分,实际操作还要配合其他的module API如getCurrentUrl()等等;

PS:如有纰漏,请联系我;

 

Reference:

http://casperjs.org/

http://docs.casperjs.org/en/latest/modules/tester.html

Simpler UI Testing With CasperJS

 


薛陈磊的博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明CasperJS-自动化测试API
喜欢 (1)
[905044086@qq.com]
分享 (0)
作者薛陈磊
关于作者:
非著名前端工程师,关注Html5、Css3、Javascript、Node.js和各种前端框架发展,学习管理技巧和团队建设方法,期待遇到更多前端小伙伴一起学习进步;
说点什么...
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 这代码 博主太专业了
    加气块设备2017-07-03 13:59 回复 Windows 7 | 搜狗浏览器 2.X
  2. 这个不错哦,我好好读读!
    网赚2017-06-22 17:52 回复 Windows 7 | 搜狗浏览器 2.X