项目开发到后期,版本相对稳定,需要进行反复测试的情况下可以考虑启用自动化测试,但不能完全替代手工测试,自动化测试仅是减去测试人员反复测试的工作量.
npm install -g karma
npm install karma-qunit --save-dev
npm install karma-chrome-launcher --save-dev
JS:
.controller("defaultCtrl", function ($scope, $http, $interval, $timeout, $log) {
$scope.intervalCounter = 0;
$scope.timerCounter = 0;
$interval(function () {
$scope.intervalCounter++;
}, 5, 10);
$timeout(function () {
$scope.timerCounter++;
}, 5);
$scope.products=[];
$http.get("productData.json").success(function (data) {
$scope.products = data;
$log.log("There are " + data.length + " items");
});
$scope.counter = 0;
$scope.incrementCounter = function () {
$scope.counter++;
}
})
Controller Test:
describe("Controller Test", function () {
// Arrange
var mockScope, controller, backend, mockInterval, mockTimeout, mockLog;
//angular.mock用于创建模拟模块和解决依赖关系。
beforeEach(angular.mock.module("exampleApp"));
//测试前执行的函数
beforeEach(angular.mock.inject(function ($httpBackend) {//inject解决依赖关系注入到一个函数。
backend = $httpBackend;
backend.expect("GET", "productData.json").respond(//模拟Ajax
[{ "name": "Apples", "category": "Fruit", "price": 1.20 },
{ "name": "Bananas", "category": "Fruit", "price": 2.42 },
{ "name": "Pears", "category": "Fruit", "price": 2.02 }]);
}));
beforeEach(angular.mock.inject(function ($controller, $rootScope,
$http, $interval, $timeout, $log) {//依赖注入
mockScope = $rootScope.$new();//Creates a new scope
mockInterval = $interval;
mockTimeout = $timeout;
mockLog = $log;
//$controller(name) Creates an instance of the specified controller
$controller("defaultCtrl", {
$scope: mockScope,
$http: $http,
$interval: mockInterval,
$timeout: mockTimeout,
$log: mockLog
});
backend.flush();//解决$http承诺
}));
// Act and Assess
it("Creates variable", function () {
expect(mockScope.counter).toEqual(0);
})
it("Increments counter", function () {
mockScope.incrementCounter();
expect(mockScope.counter).toEqual(1);//判断值mockScope.counter==1?
});
it("Makes an Ajax request", function () {
backend.verifyNoOutstandingExpectation();
});
it("Processes the data", function () {
expect(mockScope.products).toBeDefined();
expect(mockScope.products.length).toEqual(3);
});
it("Preserves the data order", function () {
expect(mockScope.products[0].name).toEqual("Apples");
expect(mockScope.products[1].name).toEqual("Bananas");
expect(mockScope.products[2].name).toEqual("Pears");
});
it("Limits interval to 10 updates", function () {
for (var i = 0; i < 11; i++) {
mockInterval.flush(5000);
}
expect(mockScope.intervalCounter).toEqual(10);
});
it("Increments timer counter", function () {
mockTimeout.flush(5000);
expect(mockScope.timerCounter).toEqual(1);
});
it("Writes log messages", function () {
expect(mockLog.log.logs.length).toEqual(1);
});
});
JS:
.filter("labelCase", function () {
return function (value, reverse) {
if (angular.isString(value)) {
var intermediate = reverse ? value.toUpperCase() : value.toLowerCase();
return (reverse ? intermediate[0].toLowerCase() :
intermediate[0].toUpperCase()) + intermediate.substr(1);
} else {
return value;
}
};
})
Filter Tests:
describe("Filter Tests", function () {
var filterInstance;
beforeEach(angular.mock.module("exampleApp"));
beforeEach(angular.mock.inject(function ($filter) {
filterInstance = $filter("labelCase");
}));
it("Changes case", function () {
var result = filterInstance("test phrase");
expect(result).toEqual("Test phrase");
});
it("Reverse case", function () {
var result = filterInstance("test phrase", true);
expect(result).toEqual("tEST PHRASE");
});
});
js:
.directive("unorderedList", function () {
return function (scope, element, attrs) {
var data = scope[attrs["unorderedList"]];
if (angular.isArray(data)) {
var listElem = angular.element(""
);
element.append(listElem);
for (var i = 0; i < data.length; i++) {
listElem.append(angular.element('' ).text(data[i].name));
}
}
}
})
Directive Tests:
describe("Directive Tests", function () {
var mockScope;
var compileService;
beforeEach(angular.mock.module("exampleApp"));
beforeEach(angular.mock.inject(function ($rootScope, $compile) {
mockScope = $rootScope.$new();
compileService = $compile;
mockScope.data = [
{ name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },
{ name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },
{ name: "Pears", category: "Fruit", price: 2.02, expiry: 6 }];
}));
it("Generates list elements", function () {
var compileFn = compileService("");
var elem = compileFn(mockScope);
expect(elem.children("ul").length).toEqual(1);
expect(elem.find("li").length).toEqual(3);
expect(elem.find("li").eq(0).text()).toEqual("Apples");
expect(elem.find("li").eq(1).text()).toEqual("Bananas");
expect(elem.find("li").eq(2).text()).toEqual("Pears");
});
});
js:
.factory("counterService", function () {
var counter = 0;
return {
incrementCounter: function () {
counter++;
},
getCounter: function () {
return counter;
}
}
});
Service Tests
describe("Service Tests", function () {
beforeEach(angular.mock.module("exampleApp"));
it("Increments the counter", function () {
angular.mock.inject(function (counterService) {
expect(counterService.getCounter()).toEqual(0);
counterService.incrementCounter();
expect(counterService.getCounter()).toEqual(1);
});
});
});