【大前端攻城狮之路·二】Javascript&QA?程师

  今天给大家分享的主题的是Javascript&QA?程师。看到这个主题,可能有人问:前端开发完就OK了,剩下的丢给测试就行,哪里还需要关心这些?但事实上呢,测试是前端开发非常重要的环节,也是迈向高级前端工程师的必经之路!

  本文主要分为一下四个部分:

  · 单元测试

  · 性能测试

  · 功能测试

  · 安全测试

  一. 单元测试

  单元测试(unit testing),是指对程序中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

  在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在像C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。

  经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。

  对于前端来说就是一个函数。

  (1)前端为什么要做单元测试?

  我认为主要原因为一下5点:

  1.正确性

  测试可以验证代码的正确性,在上线前做到心里有底。

  2.自动化

  当然手工也可以测试,通过console可以打印出内部信息,但是这是一次性的事情,下次测试还需要从头来过,效率不能得到保证。通过编写测试用例,可以做到一次编写,多次运行。

  3.解释性

  测试用例用于测试接口、模块的重要性,那么在测试用例中就会涉及如何使用这些API。其他开发人员如果要使用这些API,那阅读测试用例是一种很好地途径,有时比文档说明更清晰。

  4.驱动开发,指导设计

   代码被测试的前提是代码本身的可测试性,那么要保证代码的可测试性,就需要在开发中注意API的设计,TDD将测试前移就是起到这么一个作用。

  5.保证重构

  互联网行业产品迭代速度很快,迭代后必然存在代码重构的过程,那怎么才能保证重构后代码的质量呢?有测试用例做后盾,就可以大胆的进行重构。

  (2)单元测试原则&测试风格

  单元测试的目的是为了让开发者明确的知道代码结果,原则有三点:单一职责,接口抽象,层次分离。而单元测试必备的东西是断言库,断言库是保证最小单元能否正常运行的检测方法。

  测试风格:测试驱动开发(Test-Driven Development,TDD)、(BehaviorDriven Development,BDD)行为驱动开发均是敏捷开发方法论。

  TDD关注所有的功能是否被实现(每一个功能都必须有对应的测试用例),suite配合test利用assert(‘tobi‘ == user.name);

  BDD关注整体行为是否符合整体预期,编写的每一行代码都有目的提供一个全面的测试用例集。expect/should,describe配合it利用自然语言expect(1).toEqual(fn())执行结果。

  

  (3)单元测试框架

  单元测试的主要框架:

  

  (3)单元测试运行流程

  

  每一个测试用例组通过 describe进行设置

  1.before单个测试用例(it)开始前
  2.beforeEach每一个测试用例开始前
  3.it定义测试用例 并利用断言库进行
  设置chai如:expect(x).to.equal(true);异步mocha。
  4.以上专业术语叫mock

  

  (4)自动化单元测试 karma

  Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma。Karma是一个让人感到非常神秘的名字,表示佛教中的缘分。这个名字和LOL中的扇子妈同名 - -,比较佛系。

  On the AngularJS team, we rely on testing and we always seek better tools to make our life easier. That‘s why we created Karma - a test runner that fits all our needs.

  Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具可用于测试所有主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其他代码编辑器一起使用。

  可以生成报告和单测覆盖率检查。

  Karma.conf.js

  

// Karma configuration
// Generated on Thu Mar 22 2018 20:30:24 GMT+0800 (CST)

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
    files: [
      ‘./unit/**/*.js‘,
      ‘./unit/**/*.spec.js‘
    ],

    // list of files / patterns to exclude
    exclude: [
    ],
    //指定对应的JS文件 去执行代码的覆盖率
    preprocessors: {
      ‘./unit/**/*.js‘: [‘coverage‘]
    },

    // test results reporter to use
    // possible values: ‘dots‘, ‘progress‘
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: [‘progress‘, ‘coverage‘],
    coverageReporter: {
      type : ‘html‘,
      dir : ‘coverage/‘
    },
    // 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
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: [‘PhantomJS‘],

    //黑窗小独立的运行环境
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

  单元测试demo:

// index.js
window.test = function (num) {
    if(num == 1){
        return 1
    }else{
        return num + 1;
    }
}

// index.spec.js
describe("测试基本的函数API",function(){
    it("+1函数的应用",function(){
        expect(window.test(1)).toBe(1);
    });
});

  

  二. 功能测试

  功能测试主要是e2e测试。端到端测试是一种用于测试应用程序的流程是否从开始到结束执行的方法。执行端到端测试的目的是识别系统依赖性,并确保在各种系统组件和系统之间传递正确的信息。

  通俗点说,就是把整个系统当作一个黑盒,测试人员模拟真实用户在浏览器中操作UI来测试。

  常见的几种e2e测试框架,今天主要讲selenium,因为phantomjs,无头浏览器不在维护,所以rize与其形成犄角之势。可以在终端进行端对端测试。
  Nightwatch是一个功能非常强大,配置巨复杂的端对端测试框架,vue-cli就是用的night watch。

  (1)Selenium

  Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

  Selenium是ThoughtWorks公司的一个强大的开源Web功能测试工具系列,采用Javascript来管理整个测试过程,包括读入测试套件、执行测试和记录测试结果。它采用Javascript单元测试工具JSUnit为核心,模拟真实用户操作,包括浏览页面、点击链接、输入文字、提交表单、触发鼠标事件等等,并且能够对页面结果进行种种验证。也就是说,只要在测试用例中把预期的用户行为与结果都描述出来,我们就得到了一个可以自动化运行的功能测试套件。(Selenium的核心是Javascript写的,他和浏览器进行通信,把测试用例的信息发送给浏览器执行,从而达到自动化测试的目的。)

  我这里是用火狐测试的,需要先下载一个driver,geckdriver。然后nmp i selenium-webdriver --save;

  这里用代码控制打开火狐,找到name为‘wd’的元素并键入‘node’,然后按会车,最后退出火狐。代码如下:

  

const {Builder, By, Key, until} = require(‘selenium-webdriver‘);

(async function example() {
  let driver = await new Builder().forBrowser(‘firefox‘).build();
  try {
    await driver.get(‘https://www.baidu.com/‘);
    await driver.findElement(By.name(‘wd‘)).sendKeys(‘node‘, Key.RETURN);
    await driver.wait(until.titleIs(‘node_百度搜索‘), 1000);
  } finally {
    await driver.quit();
  }
})();

  

  使用rize框架,写法更为简洁:

const Rize = require(‘rize‘);
const rize = new Rize();
rize
  .goto(‘https://github.com/‘)
  .type(‘input.header-search-input‘, ‘node‘)
  .press(‘Enter‘)
  .waitForNavigation()
  .assertSee(‘Node.js‘)
  .end();

  

  三. UI测试

  前端,作为一个传统的页面仔,自己写的样式,心里得有点B数,不能老等着人家UI走查,说你哪哪差几像素。

  这里给大家介绍一个神奇的框架 BackstopJs。

  BackstopJS automates visual regression testing of your responsive web UI by comparing DOM screenshots over time.

  

    

  Backstop配置文件,backstop.json。

  

{
  "id": "天骄",
  "viewports": [
    {
      "label": "phone",
      "width": 375,
      "height": 667
    },
    {
      "label": "tablet",
      "width": 1024,
      "height": 768
    }
  ],
  "onBeforeScript": "chromy/onBefore.js",
  "onReadyScript": "chromy/onReady.js",
  "scenarios": [
    {
      "label": "qq",
      "cookiePath": "backstop_data/engine_scripts/cookies.json",
      "url": "http://map.qq.com/m/", // 这里是待测试的UI界面URL
      "referenceUrl": "",
      "readyEvent": "",
      "readySelector": "",
      "delay": 0,
      "hideSelectors": [],
      "removeSelectors": [],
      "hoverSelector": "",
      "clickSelector": "",
      "postInteractionWait": "",
      "selectors": [],
      "selectorExpansion": true,
      "misMatchThreshold" : 0.1,
      "requireSameDimensions": true
    }
  ],
  "paths": {
    "bitmaps_reference": "backstop_data/bitmaps_reference",
    "bitmaps_test": "backstop_data/bitmaps_test", // 这里放UI的设计图
    "engine_scripts": "backstop_data/engine_scripts",
    "html_report": "backstop_data/html_report",
    "ci_report": "backstop_data/ci_report"
  },
  "report": ["browser"], // 报表的方式,这里是浏览器
  "engine": "chrome",
  "engineFlags": [],
  "asyncCaptureLimit": 5,
  "asyncCompareLimit": 50,
  "debug": false,
  "debugWindow": false
}

  测试的结果页面非常友好,她会把你的界面和UI图的差异标注出来:

  

  三. 性能测试  

  下面说下性能测试。

  前端性能主要分为两部分,第一是页面性能,如秒开率等,第二是代码性能。今天主要说代码性能。

  今天主要讲代码性能测试 benchmarkjs,A benchmarking library that supports high-resolution timers & returns statistically significant results

  字面意思理解,支持高分辨率计时器的基准测试库,并返回统计上显著的结果。

  面向切面编程AOP无侵入式统计。Benchmark基准测试方法,它并不是简单地统计 执行多少次测试代码后对比时间,它对测试有着 严密的抽样过程。执行多少次取决于采样到的数 据能否完成统计。根据统计次数计算方差。

话不多说,直接看代码:

  

var Benchmark = require(‘benchmark‘);
var suite = new Benchmark.Suite;
suite.add(‘使用正则匹配字符串‘, function() {
    /o/.test(‘Hello World!‘);
  })
  .add(‘使用字符串查找‘, function() {
    ‘Hello World!‘.indexOf(‘o‘) > -1;
  })
  //添加监听
  .on(‘cycle‘, function(event) {
    console.log(String(event.target));
  })
  //执行结果
  .on(‘complete‘, function() {
    console.log(‘更快的是-》 ‘ + this.filter(‘fastest‘).map(‘name‘));
  })
  // run async
  .run({ ‘async‘: true });

  执行结果如下:

  

  

  下面说下 压力测试

  对网络接口做压力测试需要检查的几个常用指标有吞吐率、响应时间和并发数,这些指标反映了服务器并发处理能力。

  PV网站当日访问人数 UV独立访问人数。PV每天几十万甚至上百万就 需要考虑压力测试。换算公式QPS=PV/t ps:1000000/ 10*60*60=27.7(100万请求集中在10个小时,服务器每秒处理27.7 个业务请求);

  ab -c 100 -n 100 http://localhost:8001 每秒持续发出28个请求。? Request per second 表示服务器每秒处理请求数 即为QPS?。Failed requests 表示此次请求失败的请求数 理论上压测值越大增加? Connection Times 连接时间,它包括客户端向服务器端建立连接、服 务器端处理请求、等待报文响应的过程。

  常用的压力测试工具是ab、siege、http_load。

  四. 安全测试

  常见的安全攻击有三种:XSS, CSRF, SQL注入。

  (1)XSS 跨站点脚本攻击

  在input中输入未闭合标签,测试是否会执行。

><scrīpt>alert(document.cookie)</scrīpt>

  (2)CSRF,Sql注入。

  Sql注入。 ‘ or 1=1- -

  (3)Csrf跨站请求伪造
  这是一个cookies漏洞(身份验证),用户访问了危险网站B后,B会访问偷偷的让用户访问正规网站A。正规网站对身份进行校验后(通过cookies)认为这是同一个用户,则进行操作
目前没找到什么好的测试方法。

  总结:前段时间很多前端名人的博客网站都被攻击了,很多人吐槽前端天花板低,所以学习一门后台语言对我们前端开发人员对思维培养至关重要。而是否能写好单测非常重要。这也是我们迈向高级前端工程师的必经之路。

  最后我想说一句话:不懂测试的UI不是好前端;不懂后台的产品不是好前端。前端路漫漫,吾将上下而求索。

原文地址:https://www.cnblogs.com/tjyoung/p/9581027.html

时间: 2024-10-05 23:26:47

【大前端攻城狮之路·二】Javascript&QA?程师的相关文章

java攻城狮之路--复习JDBC

1.JDBC中如何获取数据库链接Connection? Driver 是一个接口: 数据库厂商必须提供实现的接口. 能从其中获取数据库连接. 可以通过 Driver 的实现类对象获取数据库连接. 1. 加入 mysql 驱动 1). 解压 mysql-connector-java-5.1.7.zip 2). 在当前项目下新建 lib 目录 3). 把 mysql-connector-java-5.1.7-bin.jar 复制到 lib 目录下 4). 右键 build-path , add to

零基础前端攻城狮养成计划

本喵至今已经做了一年半的前端了,还不能自封前端大牛,但是也算是入门了~这段时间里,从一个测试实习生到写文案,到成为一枚前端实习并入职正式工作一年.对于前端知识来讲可以说是从0开始了~得到过大牛们指点,踩过很多坑,自己也在不断的摸索着,学习着,成长着. 先说说自己目前的技术能力,给想要入门前端的小白们一颗定心丸~ 现在自己差不多3个小时可以切出一个兼容PC端和移动端的活动页面:一个和后端有交互并有表单验证的功能基本上1天就可以完成:一个没有见过的插件,看看文档就可以愉快的使用了:自己亲手写过两个插

初级JavaWeb攻城狮面试指导(二)

一.Java面向对象必会知识点 Java的核心是面向对象编程,所有的java程序都是面向对象的.需要看清Java的本质,从复杂的表象中寻找普遍的规律,并深刻理解Java的核心思想. 1.面向对象的特点总结 封装:隐藏在对象的属性和实现细节,仅对外提供公共的访问方式 继承:在一个类基础上定义一个新类,原有的类叫父类,新生成的类叫子类 多态:事物存在多种体现的形态 面向对象程序设计的优点是:可重用性.可扩展性.可管理性 2.类与对象特性总结 类与对象的概念: 类是具体事物的抽象,在概念上的定义 对象

java攻城狮之路(Android篇)--Activity生命

1 写一个类 extends Activity Activity是android的四大组件之一. Activity的激活分为显式意图激活和隐式意图激活. 如果一个activity希望别人隐式意图激活:则要配置过滤器1 action = ""2 有一个缺省的category,(可以有多个category),若不配置该类型会发生这样的一个错误:Caused by: android.content.ActivityNotFoundException: No Activity found to

java攻城狮之路--复习xml&amp;dom_pull编程

xml&dom_pull编程: 1.去掉欢迎弹窗界面:在window项的preferences选项中输入“configuration center” 找到这一项然后     把复选框勾去即可. 2.去掉打开Myeclipse时弹出的:Please allow Subclipse team to receive......办法: Windows-->Preferences-->General-->Startup and Shutdown-->取消Subclipse Usage

java攻城狮之路(Android篇)--BroadcastReceiver&amp;Service

四大组件:activity 显示. contentProvider 对外暴露自己的数据给其他的应用程序.BroadcastReceiver 广播接收者,必须指定要接收的广播类型.必须明确的指定actionservice 服务,是运行后台,它是没有界面的.对某件事情进行监听. 一.广播:事件.普通广播: 是异步的.会广播接收者同时接收,不能被中断sendBroadcast()有序广播: 是同步的.会根据广播接收的优先级进行接收,是可以中断 短信到来广播 sendOrderBroadcast()-1

前端攻城狮学习笔记九:让你彻底弄清offset

很多初学者对于JavaScript中的offset.scroll.client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确. 图一 不知道大家看到这张图的第一感觉如何,反正我的感觉就是“这次第,怎一个乱字了得”. 既然我认为上图太多太乱,那么我就把offset.scroll.client分开说,希望能让大家彻底弄清楚,今天只说offset. 一.关于offset,我们要弄明白什么 w3中offset相关页面是:http://www.w

java攻城狮之路(Android篇)--ListView与ContentProvider

一.ListView 1.三种Adapter构建ListView ListView添加条目的时候, 可以使用setAdapter(ListAdapter)方法, 常用的ListAdapter有三种 BaseAdapter: 定义一个类继承BaseAdapter, 重写4个抽象方法, ListView的条目是由getView()方法构建出来的 SimpleAdapter: 创建SimpleAdapter对象时, 传入数据(List<Map<String, ?>>), 并指定数据的绑定

java攻城狮之路(Android篇)--与服务器交互

一.图片查看器和网页源码查看器 在输入地址的是不能输入127.0.0.1 或者是 localhost.ScrollView :可以看成一个滚轴 可以去包裹很多的控件在里面 练习1(图片查看器): package com.shellway.imagelooker; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedUR