js 单元测试框架介绍

35
李亚飞 louie/185421

Upload: louieuser

Post on 07-May-2015

1.018 views

Category:

Education


5 download

TRANSCRIPT

Page 1: Js 单元测试框架介绍

李亚飞 louie/185421

Page 2: Js 单元测试框架介绍

1.Qunit 2.Jasmine 3.YUITest

Page 3: Js 单元测试框架介绍

Jörn Zaefferer : QUnit是一个JavaScript单元测试框架,主要用于在浏览器中运行单元测试。虽然这个项目从属于jQuery,但却不依赖于jQuery,也不依赖于浏览器DOM。因此你也可以在node.js或Rhino上使用。QUnit很容易学习,你只需在html页面中包含两个文件,不需要安装或者构建任何其他东西。最短的测试集只需要一个11行的html文件。

特点: 1.使用方便,界面美观 2.支持异步 3.手工加载 4.对html文件有约束 4.适合开发调试阶段使用

Page 4: Js 单元测试框架介绍

Davis Frank: Jasmine是一个 JavaScript测试框架,目的是将BDD风格引入JavaScript测试之中。至于区别嘛,我们的目标是BDD(相比标准的TDD),因此我们尽 力帮助开发人员编写比一般xUnit框架表达性更强,组织更好的代码。此外我们还力图减少依赖,这样你可以在node.js上使用Jasmine,也可以在浏览器或移动程序中使用。

特点: 1.语法简洁,describe ,it 2.Browsers,servers,phones,etc 3.支持自定义Matchers 4.beforeEach()、afterEach()、Single-spec After functions 5.spies,mock 6.异步,runs(),waits(),waitsFor()

Page 5: Js 单元测试框架介绍

YUI Test features: Rapid creation of test cases through simple syntax. Advanced failure detection for methods that throw errors. Grouping of related test cases using test suites. Mock objects for writing tests without external dependencies. Asynchronous tests for testing events and Ajax communication. DOM Event simulation in all A-grade browsers (through Event).

Page 6: Js 单元测试框架介绍

YUITest Standalone Library

<script src="http://192.168.194.159/test/yuitest/yuitest.js"></script>

引入测试框架

YUI Test for YUI 3.x <script src="http://192.168.194.159/test/yui/build/yui/yui.js"></script> // Create a new YUI instance and populate it with the required modules. YUI().use('test', function (Y) { // Test is available and ready for use. Add implementation // code here. });

Page 7: Js 单元测试框架介绍

Using Test Cases

YUITest Standalone Library var testCase = new YUITest.TestCase({ name: "TestCase Name", //traditional test names testSomething : function () { //... }, testSomethingElse : function () { //... } });

var testCase = new YUITest.TestCase({ name: "TestCase Name", //friendly test names "Something should happen here" : function () { //... }, "Something else should happen here" : function () { //... } });

Page 8: Js 单元测试框架介绍

Using Test Cases

YUI Test for YUI 3.x var testCase = new Y.Test.Case({ name: "TestCase Name", //traditional test names testSomething : function () { //... }, testSomethingElse : function () { //... } });

var testCase = new Y.Test.Case({ name: "TestCase Name", //friendly test names "Something should happen here" : function () { //... }, "Something else should happen here" : function () { //... } });

Page 9: Js 单元测试框架介绍

setUp() and tearDown()

var testCase = new YUITest.TestCase({ name: "TestCase Name", //--------------------------------------------- // Setup and tear down //--------------------------------------------- setUp : function () { this.data = { name : "Nicholas", age : 28 }; }, tearDown : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YUITest.Assert.areEqual(28, this.data.age, "Age should be 28"); } });

Page 10: Js 单元测试框架介绍

init() and destroy()

var testCase = new YUITest.TestCase({ name: "TestCase Name", //--------------------------------------------- // init and destroy //--------------------------------------------- init : function () { this.data = { name : "Nicholas", age : 28 }; }, destroy : function () { delete this.data; }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YUITest.Assert.areEqual(28, this.data.age, "Age should be 28"); } });

Page 11: Js 单元测试框架介绍

Ignoring Tests

var testCase = new YUITest.TestCase({ name: "TestCase Name", //--------------------------------------------- // Special instructions //--------------------------------------------- _should: { ignore: { testName: true //ignore this test } }, //--------------------------------------------- // Tests //--------------------------------------------- testName: function () { YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); }, testAge: function () { YUITest.Assert.areEqual(28, this.data.age, "Age should be 28"); } });

Page 12: Js 单元测试框架介绍

Intentional Errors

testGenericError : function() { YUITest.Assert.throwsError(Error, function() { throw new Error("Generic error"); }); }, testStringError : function() { YUITest.Assert.throwsError("I'm a specific error message.", function() { throw new Error("I'm a specific error message."); }); }, testObjectError : function() { YUITest.Assert.throwsError(new TypeError("Number expected."), function() { throw new TypeError("Number expected."); }); },

Page 13: Js 单元测试框架介绍

Assertions

Equality Assertions areEqual() areNotEqual()

Sameness Assertions areNotSame() areSame()

Data Type Assertions isArray() isBoolean() isFunction() isNumber() isObject() isString() isTypeOf()

Special Value Assertions isFalse() isTrue() isNaN() isNotNaN() isNull() isNotNull() isUndefined() isNotUndefined()

Forced Failures fail()

Page 14: Js 单元测试框架介绍

ArrayAssert

contains() containsItems() containsMatch() doesNotContain() doesNotContainItems() doesNotContainMatch() indexOf() isEmpty() isNotEmpty() itemsAreEqual() itemsAreEquivalent() itemsAreSame() lastIndexOf()

Page 15: Js 单元测试框架介绍

DateAssert

datesAreEqual() timesAreEqual()

Page 16: Js 单元测试框架介绍

ObjectAssert

hasKey() hasKeys() ownsKey() ownsKeys() ownsNoKeys() areEqual() inheritsKey() inheritsKeys() ownsOrInheritsKey() ownsOrInheritsKeys()

Page 17: Js 单元测试框架介绍

Mock Objects

//code being tested function logToServer(message, xhr){ xhr.open("get", "/log.php?msg=" + encodeURIComponent(message), true); xhr.send(null); } //test case for testing the above function var testCase = new YUITest.TestCase({ name: "logToServer Tests", testPassingDataToXhr : function () { var mockXhr = YUITest.Mock(); //I expect the open() method to be called with the given arguments YUITest.Mock.expect(mockXhr, { method: "open", args: ["get", "/log.php?msg=hi", true] }); //I expect the send() method to be called with the given arguments YUITest.Mock.expect(mockXhr, { method: "send", args: [null] }); //now call the function logToServer("hi", mockXhr); //verify the expectations were met YUITest.Mock.verify(mockXhr); } });

Page 18: Js 单元测试框架介绍

Special Argument Values

YUITest.Mock.Value.Any - any value is valid regardless of type. YUITest.Mock.Value.String - any string value is valid. YUITest.Mock.Value.Number - any number value is valid. YUITest.Mock.Value.Boolean - any Boolean value is valid. YUITest.Mock.Value.Object - any non-null object value is valid. YUITest.Mock.Value.Function - any function value is valid.

YUITest.Mock.expect(mockXhr, { method: "open", args: [YUITest.Mock.Value.String, "/log.php?msg=hi“, YUITest.Mock.Value.Boolean] });

Page 19: Js 单元测试框架介绍

Property Expectations

var testCase = new YUITest.TestCase({ name : "TestCase Name", testMock : function() { var mockMyObject = YUITest.Mock(); YUITest.Mock.expect(mockMyObject,{ method: "add", args: [1,2], returns: 3, property: "status", value: 404 }); var result = mockMyObject.add(1,2); mockMyObject.status = 100; Assert.areEqual(3,result,"1 + 2 = 3"); YUITest.Mock.verify(mockMyObject); } });

Page 20: Js 单元测试框架介绍

Asynchronous Tests

var testCase = new YUITest.TestCase({ name: "TestCase Name", setUp : function () { this.data = { name : "Nicholas", age : 29 }; }, tearDown : function () { delete this.data; }, testAsync: function () { YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'"); //wait 1000 milliseconds and then run this function this.wait(function(){ YUITest.Assert.areEqual(29, this.data.age, "Age should be 29"); }, 1000); } });

Page 21: Js 单元测试框架介绍

Asynchronous Tests

var testCase = new YUITest.TestCase({ name: "TestCase Name", testAnimation : function (){ //animate width to 400px var myAnim = new Y.Anim({ node: '#testDiv', to: {width: 400}, duration: 3}); var test = this; //assign oncomplete handler myAnim.on("end", function(){ //tell the TestRunner to resume test.resume(function(){ YUITest.Assert.areEqual(myAnim.get("node").get("offsetWidth"), 400, "Width of the DIV should be 400."); }); }); //start the animation myAnim.run(); //wait until something happens this.wait(3000); } });

Page 22: Js 单元测试框架介绍

Test Suites

//create the test suite var suite = new YUITest.TestSuite("TestSuite Name"); //add test cases suite.add(new YUITest.TestCase({ //... })); suite.add(new YUITest.TestCase({ //... })); //add the second suite to the first suite.add(anotherSuite);

//create a test suite var suite = new YUITest.TestSuite({ name : "TestSuite Name", setUp : function () { //test-suite-level setup }, tearDown: function () { //test-suite-level teardown } });

Page 23: Js 单元测试框架介绍

Context Data var testSuite = new YUITest.TestSuite({ name: "Test Suite Name", setUp: function(data){ data.topLevel = 1;} }); testSuite.add(new YUITest.TestCase({ name: "First Test Case", init: function(data){ data.foo = "bar";}, testValueOfFoo : function (data) { YUITest.Assert.areEqual("bar", data.foo); //from init }, testValueOfTopLevel: function(data){ YUITest.Assert.areEqual(1, data.topLevel); //from test suite } }); testSuite.add(new YUITest.TestCase({ name: "Second Test Case", testValueOfFoo : function (data) { YUITest.Assert.areEqual("bar", data.foo); //from init in First Test Case }, testValueOfTopLevel: function(data){ YUITest.Assert.areEqual(1, data.topLevel); //from test suite } });

Page 24: Js 单元测试框架介绍

Running Tests

//add the test cases and suites YUITest.TestRunner.add(testCase); YUITest.TestRunner.add(testSuite); //run all tests YUITest.TestRunner.run(); YUITest.TestRunner.clear();

Page 25: Js 单元测试框架介绍

TestRunner Events

Test-Level Events

YUITest.TestRunner.TEST_PASS_EVENT - occurs when the test passes.

YUITest.TestRunner.TEST_FAIL_EVENT - occurs when the test fails.

YUITest.TestRunner.TEST_IGNORE_EVENT - occurs when a test is ignored.

For each of these events, the event data object has three properties:

type - indicates the type of event that occurred.

testCase - the test case that is currently being run.

testName - the name of the test that was just executed or ignored.

Page 26: Js 单元测试框架介绍

TestRunner Events

TestCase-Level Events

YUITest.TestRunner.TEST_CASE_BEGIN_EVENT occurs when the test case is next to be executed but before the first test is run.

YUITest.TestRunner.TEST_CASE_COMPLETE_EVENT

occurs when all tests in the test case have been executed or ignored.

For these two events, the event data object has three properties:

type - indicates the type of event that occurred.

testCase - the test case that is currently being run.

Page 27: Js 单元测试框架介绍

TestRunner Events

TestSuite-Level Events

YUITest.TestRunner.TEST_SUITE_BEGIN_EVENT occurs when the test suite is next to be executed but before the first test is run.

YUITest.TestRunner.TEST_SUITE_COMPLETE_EVENT occurs when all tests in all test cases in the test suite have been executed or ignored.

For these two events, the event data object has three properties:

type - indicates the type of event that occurred.

testSuite - the test suite that is currently being run.

Page 28: Js 单元测试框架介绍

TestRunner Events

TestRunner-Level Events

YUITest.TestRunner.BEGIN_EVENT occurs when testing is about to begin but before any tests are run.

YUITest.TestRunner.COMPLETE_EVENT occurs when all tests in all test cases and test suites have been executed or ignored.

Subscribing to Events function handleTestFail(data){ alert("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); } var TestRunner = YUITest.TestRunner; TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestFail); TestRunner.run();

Page 29: Js 单元测试框架介绍

Viewing Results

YUI({ logInclude: { TestRunner: true } }).use("console", function(Y){ //tests go here //initialize the console var yconsole = new Y.Console({ newestOnTop: false }); yconsole.render('#log'); //run the tests YUITest.TestRunner.run(); });

Page 30: Js 单元测试框架介绍

Viewing Results

YUI({ useBrowserConsole: true }).use("test", function(Y){ //tests go here Y.Test.Runner.run(); });

Page 31: Js 单元测试框架介绍

Viewing Results

YUI({ useBrowserConsole: true }).use("test", function(Y){ //tests go here //get object of results var resultsObject = YUITest.TestRunner.getResult(); //get XML results var resultsXML = YUITest.TestRunner.getResult(YUITest.TestFormat.XML); });

YUITest.TestFormat.XML - YUI Test XML (default) YUITest.TestFormat.JSON - JSON YUITest.TestFormat.JUnitXML - JUnit XML YUITest.TestFormat.TAP - TAP

Page 32: Js 单元测试框架介绍

Code Coverage Data

YUITest.TestRunner.getCoverage()

YUITest.CoverageFormat.JSON - JSON YUITest.CoverageFormat.XdebugJSON - JSON formatted Xdebug

Page 33: Js 单元测试框架介绍

Test Reporting

var reporter = new YUITest.Reporter("http://www.yourserver.com/path/to/target", YUITest.TestFormat.JSON); reporter.report(results);

results - the serialized results object. useragent - the user-agent string of the browser. timestamp - the date and time that the report was sent.

reporter.addField("color", "blue"); reporter.addField("message", "Hello world!");

Page 34: Js 单元测试框架介绍

Yeti: YUI’s Easy Testing Interface Yeti is a command-line tool for launching JavaScript unit tests in a browser and reporting the results without leaving your terminal. Yeti is designed to work with existing unmodified YUI-based tests. Yeti is designed to help you run tests before you commit. It compliments existing CI tools like Selenium and Hudson which run tests post-commit. Yeti is not a replacement for those tools.

Page 35: Js 单元测试框架介绍

More Info

http://docs.jquery.com/Qunit http://pivotal.github.com/jasmine/ http://developer.yahoo.com/yui/ http://yuilibrary.com/projects/yuitest http://yuilibrary.com/yui/docs/test/ http://yuilibrary.com/theater/ http://yuilibrary.com/projects/yeti/ http://192.168.194.159/test/slide/yeti.html