// Karma configuration // Generated on Tue Nov 01 2016 14:17:00 GMT+0800 (中国标准时间)
module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '',
// frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser //需要加载入浏览器的js文件,包括基础的类库,被测试js文件和测试用例js文件 //如果需要测试angular代码,比如引入angular-mock.js,给angular代码进行mock。 //注意angular-mock的版本一定要和angular版本一致。可在cdn网站对应的angular版本列表中寻找 files: [ '../webapp/vender/jquery/jquery-1.10.2.min.js', '../webapp/vender/angular/angular.min.js', '../webapp/vender/angular/angular-ui-router.min.js', 'lib/angular-mocks.js', '../webapp/common/*.js', '../webapp/commont/template/*.html', 'tc/ut/**/*.js' ], // list of files to exclude exclude: [ //'../webapp/vender/**/*.js' ], // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter //这里定义输出的报告 //html对应karma-html-reporter组件,输出测试用例执行报告 //coverage对应karma-coverage组件,输出测试用例执行报告 reporters: ['progress', 'html', 'junit', 'coverage'], junitReporter: { // will be resolved to basePath (in the same way as files/exclude patterns) outputFile: 'report/ut/test-results.xml', suite: 'UT', useBrowserName: false }, htmlReporter: { outputDir: 'report/ut', reportName: 'result'//outputDir+reportName组成完整的输出报告格式,如没有定义,会自动生成浏览器+OS信息的文件夹,不方便读取报告 }, //定义需要统计覆盖率的文件 preprocessors: { '../webapp/common/*.js':'coverage', '../webapp/common/template/*.html': 'ng-html2js' }, coverageReporter: { type: 'html', //将覆盖率报告类型type设置为cobertura 或者 html subdir:'coverage', //dir+subdir组成完整的输出报告格式,如没有定义,会自动生成浏览器+OS信息的文件夹,不方便读取报告 dir: 'report/ut/'//代码覆盖率报告生成地址 }, // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes //karma自动自动监视被测试文件和测试用用例文件,如有修改,自动重新执行测试 autoWatch: true, // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits //上一个参数为true,本参数为false,,则自动监视才生效。否则执行完测试用例后自动退出 singleRun: true, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher //用来执行自动监听的浏览器,推荐chrome browsers: ['Chrome'], // Concurrency level // how many browser should be started simultaneous concurrency: Infinity, //自动将模板文件路径转换页面引入路径,以便注入用例中 ngHtml2JsPreprocessor: { cacheIdFromPath: function(filepath) { var cacheId = filepath.substr(filepath.lastIndexOf('/webapp/')+7); // console.log(cacheId); return cacheId; }, moduleName: 'template' } }) } ``` 3. 保存配置文件到测试目录 ### 测试用例编写 #### 1、用例怎么写 ```javascript describe("A suite of Common/common.js", function() { beforeAll(function(){ console.log('beforeAll'); }); describe("extends of String", function() { var expected; beforeEach(function(){ expected = 'abcd'; }); it("trim",function(){ expect(expected).toEqual((" abcd ").trim()); }); it("ltrim",function(){ expect(expected).toEqual((" abcd").ltrim()); }); it("rtrim",function(){ expect(expected).toEqual(("abcd ").rtrim()); }); }); });
上述例子中, a. describe相当于一个测试套,可以嵌套。 b. it(‘tc name’,function(){})是一个测试用例。 c. beforeAll和beforeEach是预置条件,前者一个测试套执行一次,后者每个测试用例执行一次。 d. 当然还会有afterAll和afterEach e. expect是断言
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。 Visual Studio Code (简称 VS Code / VSC) 是一款免费开源的现代化轻量级代码编辑器,支持几乎所有主流的开发语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性,支持插件扩展,并针对网页开发和云端应用开发做了优化。软件跨平台支持 Win、Mac 以及 Linux,运行流畅,可谓是微软的良心之作……
1、开始怀疑是jenkins没有权限,无法调用firefox,给jenkins配置为root权限。可以在脚本中增加 whoami 命令来打印当前用户名称。结果错误依然存在。 2、在在脚本里直接调用firefox,显示错误信息:Error: GDK_BACKEND does not match available displays。经查询,发现是调用firefox时没有传递display ID,导致firefox无法显示界面。 3、原因分析:由于CI服务器上调用jenkins使用的命令是:(java -jar /home/data/jenkins/jenkins.war&) 。此种方式调用jenkins,直接后台进行运行,没有分配显示资源,而且关闭命令窗口,程序依然可以正常执行。但是由于没有display ID,导致firefox无法运行。
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
//由于每次添加div后,长度增加,此循环是死循环 var divList= document.getElementByName('div'); for(var count = 0; count < divList.length; count++){ document.body.appendChild(document.createElement('div')); } //集合保存到变量,避免重复查询 for(var count = 0; count < document.getElementByName('div').length; count++){ //do something } var divList= document.getElementByName('div'); var len = divList.length var arr = toArray(divList); //toArray是自定义的函数,将集合转成array for(var count = 0; count < len; count++){ //do something }
注意:此方法会额外增加一次遍历操作,长度小的集合可能不会提升反而下降
局部变量替代
1 2 3 4 5 6 7 8 9
for(var i = 0; i < document.getElementsByTagName("a").length; i++){ document.getElementsByTagName("a")[i].class = 'active' } //改进后 var list = document.getElementsByTagName("a"); var len = list.length; for(var i = 0; i < len; i++){ list[i].class = 'active' }
getCumputedStyle()(currentStyle in IE) 执行这些属性和方法需要返回最新的布局信息,因此浏览器会执行渲染队列中的操作,已获得最新的布局信息。因此不需要避免频繁执行这些属性和方法。
最小化重排和重绘
为减少重排或者重绘,应该合并多次对DOM和样式的修改,然后一次性处理。
修改样式
1 2 3 4 5 6 7 8 9 10 11
//优化前,执行了三次重排。大部分现代浏览器进行了优化,可能只执行一次 var el = document.getElementById('mydiv'); el.style.borderLeft='1px'; el.style.borderRight='2px'; el.style.padding='5px'; //优化后,只执行一次 var el = document.getElementById('mydiv'); el.style.ccsText='border-left:1px;border-right:2px;padding:5px;'; //第二种优化方法 var el = document.getElementById('mydiv'); el.className='active';
function appendDataToElement(appendToElement, data) { var a, li; for (var i = 0, max = data.length; i < max; i++) { a = document.createElement('a'); a.href = data[i].url; a.appendChild(document.createTextNode(data[i].name)); li = document.createElement('li'); li.appendChild(a); appendToElement.appendChild(li); } }; //优化前,循环内N次重排 var ul = document.getElementById('mylist'); appendDataToElement(ul, data); //第一种,异常和显示 var ul = document.getElementById('mylist'); ul.style.display = 'none'; appendDataToElement(ul, data); ul.style.display = 'block'; //第二种,文档片段 var fragment = document.createDocumentFragment(); appendDataToElement(fragment, data); document.getElementById('mylist').appendChild(fragment); //第三种,元素替换 var old = document.getElementById('mylist'); var clone = old.cloneNode(true); appendDataToElement(clone, data); old.parentNode.replaceChild(clone, old);
关闭mysql:$ /etc/init.d/mysql stop
进入mysql安全模式: $ mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
设置root账号密码,允许root远程连接,开发所有权限:
mysql -u root
mysql> use mysql;
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root';
mysql> INSERT INTO mysql.user (Host,User,Password,ssl_cipher,x509_issuer,x509_subject) VALUES ('%','root',PASSWORD('newpassword'),"","","");
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'newpassword' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> quit