Angular ile Unit ve Arayüz Testi

Unit Testing
Yazılım sisteminin en küçük birimlerini test etmek için kullanılan bir yaklaşımdır.
Anguların bize sunmuş olduğu DI ve loose coupling sayesinde sistemi kolay bir şekilde test edebiliriz.
- Karma
- Jasmine
Sistemi test ederken kullanacağımız teknolojiler
Sistemi test ederken kullanacağımız alternatif teknolojiler
- Mocha
- Chai
- Phantom.js (Karma Alternatifi)
Karma

Angular unit testleri, Angular team tarafından geliştirilen komut bazlı bir araç olan karma-runner tarafından çalıştırılır.
Tek bir konfigürasyon dosyasıyla test ortamını oluşturabiliriz.
Karma.js çalıştırmak için bilgisayarınızda Node.js yüklü olmalıdır.
http://karma-runner.github.io/
Karma.conf.js ayarlanması
module.exports = function (config) {
config.set({
frameworks: ['jasmine'],
files: [
"Scripts/jquery-2.1.1.min.js",
"Scripts/jquery.validate*",
"Scripts/modernizr-*",
"Scripts/js/smartadmin.jquery.init.js",
"Scripts/js/plugin/datatables/jquery.dataTables.min.js",
"Scripts/js/plugin/datatables/dataTables.colVis.min.js",
"Scripts/js/plugin/datatables/dataTables.tableTools.min.js",
"Scripts/js/plugin/datatables/dataTables.bootstrap.min.js",
"Scripts/js/plugin/datatable-responsive/datatables.responsive.min.js",
"Scripts/js/datatables.init.js",
"Scripts/jquery.datetimepicker.js",
"Scripts/jquery-ui-1.10.3.min.js",
"Scripts/js/app.config.min.js",
"Scripts/js/plugin/jquery-touch/jquery.ui.touch-punch.min.js",
"Scripts/bootstrap.min.js",
"Scripts/js/notification/SmartNotification.min.js",
"Scripts/js/smartwidgets/jarvis.widget.min.js",
"Scripts/select2.min.js",
"Scripts/js/plugin/msie-fix/jquery.mb.browser.min.js",
"Scripts/js/plugin/fastclick/fastclick.min.js",
"Scripts/js/app.min.js",
"Scripts/lodash.underscore.min.js",
"Scripts/angular.js",
"Scripts/angular-mocks.js",
"Scripts/angular-datatables.min.js",
"Scripts/dataTables.columnFilter.js",
"Scripts/angular-datatables.columnfilter.min.js",
"Scripts/angular-animate.js",
"Scripts/angular-sanitize.js",
"Scripts/toaster.js",
"Scripts/angular-ui/ui-bootstrap.js",
"Scripts/angular-ui/ui-bootstrap-tpls.js",
"Scripts/angular-ui-router.js",
"Scripts/select.js",
"Scripts/angular-placeholders-0.0.1-SNAPSHOT.min.js",
"Scripts/angular-busy.js",
"Scripts/js/plugin/moment/moment.min.js",
"app/app.module.js",
"app/app.config.js",
"app/app.controller.js",
/*BLOCKS MODULE*/
"app/blocks/blocks.module.js",
"app/blocks/exception/exception.js",
"app/blocks/exception/exception-handler.js",
"app/blocks/exception/exception.service.js",
"app/blocks/logger/logger.js",
/*COMMON MODULE*/
"app/common/common.module.js",
"app/common/constants.js",
"app/common/storage.js",
"app/common/notification.service.js",
"app/common/dropdown-multiselect.directive.js",
"app/common/notification-popup.directive.js",
"app/common/smart-admin-adapter.js",
"app/common/datetimepicker.js",
"app/common/ng-file-upload-shim.js",
"app/common/ng-file-upload-all.js",
"app/common/dialogs.min.js",
/*HOME MODULE*/
"app/home/home.module.js",
"app/home/config.js",
"app/home/controller/home.controller.js",
/*CAMPAIGN MODULE*/
"app/campaign/campaign.module.js",
"app/campaign/config.js",
"app/campaign/service/campaign.service.js",
"app/campaign/controller/campaign.controller.js",
"app/campaign/controller/campaign.create.controller.js",
"app/campaign/controller/campaign.update.controller.js",
"app/campaign/controller/campaign.sample.controller.js",
"app/campaign/controller/campaign.upload.modal.controller.js",
"app/campaign/service/campaign.preparation.service.js",
"app/campaign/controller/campaign.preparation.controller.js",
"app/campaign/controller/campaign.repeat.controller.js",
"app/campaign/service/samplerequest.management.service.js",
"app/campaign/controller/campaign.samplerequest.management.controller.js",
"app/campaign/service/dataentry.service.js",
"app/campaign/controller/campaign.dataentry.controller.js",
/*MESSAGES MODULE*/
"app/messages/messages.module.js",
"app/messages/config.js",
"app/messages/service/messages.service.js",
"app/messages/directives/message-list.directive.js",
"app/messages/controller/messages.controller.js",
/*LOOKUP MODULE*/
"app/lookup/lookup.module.js",
"app/lookup/services/lookup.service.js",
"app/lookup/directives/businessunit-dropdown.directive.js",
"app/lookup/directives/salechannel-dropdown.directive.js",
"app/lookup/directives/webcategory-dropdown.directive.js",
"app/lookup/directives/buyingtype-dropdown.directive.js",
"app/test/*.spec.js"
],
// list of files to exclude
exclude: [
],
preprocessors: {
'app/test/**/*.spec.js': ['coverage']
},
coverageReporter: {
type: 'html',
dir: 'coverage/'
},
reporters: ['progress', 'coverage'],
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
//plugins: [
// 'karma-chrome-launcher',
// 'karma-firefox-launcher',
// 'karma-jasmine',
// 'karma-junit-reporter'
//],
//junitReporter: {
// outputFile: 'test_out/unit.xml',
// suite: 'unit'
//}
});
};
Jasmine yazılım süreçlerinin daha test odaklı gitmesini sağlayan bir javascript test kütüphanesidir. Herhangi başka bir kütüphaneye ihtiyaç duymadan testlerimizi kolaylıkla Jasmine ile geliştirebiliriz.

describe("Basit bir test suiti", function() {
it("Oluşturduğumuz test", function() {
expect(true).toBe(true);
});
});
beforeEach(function() {
//Her testten önce çalışacak işlemler
});
afterEach(function() {
//Her testten sonra çalışacak işlemler
});
Örnek bir test case oluşturulması.
Her testten önce ve sonra çalışacak işlemlerin tanımlanması.
https://github.com/jasmine/jasmine
Örnek bir servis testi oluşturulması
var campaignService, $httpBackend, appConfiguration, q;
beforeEach(function () {
module('oneAdminApp');
inject(function (_campaignService_, _$httpBackend_, _appConfiguration_, $q) {
campaignService = _campaignService_;
$httpBackend = _$httpBackend_;
q = $q;
appConfiguration = _appConfiguration_;
});
it('should be service instance loaded', function () {
expect(campaignService).toBeDefined();
});
Yüklenecek modüllerin sisteme bildirilmesi.
Örnek bir test case oluşturulması.
it('should be campaignService getCampaignProducts valid paramerters', function (done) {
var result = { campaignId: 1, campaignName: "SampleCampaign" };
$httpBackend.whenGET(appConfiguration.CampaignServiceEndpoint + "campaigns" + "/" + 1 + "/products").respond(result);
campaignService.getCampaignProducts(1).then(function (response) {
expect(response.campaignName).toEqual(result.campaignName);
done();
});
$httpBackend.flush();
});
$http mocklanması.
Örnek bir controller testi oluşturulması
var vm, createController, campaignService, dialogs, modal, scope;
beforeEach(function (done) {
module('oneAdminApp');
inject(function (_$httpBackend_, _$q_, $controller, $rootScope, _smartAdminAdapter_
, _DTOptionsBuilder_, _DTColumnDefBuilder_, _DTColumnBuilder_,
$modal, _logger_, _campaignService_, $dialogs, $window) {
campaignService = _campaignService_;
dialogs = $dialogs;
modal = $modal;
scope = $rootScope.$new();
createController = function () {
return $controller("CampaignCtrl", {
$httpBackend: _$httpBackend_,
$q: _$q_,
$scope: $rootScope.$new(),
smartAdminAdapter: _smartAdminAdapter_,
DTOptionsBuilder: _DTOptionsBuilder_,
DTColumnDefBuilder: _DTColumnDefBuilder_,
DTColumnBuilder: _DTColumnBuilder_,
$modal: $modal,
logger: _logger_,
campaignService: campaignService,
$dialogs: $dialogs,
$window: $window
});
};
done();
});
});
it('should be all campaign to have been called and defined', function () {
spyOn(campaignService, 'getAll').and.callFake(function () {
return {
then: function (callback) {
return callback();
}
};
});
Yüklenecek modüllerin sisteme bildirilmesi.
Örnek bir test case oluşturulması.
spyOn-kullandığımız sanal obje metotları oluşturur.
Testlerin Çalıştırılması
npm test
Bu komut sayesinde testlerimiz karma-runner üzerinde çalışacaktır.Ayrıca karma-runner dosya üzerindeki değişikleri izleyerek testleri yeniden çalıştıracaktır.
http://git-scm.com/
http://nodejs.org/
Gerekli Kurulumlar
E2E Testing
Büyük kapsamlı uygulamalarda sistemin birlikte çalışabildiğinide doğrulamak gereklidir. Bu gibi durumlarda sistemin bileşenleri ayrı ayrı test edildikten sonra bütünün istenildiği gibi çalıştığını belirlemek için end to end( uçtan uca) test gerçekleştirilir.
- Protractor
- Jasmine
Sistemi test ederken kullanacağımız teknolojiler ?
Angular e2e testleri, Selenium Web driver tarafından çalıştırılır. Gerekli testler yazıldıktan sonra proxy bir browser başlayarak,sistemin test edilmesi gözlenir.
Tek bir konfigürasyon dosyasıyla test ortamını oluşturabiliriz.
Protractor çalıştırmak için bilgisayarınızda Node.js yüklü olmalıdır.
https://github.com/angular/protractor


protractor.conf.js ayarlanması
exports.config = {
allScriptsTimeout: 11000,
specs: [
'*.js'
],
capabilities: {
'browserName': 'chrome'
},
baseUrl: 'http://localhost:8000/app/',
framework: 'jasmine2',
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
Burada hangi browser türünde çalışacak, hangi testler çalışacak ayarlarını yapmak mümkündür.
Örnek bir Ui test oluşturulması
beforeAll(function () {
browser.get('http://local.oneadmin.com/#/campaign');
});
it('should dataTable item greater than 0', function () {
var count = element.all(by.repeater('campaignItem in vm.campaigns'));
count.then(function (result) {
expect(result.length).toBeGreaterThan(1);
});
});
Testler başlamadan önce bir kere çalışacak fonksiyon
Table listesi 0 dan büyük olma testi
- Dom elementlerine mutlaka id veya class ataması yapılmalıdır.
- Sayfa içinde xPath ile elementleri bulma yöntemi en son çare olarak kullanılmalıdır.
- Sayfa içinde timeOut süreleri minumum düzeyde tutulmalıdır.
Testlerin Çalıştırılması
npm start
Protractor, testleri simüle edebilmesi için bir web server başlatıyoruz.
http://git-scm.com/
http://nodejs.org/
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Gerekli Kurulumlar
npm run protractor
komutuyla birlikte config ile belirtilen testlerimizi çalıştırıyoruz.
Angular ile Unit ve Arayüz Testi
By gökhan karadaş
Angular ile Unit ve Arayüz Testi
Angular ile test ortamları oluşturulması ve testlerin yazılması.
- 3,959