发布新日志

  • pytest失败重试机制

    2020-07-02 09:19:25

    第一种:对所有用例使用

    1、安装:pip install pytest-rerunfailures
    2、命令行参数:pytest -- reruns 重试次数 (--reruns-delay 次数之间间隔)                   pytest --reruns 2 运行失败的用例可以执行2次                   pytest --reruns 2 --reruns-delay 5 运行失败的用例可以执行2次,每次间隔5秒 pytest.main(["-v","-m","demo","--reruns","2","--reruns-delay","5","--alluredir=../OutPuts/allure-results"]) pytest中的失败截图。
    第二种:只对部分用例使用重运行机制
    1、安装:pip install flaky

    在指定的用例使用装饰器 @pytest.mark.flaky(reruns=5, reruns_delay=2) def test_example():     import random     assert random.choice([True, False])
    reruns=5, reruns_delay=2:最多失败重跑5次 & 如果失败则延迟1秒后重跑(可以不传)
    @flaky(max_runs=3, min_passes=2):第一次执行失败了,将会再次重复执行它3次,如果这3次中有2次成功了,则认为这个测试通过了。
  • 云计算测试之-块存储基础知识-元数据

    2020-06-30 08:15:43

    1. 什么是元数据
             任何文件系统中的数据分为数据和元数据。数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息(inode...)等等。在集群文件系统中,分布信息包括文件在磁盘上的位置以及磁盘在集群中的位置。用户需要操作一个文件必须首先得到它的元数据,才能定位到文件的位置并且得到文件的内容或相关属性。

    2. 元数据管理方式
             元数据管理有两种方式。集中式管理和分布式管理。集中式管理是指在系统中有一个节点专门司职元数据管理,所有元数据都存储在该节点的存储设备上。所有客户端对文件的请求前,都要先对该元数据管理器请求元数据。分布式管理是指将元数据存放在系统的任意节点并且能动态的迁移。对元数据管理的职责也分布到各个不同的节点上。大多数集群文件系统都采用集中式的元数据管理。因为集中式管理实现简单,一致性维护容易,在一定的操作频繁度内可以提供较满意的性能。缺点是单一失效点问题,若该服务器失效,整个系统将无法正常工作。而且,当对元数据的操作过于频繁时,集中的元数据管理成为整个系统的性能瓶颈。
             分布式元数据管理的好处是解决了集中式管理的单一失效点问题, 而且性能不会随着操作频繁而出现瓶颈。其缺点是,实现复杂,一致性维护复杂,对性能有一定影响。

  • Bash 脚本 set 命令教程

    2020-06-28 08:01:12

    set命令是 Bash 脚本的重要环节,却常常被忽视,导致脚本的安全性和可维护性出问题。本文介绍它的基本用法,让你可以更安心地使用 Bash 脚本。

    一、简介

    我们知道,Bash 执行脚本的时候,会创建一个新的 Shell。

    
    $ bash script.sh
    

    上面代码中,script.sh是在一个新的 Shell 里面执行。这个 Shell 就是脚本的执行环境,Bash 默认给定了这个环境的各种参数。

    set命令用来修改 Shell 环境的运行参数,也就是可以定制环境。一共有十几个参数可以定制,官方手册有完整清单,本文介绍其中最常用的四个。

    顺便提一下,如果命令行下不带任何参数,直接运行set,会显示所有的环境变量和 Shell 函数。

    
    $ set
    

    二、set -u

    执行脚本的时候,如果遇到不存在的变量,Bash 默认忽略它。

    
    #!/usr/bin/env bash
    
    echo $a
    echo bar
    

    上面代码中,$a是一个不存在的变量。执行结果如下。

    
    $ bash script.sh
    
    bar
    

    可以看到,echo $a输出了一个空行,Bash 忽略了不存在的$a,然后继续执行echo bar。大多数情况下,这不是开发者想要的行为,遇到变量不存在,脚本应该报错,而不是一声不响地往下执行。

    set -u就用来改变这种行为。脚本在头部加上它,遇到不存在的变量就会报错,并停止执行。

    
    #!/usr/bin/env bash
    set -u
    
    echo $a
    echo bar
    

    运行结果如下。

    
    $ bash script.sh
    bash: script.sh:4: a: 未绑定的变量
    

    可以看到,脚本报错了,并且不再执行后面的语句。

    -u还有另一种写法-o nounset,两者是等价的。

    
    set -o nounset
    

    三、set -x

    默认情况下,脚本执行后,屏幕只显示运行结果,没有其他内容。如果多个命令连续执行,它们的运行结果就会连续输出。有时会分不清,某一段内容是什么命令产生的。

    set -x用来在运行结果之前,先输出执行的那一行命令。

    
    #!/usr/bin/env bash
    set -x
    
    echo bar
    

    执行上面的脚本,结果如下。

    
    $ bash script.sh
    + echo bar
    bar
    

    可以看到,执行echo bar之前,该命令会先打印出来,行首以+表示。这对于调试复杂的脚本是很有用的。

    -x还有另一种写法-o xtrace

    
    set -o xtrace
    

    四、Bash 的错误处理

    如果脚本里面有运行失败的命令(返回值非0),Bash 默认会继续执行后面的命令。

    
    #!/usr/bin/env bash
    
    foo
    echo bar
    

    上面脚本中,foo是一个不存在的命令,执行时会报错。但是,Bash 会忽略这个错误,继续往下执行。

    
    $ bash script.sh
    script.sh:3: foo: 未找到命令
    bar
    

    可以看到,Bash 只是显示有错误,并没有终止执行。

    这种行为很不利于脚本安全和除错。实际开发中,如果某个命令失败,往往需要脚本停止执行,防止错误累积。这时,一般采用下面的写法。

    
    command || exit 1
    

    上面的写法表示只要command有非零返回值,脚本就会停止执行。

    如果停止执行之前需要完成多个操作,就要采用下面三种写法。

    
    # 写法一
    command || { echo "command failed"; exit 1; }
    
    # 写法二
    if ! command; then echo "command failed"; exit 1; fi
    
    # 写法三
    command
    if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi
    

    另外,除了停止执行,还有一种情况。如果两个命令有继承关系,只有第一个命令成功了,才能继续执行第二个命令,那么就要采用下面的写法。

    
    command1 && command2
    

    五、 set -e

    上面这些写法多少有些麻烦,容易疏忽。set -e从根本上解决了这个问题,它使得脚本只要发生错误,就终止执行。

    
    #!/usr/bin/env bash
    set -e
    
    foo
    echo bar
    

    执行结果如下。

    
    $ bash script.sh
    script.sh:4: foo: 未找到命令
    

    可以看到,第4行执行失败以后,脚本就终止执行了。

    set -e根据返回值来判断,一个命令是否运行失败。但是,某些命令的非零返回值可能不表示失败,或者开发者希望在命令失败的情况下,脚本继续执行下去。这时可以暂时关闭set -e,该命令执行结束后,再重新打开set -e

    
    set +e
    command1
    command2
    set -e
    

    上面代码中,set +e表示关闭-e选项,set -e表示重新打开-e选项。

    还有一种方法是使用command || true,使得该命令即使执行失败,脚本也不会终止执行。

    
    #!/bin/bash
    set -e
    
    foo || true
    echo bar
    

    上面代码中,true使得这一行语句总是会执行成功,后面的echo bar会执行。

    -e还有另一种写法-o errexit

    
    set -o errexit
    

    六、set -o pipefail

    set -e有一个例外情况,就是不适用于管道命令。

    所谓管道命令,就是多个子命令通过管道运算符(|)组合成为一个大的命令。Bash 会把最后一个子命令的返回值,作为整个命令的返回值。也就是说,只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e就失效了。

    请看下面这个例子。

    
    #!/usr/bin/env bash
    set -e
    
    foo | echo a
    echo bar
    

    执行结果如下。

    
    $ bash script.sh
    a
    script.sh:4: foo: 未找到命令
    bar
    

    上面代码中,foo是一个不存在的命令,但是 查看(609) 评论(0) 收藏 分享 管理

  • 云计算测试之iaas技术原理(一)

    2020-06-23 09:24:25

    云计算架构原理

    通过虚拟化技术(如Vmware),可以把一个物理主机抽象成为多个虚拟主机,每个虚拟主机都拥有独立的CPU、内存、网络、存储等资源。如果在每个主机上安装分布式集成软件(如Hadoop),可以实现分布式计算和存储。Hadoop会让某个主机成为Master,让一系列主机成为Slave。如果需要存储一个文件,Master把文件分成若干片段,并把它存储在不同的Slave上。如果需要运行一个计算公式,Master会把计算公式分解,让不同的Slave进行运算。所以通过虚拟化技术和分布式技术,可以把计算机资源池化,实现弹性调配。

    云计算架构相对传统虚拟主机的优势

    1、安全性更高:在传统的虚拟主机架构下,多个虚拟机运行在一个物理机上,一旦这台物理机报废,所有的相关数据都报废了。但云计算架构可以在多个物理机抽象的主机上进行备份。

    2、资源利用效率更高:虚拟主机资源存在浪费,例如一个电商网站租用了2G的CPU、1TB的硬盘,那么这些资源从对应的物理机上永久地划分出来分配给这家电商。但云计算架构可以实现弹性地提供资源。

    虚拟化技术市场的格局

    主要是四种产品,Vmware、HyperV、Xen、KVM,其中Vmware占有86%的市场份额。HyperV 是微软的产品,市场占有率8%。VXen是Citix的产品,是开源的,市场占有率很小。KVM 是linux内核本身一部分,也是开源的。

    分布式集成技术市场的格局

    主要是两种产品:Google的分布式系统、Hadoop的分布式系统。Hadoop是Apache公司的开源产品。

    Iaas的商业模式

    一般来说,Iaas的商业模式是先购买硬件,再通过云计算架构技术进行改造,然后把计算和存储资源租用出去。商业模式类似租车业务。Iaas起源于Amazon,但现在主要是拥有大量服务器和机房资源的传统IDC厂家在做。Iaas一般是重资产投资,使用的技术是成熟技术,产品和服务比较同质化。

  • 云计算测试之-网络管理器NetworkManager

    2020-06-23 09:00:36

    网络管理器(NetworManager)是检测网络、自动连接网络的程序。无论是无线还是有线连接,它都可以令您轻松管理。对于无线网络,网络管理器优先连接已知的网络并可以自动切换到最可靠的无线网络。利用网络管理器的程序可以自由切换在线和离线模式。网络管理器会相对无线网络优先选择有线网络,支持 VPN。网络管理器最初由 Redhat 公司开发,现在由 GNOME 管理。

    NetworkManager由一个管理系统网络连接、并且将其状态通过D-BUS(是一个提供简单的应用程序 互相通讯的途径的自由软件项目,它是作为freedesktoporg项目的一部分来开发的。)进行报告的后台服务,以及一个允许用户管理网络连接的客户端程序。

    networkmanager提供了命令行工具-nmcli ,包括在networkmanager中。

    ubuntu安装:

    1. sudo apt --fix-broken install

    2.sudo apt install network-manager

    重启

    # service dbus restart
    # service network-manager restart

    链接WiFi网络:

    nmcli dev wifi connectpassword

    通过wlan1接口连接 WiFi 网络:

    nmcli dev wifi connectpasswordiface wlan1 [profile name]

    断开一个接口:

    nmcli dev disconnect iface eth0

    重新连接一个标记为已断开的接口:

    nmcli con up uuid

    获得 UUID 列表:

    nmcli con show

    查看网络设备及其状态列表:

    nmcli dev

    关闭 WiFi:

    nmcli r wifi off


    在systemd里面,可以直接使用systemctl进行管理

    启动:systemctl start NetworkManger

    关闭:systemctl stop NetworkManager

    开机启动:systemctl enable NetworkManger

    查看是否开机启动:systemctl is-enabled NetworkManager

    禁用开机启动:systemctl disable NetworkManager

    在CentOS6里面就有这个服务,可以用service和chkconfig里面进行管理:

    启动:service NetworkManager start

    关闭:service NetworkManager stop

    开机启动:chkconfig NetworkManager on

    禁用开机启动:chkconfig NetworkManager off

  • 云计算测试之防火墙和iptables

    2020-06-21 19:54:05

    从逻辑上讲。防火墙可以大体分为主机防火墙和网络防火墙。

    主机防火墙:针对于单个主机进行防护。

    网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网。

    网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)。

     

    从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。

    硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。

    软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。

    iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的"安全框架"中,这个"安全框架"才是真正的防火墙,这个框架的名字叫netfilter

    netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。

    iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。


    1.ubuntu下安装iptables
    sudo apt-get install iptables*
    2.启动防火墙
    service iptables start
  • 接口自动化测试平台

    2020-03-10 13:01:04

    接口自动化测试平台,免费**地址:test.ironz.com
  • 支持案例自动生成的接口测试平台

    2020-03-01 12:38:54

    IRON TEST支持接口类型丰富、案例自动生成、案例管理,定时回归执行,测试报告自动发送功能。地址:test.ironz.com
  • 为什么接口自动化测试的投入产出比最高,收益最大?

    2019-09-12 13:22:50

           测试的边际成本会随着缺陷发现率的提高而提高,这一规律也适用于自动化测试,在自动化测试金字塔模式中提到的3种自动化测试类型,(UI、接口测试、单元测试)随着自动化覆盖率的提升,自动化的成本也呈现指数式上升。按照这个思路进行拓展,可以得出单元测试,接口测试和UI测试的自动化测试,在相同的自动化率前提下,UI的成本最高、其次是API,Unit则最低。


           经济学中有另外一个著名的理论叫做边际效益递减。当做一项投资,随着投资量的增加,单位投资增量所带来的单位收益是越来越少的,甚至在某个临界点之后,这个收益有可能是负数。而这个零界点,就是投资收益最大的点。在这个点之前的所有投资,都可以扩大总收益,而在超过之后继续进行投资,就不那么明智了。

        按照这个思路,针对三种不同类型的自动化测试,可以获得三个零界点。而总收益最大的点在接口测试上,随后是单元测试,UI测试则最低。
      如果从测试效果上看,接口测试和UI/单元测试相比,有很多优势。 对于单元测试来说,通常单元测试是针对代码进行的测试,而接口测试是在测试一个活的,经过部署的系统。 另外,单个接口测试与单个单元测试用例相比,也可以覆盖更多的代码。更重要的是,接口测试也可以是面向业务的测试,通过接口进行业务层面的测试。
      而相比UI自动化用例,接口测试更加的简单直接,执行效率更高。 
           因此,将大部分自动化投资用于接口测试,可以获得最高的投资回报。再结合持续测试与持续集成等最佳实践,在团队之间彼此共享测试用例、测试框架或者平台。
           接口测试中目前常用的工具包括Jmeter,Postman,这2款工具在多人协调工作方面不太好,测试人员共同完成一个任务费时费力,尤其对成熟的企业。另外对不同接口类型的支持方面这2款工具也不太好,需要现开发,例如postman主要支持rest接口,Jmeter支持dubbo需要提供额外的jar包支持。
         基于上面的问题,这里有提供一款接口智能测试平台,不仅不需要懂代码,使用简单,对测试人员要求低,而且解决了postman和Jmeter中遇到的各种问题,还支持多人协同,支持加解密等扩展功能,满足成熟企业的要求。免费地址:https://test.ironz.com/welcome
    之后下载镜像,启动并绑定账号就可正常使用,关键是这一切都是免费的。
  • Robot Framework类似功能

    2019-09-10 18:02:34

    https://test.ironz.com/welcome

    帮助手册和免费镜像下载在首页
  • 不懂代码也能测试的接口自动化平台

    2019-09-04 19:47:14

    https://test.ironz.com/welcome
    手册和镜像见首页
  • 安全测试大全

    2019-01-31 13:58:27

    1.安全测试在做什么?
    扫描?在很多人的眼中,做安全的就是整天拿个工具在哪里做扫描操作,使用各种不同的工具做扫描。是的,扫描是安全测试的很重要的一部分,扫描可以快速有效的发现问题。扫描工具的易用性、方便性决定了重要地位。但是扫描工具的局限性、程序的不够灵活等缺点也是显而易见的。不管是扫描报告的分析、漏洞的深度挖掘、测试的组织等等的工作都离不开安全测试人员,所以只能说扫描工具减轻了测试人员的工作量,是安全测试的一种手段。
    2.安全测试者是怎样定位自己的?
    我们经常可以从身边的朋友口中听到一些有关安全的名称,向什么软件安全、信息安全、网络安全、计算机安全等一些词组,这些领域都是做安全的,那么我们是属于哪一个呢?
    大家可以上百度百科查看下这些词组的概念。软件安全往小了说就是某一个软件产品,说大了除了硬件就是软件了啊。信息安全看名字我们就知道关键是信息两个字,但是什么是信息呢,客户的数据还是一切有用的数据?网络安全,什么是网络,网络系统硬件、软件这都是写模糊的可大可小的概念。在看计算机安全,PC?服务器?路由器?好吧我们可以看到这些概念往大了说就成了组成我们今天互联网的各种设备包括各种的嵌入式机器、外接USB、蓝牙等设备的共同体的硬软件,以及使用、维护、管理等这些东西的人的整个的安全问题。在看他们的区别,他们已不同的地方作为其主要关注点,或者说出发点,他们并没有明显的界线却有着自己的侧重点。而我们的侧重点是什么呢,我们产品是一个什么样的产品呢?我们有WEB服务、接口服务、文件服务、视屏等服务等我们把它们统一称为我们的系统,那么我们就是在做这个系统的安全测试,所以我觉得我们应该定位为系统安全测试。
    当然我们的系统运行中也涉及到人、涉及到硬件,

    比如这些站安全比较好

    http://www/lahuoge.cn拉货哥同城网站 http://www.qijihu.com奇迹虎网站 http://www.qijihu.cn奇迹狐网站

     

    此处都不是我们的关注点,我们只从软件技术的角度来识别它。那么,系统安全测试就成了区别于功能测试,和性能测试一样,单独列出来的专项测试了。

    3.安全的本质是什么?
    信任、人性(网络安全的最大漏洞是人)、止损、攻防
    以上是当前网上一些主要的论点,以信任或者不信任作为本质出发点的还是占据主流的。
    4.概念定义
    敏感数据:
    敏感数据的具体范围取决于产品具体的应用场景,产品应根据风险进行分析和判断。典型的敏感数据包括口令、银行帐号、大批量个人数据、用户通信内容和密钥等。
    个人数据:
    指直接通过该数据或者结合该数据与其他的信息,可以识别出自然人的信息。
    匿名化:
    指对个人数据进行的更改(例如单向散列、截短、替换等,如需保留个人数据真实值与替换值之间的对应关系,可以使用对称加密或映射表方式,但密钥/映射表必须由数据所有者控制),使原来有关个人的信息不再能归属到一个可识别的自然人,或推理这种归属需要耗费过多、不相称的时间、费用和精力

    5.我们应该如何去着手
    如何着手去做这个系统安全测试呢?作为一个测试人员要保证系统整体的安全,这就需要有一个整体的结构的框架,就像盖房子一样,先造钢筋混凝土框架,然后砖块去填充它。这里的钢筋混凝土框架就是安全特性方向,其实就是从整体方向上的一个划分,可以有如下简单的划分。
    5.1.测试的特性
    安全特性:操作系统安全、数据库安全、WEB安全、软件的发布和安装安全、协议与接口攻防、敏感数据保护、手机端安全、静态代码分析。
    5.1.1.操作系统安全
    操作系统安全我们可以把它分为以下几块:
    系统漏洞(操作系统补丁)、系统配置(安全加固)
    业界权威工具Nessus,其他如retina、绿盟、天镜等。开源的工具可以使用OpenVAS。
    5.1.2.数据库
    数据库安全我们可以把它分为以下几块:
    数据库漏洞(补丁)、数据库配置(安全加固)
    工具可以使用Ngs
    5.1.3.web安全
    数据库安全我们可以把它分为以下几块:
    身份验证、验证码、会话管理、权限管理、敏感信息传输、安全审计、信息泄露、输入校验、输出编码、上传下载、异常处理、注释代码等
    容器的安全(tomcat)
    应用软件安全(nginx、负载均衡软件、jquery等)
    扫描工:appScan、awvs
    5.1.4.软件的发布与安装安全
    发布件的完整性校验(签名、哈希)
    防病毒:需要安装的软件需要经过常用的杀毒软件(如360、卡巴斯基、金山毒霸等)的扫描,保证没有病毒特种码,以免被杀软处理掉。
    5.1.5.协议与接口攻防
    业务交互数据在网络中使用的协议安全性测试
    协议测试工具:codenomical
    对外开放的端口:系统对外开放的端口必须是必须的,禁止开放无用端口
    端口扫描工具:Nmap,近端可以直接在服务器上使用命令查看
    接口:接口接受的数据需要做严格的处理
    接口数据严格校验测试
    5.1.6.敏感数据保护
    识别敏感数据:密码、秘钥、会话标识;个人信息、商业机密、客户信息等
    保护:加密、存储位置、传输方式;获取数据脱敏、匿名化

    这些站就做了加密http://www.hiry.cn/杏仁网站http://www.hiry.net进口商品网站http://www.lahuoge.com拉货哥
    5.1.7.手机端安全
    1、app的签名、反逆向
    2、用户隐私
    3、文件权限
    4、网络通讯
    5、运行时解释保护
    6、组件权限保护
    7、升级
    8、3rd库

    移动APP测试要点:http://blog.nsfocus.net/mobile-app-security-security-test/
    5.1.8.静态代码分析(纯白盒)
    白盒测试主要是通过对代码的浏览来发现问题,当然问题的类型可能是跟我们黑灰盒总结的一致,拿出来单独讲是因为其不同于其他的测试方式。
    1、危险函数、方法
    2、工具检测
    3、逻辑漏洞

    灰盒
    结合白盒和黑盒的一些思路,在实际的代码审计中建议采用灰盒的方式,在需要的地方对代码进行动态调试查看。审计中思路可以考虑如下这些部分:
    1、涉及敏感数据的时候,检查是get、post哪种形式发送数据
    Get传输的数据会被记录在代理、浏览器、web容器tomcat等的日志中
    2、提交铭感数据的时候是否有防止csrf的token、refer、验证码等
    3、sql注入
    1)Statement和preparestatement
    2)mybitas框架 #和$
    4、XSS
    我们用的antisamy只能过滤基于标签的XSS伪造,其他的无法过滤,需要做二次过滤
    5、逻辑
    此处是指,逻辑思路不合理,不符合安全的一些思想,如权限最小化等等
    6、参数范围是否造成dos或者影响系统性能
    7、权限校验、越权
    1)横、纵、多步骤关联性
    2)
    8、session会话管理
    1)常规cookie及session形式
    2)把token作为session的形式,特别注入登录用户和token的绑定关系
    9、参数是否是简单形式,是否可以造成遍历
    10、代码中使用的第三方插件、开源软件是否是最新、是否有安全漏洞
    11、代码中所使用的加密算法,是否是安全的
    12、跳转中的redirect形式中不要带敏感信息,会被发回客户端重新请求的,相当于把这些参数放在了get请求中
    13、SSRF服务端请求伪造,注意url中含有另外一个url的请求
    1)源码中使用urlconnection 支持的协议除了http和https以外,还有file、ftp、jar、mailto等
    request、httpurlconnecttion、httpClient、URL等发起网络请求
    14、加密算法的使用,是否使用的是不合场景的弱算法

    15、数据插入自增Id攻击
    数据传入过来做插入动作,并且使用spring自动绑定对象方法获取数据,之后使用生成的插入sql
    此时自动增长id不要写到更新语句中,如果写入可能造成恶意注入integer范围最大值2147483647,使功能不可用dos
    16、Spring自动绑定参数,参数扩展攻击
    后台使用的对象参数自动绑定获取,相应的sql使用了自动的if是否为null和为空的判断条件,前台可以根据猜测
    注入队形的相应的属性实现非预料结果
    5.2.WEB安全测试
    5.2.1.身份验证 
    为防止密码破解和猜测:
    复杂度要求,必须由大写、小写、数字等组成;
    时效性要求,建议用户3个月更改一次口令;
    密码长度要求,最小8位,最大?位;
    管理员重置密码后密码必须在下次登录更改;
    强度要求,不能跟原密码一致,不能与用户名相似(如,不能包含用户名正写反写大小写等),
    (最新也有说法不建议频繁修改http://www.secdoctor.cn/html/sec/35995.html)
    口令认证必须在服务端进行。
    必须要有验证码机制。
    登录锁定,登录需要有锁定机制即就是多次登录失败后锁定账号或者ip,在一段时间后自动解锁。
    手机验证码轰炸
    手机验证码超时机制
    账户枚举测试

    弱密码概念:https://help.aliyun.com/knowledge_detail/37509.html?spm=5176.7837442.2.5.ZotsLv
    5.2.2.验证码 (普通验证码、知识验证码、无需思考的滑动验证码)
    验证码字符生成算法的安全随机数
    验证码字符不能被验证码识别工具识别
    验证码必须是一次性的
    验证码超时(验证码有效期的意义:1、增加图片处理识别的难度;2、验证码没有有效期的话导致服务器验证码堆积)
    在忘记密码处做安全问答测试

     

    建议的验证码形式:
    当前的最流行的滑动块验证码,有点用户无需动脑,不会打断用户的思考。
    (验证码的前世今生:http://www.freebuf.com/articles/web/102276.html)

    5.2.3.会话管理 
    登录前后会话标示要有变化
    安全退出会话标示注销
    会话标示安全随机
    会话标示的长度适度
    会话超时机制
    会话标识的传输和存储
    会话标识夸PC访问
    5.2.4.权限管理 
    通过灰化(隐藏)使功能失效
    纵向越权
    横向越权
    权限分离
    (系统管理、安全管理、审计管理
    系统管理员主要负责用户管理和系统日常运作相关的维护工作;
    安全管理员负责安全策略的配置和系统资源安全属性的设定;
    审计管理员则对系统审计信息进行管理)
    参看《关于越权》

    5.2.5.敏感信息传输及存储 
    敏感信息不能以get方式提交
    传输通道使用https(关键数据提交服务端不接收http明文数据)
    严格安全传输HSTS(确保从浏览器发出的请求就是https的)
    在url中有session
    对用户保密的信息不能传输到客户端
    含有敏感信息的页面需要设置不缓存
    5.2.6.安全审计 
    登录、退出、操作等都要有日志
    日志格式标准(时间、谁、做了什么操作、结果怎样)
    日志访问的限制
    日志中的敏感信息

    他们是如何迭代的?日志是否保存足够长的时间?
    日志是如何被审查的?管理员能否通过审查出发现攻击行为?
    日志备份如何保存?
    日志记录数据前是否进行验证(最小最大长度,字符等)?
    5.2.7.信息泄露 
    数据库版本泄露 
    容器版本泄露
    绝对路径泄露
    异常信息泄露
    泄露服务器路径
    泄露容器版本
    泄露程序详细堆栈信息
    源代码泄露
    检测Web网络是否存在源代码泄露漏洞,如果存在此漏洞,攻击者可直接下载网站的源代码。
    管理地址泄露
    网站管理地址属于内部使用的信息,公开增加了安全风险。
    Bak信息泄露
    搜索引擎发现和侦察信息泄露(暂时不涉及)
    服务器指纹探测(使用指纹探测工具whatweb需要在linux上编译运行,httprint--最新的signatures.txt不然识别到不准确)


    【其他关注项:】
    枚举web服务器上存在的应用程序
    Whois信息收集
    识别Web应用框架
    Owasp测试指南4中文:https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/zh/web_application_security_testing/review_webserver_metafiles_for_information_leakage_otg-info-003.html
    拖库撞库http://blog.nsfocus.net/information-leakage-thinking-library-collision/
    5.2.8.输入校验
    前台后台都必须校验(“移除已知的恶意数据”不如移除“良好数据之外的所有数据”)
    5.2.8.1.XSS(跨站点脚本攻击)
    XSS-1反射型跨站点脚本编制
    XSS-2存储型跨站点脚本编制(http://xxxxx0000sssss.lofter.com/post/14b1dc_50023e)
    XSS-3 DOM型跨站点脚本编制
    dom xss并不复杂,他也属于反射型xss的一种,domxss取决于输出位置,并不取决于输出环境,因此domxss既有可能是反射型的,也有可能是存储型的),简单去理解就是因为他输出点在DOM,所以在道哥的《白帽子讲Web安全里》也有详细介绍。dom - xss是通过url传入参数去控制触发的。
    HPP(HTTP参数污染[同名参数]http://blog.csdn.net/eatmilkboy/article/details/6761407)
    漏洞危害: 
    1、钓鱼欺骗:最典型的就是利用目标网站的反射型跨站脚本漏洞将目标网站重定向到钓鱼网站,或者注入钓鱼JavaScript以监控目标网站的表单输入,甚至发起基于DHTML更高级的钓鱼攻击方式。
    2、网站挂马:跨站时利用IFrame嵌入隐藏的恶意网站或者将被攻击者定向到恶意网站上,或者弹出恶意网站窗口等方式都可以进行挂马攻击。
    3、身份盗用:Cookie是用户对于特定网站的身份验证标志,XSS可以盗取到用户的Cookie,从而利用该Cookie盗取用户对该网站的操作权限。如果一个网站管理员用户Cookie被窃取,将会对网站引发巨大的危害。
    4、盗取网站用户信息:当能够窃取到用户Cookie从而获取到用户身份使,攻击者可以获取到用户对网站的操作权限,从而查看用户隐私信息。
    5、垃圾信息发送:比如在SNS社区中,利用XSS漏洞借用被攻击者的身份发送大量的垃圾信息给特定的目标群。
    6、劫持用户Web行为:一些高级的XSS攻击甚至可以劫持用户的Web行为,监视用户的浏览历史,发送与接收的数据等等。
    7、XSS蠕虫:XSS 蠕虫可以用来打广告、刷流量、挂马、恶作剧、破坏网上数据、实施DDoS攻击等。
    参考:
    https://help.aliyun.com/knowledge_detail/37444.html?spm=5176.7837442.2.11.F8ceHg
    http://blog.csdn.net/change518/article/details/51024706 隐藏域XSS(借助accesskey属性)
    5.2.8.2.SQL注入
    (1、java预处理preparestatement;2、正则表达式过滤参数;3、严格字符串过滤;4、参数化的sql)
    例子:参数date=if(now()=sysdate(),sleep(0),0)/*'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"*/
    Sql语句中的/斜杠:表示执行,把之前时间内的缓存中的语句再执行一遍
    \斜杠:表示语句未完换行
    单行注释:--
    多行注释:/* */
    If(now()=sysdate(),sleep(2),0)表示如果now()=sysdate(),为真执行sleep(2),否则执行0
    当前形势下,新开发的网站,大部分采用新框架都已经可以预防sql注入了,只有手动拼接的sql语句易被sql注入。
    生成注入用例时注意:
    1)’ 单引号闭合
    2)‘OR 单引号也可以有结束开始下一元素的效果
    3)-- - 注释后面跟空格实现注释不跟后面语句连接,后面实际被注释掉效果
    4)Select CONCAT_WS(0x3A, USER, PASSWORD) FROM mysql.user 获取数据库用户
    5)union all 连接两个select查询结果,合union的区别不去重复;两个select查询的字段一样
    6)insert into mysql.user(Host,User,Password) values("%","Sectest",password("111111")) 给数据库添加用户 %:远程用户,localhost:本地用户

    系统使用了MyBatis动态SQL框架组装sql,注意配置文件中的$和#的使用,使用$可能导致sql注入
    拼接后的语句再放入预编译对象是徒劳的,因为在预编译之前拼接的SQL语句执行逻辑已经被破坏,原 SQL语句的本意已经被改变了。

    概念:
    https://help.aliyun.com/knowledge_detail/37450.html?spm=5176.7837442.2.10.ZotsLv
    Sql注入常用语句:
    http://www.111cn.net/database/mysql/58518.htm
    http://wenku.baidu.com/link?url=sK_daSqJFJt3KsCuYQOjCkuGldDJSJQbATiRX42UEocanxFejYSjVESnyHPhvDP___hGAbKSLMhh4020TOP9wItRr1YWiq8OQ1HzYItXc6q

     

    5.2.8.3.XML注入测试
    (借助XXE,攻击者可以实现任意文件读取,DOS拒绝服务攻击以及代理扫描内网等)
    日志注入(\r,\n换行,伪造日志)
    命令注入(操纵系统命令)
    Email Header Injection(邮件标头注入) 
    /*(我们在暂时不涉及)
    Email Header Injection:如果表单用于发送email,表单中可能包括“subject”输入项(邮件标题),我们要验证subject中应能escape掉“\n”标识。
    <!--[if !supportLists]--> <!--[endif]-->因为“\n”是新行,如果在subject中输入“hello\ncc:spamvictim@example.com”,可能会形成以下
    Subject: hello
    cc: spamvictim@example.com
    <!--[if !supportLists]--> <!--[endif]-->如果允许用户使用这样的subject,那他可能会给利用这个缺陷通过我们的平台给其它用户发送垃圾邮件。
    */
    5.2.8.4.代码执行
    代码执行是指应用程序对传入命令的参数过滤不严导致恶意用户能控制最终执行的命令,进而入侵系统,导致严重破坏的高危漏洞。
    https://help.aliyun.com/knowledge_detail/37446.html?spm=5176.7837442.2.2.nCzE5s

    5.2.8.5.CRLF漏洞
    CRLF,carriage-return-line-feed,回车换行漏洞。
    案例参考:https://www.leavesongs.com/PENETRATION/Sina-CRLF-Injection.html(对header进行注入)

    5.2.9.上传下载 
    跨目录文件下载
    任意文件下载

    任意文件上传(后缀)
    任意目录文件上传(目录)
    超大文件上传(大小)
    上传文件废弃后处理(堆积)
    上传文件名xss(重命名)
    上传文件名截断(0x00或者0x58,burp也可以修改二进制,url中%00)
    上传文件权限限制
    压缩炸弹
    Include包含上传(shtml)
    上传zip文件名中包含../
    本地文件包含的概念:
    https://help.aliyun.com/knowledge_detail/37472.html?spm=5176.7837442.2.2.2NdNhY
    5.2.10.CSRF

    CSRF【cross site request forgery】跨站点请求伪造。
    原理:利用浏览器内存共享原理,利用用户身份伪造用户动作发送到服务端。(从恶意站点模拟用户发送正常的请求携带cookie,见7.1)
    5.2.10.1.URL重定向(跳转)漏洞:
    (参考http://drops.wooyun.org/papers/154)
    1、问题点
    在页面跳转的地方,URL中包含另外的网址,例如:
    第一类 简单URL过滤
    www.xxx.com?a=http://www.yyy.com
    第二类 底层操作类库支持其他协议导致读取本地或探测网络信息
    http://h2w.iask.cn/h5.php?u=file:///etc/passwd
    由于底层适用类curl库,而没有正确过滤URL导致,可以读取内网诸多信息.还有其他类似的形式:
    如file://, ftp://, telnet://等
    第三类 不支持其他协议但是没有设置网络边界(SSRF漏洞的姿势啊)
    http://wap.sogou.com/tc?url=http%3A%2F%2Fno.sohu.com%2F
    使用域之间的信任,突破到系统的内网

    2、分析
    理论上讲,url跳转属于CSRF的一种,我们需要对传入的URL做有效性的认证,保证该URL来自于正确的地方,限制的方式同防止csrf一样可以包括:
    1)referer的限制
    2)加入有效性验证Token
    3、对跳转的地址没有做严格的校验
    5.2.11.CORS漏洞
    CORS【cross origin resouse-sharing】跨域资源共享。
    工具:shell of the future
    理解参考:http://www.2cto.com/Article/201209/154081.html
    5.2.12.SSRF漏洞(服务端请求伪造)
    行为特点:从其他服务器获取数据资源的功能,并且此功能获取资源的请求是从服务端发起的。
    可以实现的攻击:
    可以对服务器所在的内网、本地端口进行扫描、获取banner等
    攻击运行在内网或者本地的应用程序(比如溢出)
    对内网WEB应用进行指纹识别,访问默认文件的方式
    攻击内网WEB服务器,get请求方式
    利用file协议读取本地文件:例如http://192.168.1.119/pm/www/index.php?m=bug&f=view&bugID=4052


    http://netsecurity.51cto.com/art/201312/424038.htm
    5.2.13.Google黑客
    1、搜索站点看是否能发现敏感的信息或不该公布的信息
    搜索命令,例如:
    site:yizhen.cn
    site:yizhen.cn yizhen.cn:password
    site:yizhen.cn inurl:session
    site:yizhen inanchor:修改密码
    cache:www.yizhen.cn

    参考:http://www.cnblogs.com/xuanhun/p/3910134.html
    5.2.14.其他
    http开放方法测试
    不安全的方法:put、delete、trace、connect
    TRACE: 这个方法简单返回客户端发送给服务器的所有信息,主要用于调试目的。这个方法最初被认为没有危害,被Jermiah Grossman发现能被用于实施XST
    CONNECT: 这个方法允许客户端使用web服务器作为代理。
    DELETE: 这个方法允许客户端删除web服务器上的一个文件。攻击者能利用他简单直接破坏网站或者实施拒绝服务攻击。
    这个方法允许客户端向web服务器上传新的文件。攻击者可以利用他来上传恶意文件(比如一个asp文件通过调用cmd.exe来执行命令),或者简单使用受害者服务器作为文件仓库。
    banner信息检查
    HTTP方法篡改(已验证,没有此问题;问题案例https://www.sobug.com/article/detail/25)
    JavaScript. DDOS(切换https后问题解决)
    缓冲器溢出漏洞,java的不涉及
    管理接口暴力枚举(DirBuster)
    测试HEAD访问控制绕过
    跨域策略测试
    数值溢出
    不管整数,浮点数,长整数等都是有一个可以表示的最大值,如果一个该类型变量被赋予超过其最大值的时候就会出现溢出,而找出该变量的值异常。

    5.2.15.重放攻击
    重放多次请求消耗系统资源的请求,造成dos。筛选出较为消耗资源的请求,检查系统是否有防重放策略或者机制。
    5.2.16.容器的安全
    5.2.16.1.Apache tomcat
    1)官网公布的安全漏洞补丁升级
    http://tomcat.apache.org/security-7.html#Apache_Tomcat_7.x_vulnerabilities
    2)运行账户
    建立独立用户,用户名和组名均为tomcat,不设置密码(即禁止SSH登录),tomcat进程以此帐号身份运行,严禁以root权限运行tomcat,禁止以个人帐号或其他有shell权限的帐号运行tomcat。
    3)删除Tomcat自带项目
    4)检查tomcat已知的带有风险的配置
    a)禁用应用程序自动部署功能(待考虑)
    b)禁用webdav
    c)定制Tomcat出错信息
    d)关闭Tomcat的目录列表功能
    e)限制http请求的消息主体的大小
    f)禁止配置Tomcat的网络连接超时时间为0或-1
    g)可执行文件只能由Tomcat属主用户修改
    h)配置文件只能由Tomcat属主用户修改
    i)日志文件只能由Tomcat属主用户修改和执行
    j)配置虚拟目录,用以隐藏后台路径
    k)禁用SSI和CGI功能
    l)不允许使用SetUID程序,尤其是root身份的SetUID程序
    m)开启Tomcat的日志功能:正常的访问日志和错误请求日志。日志文件的记录中包含访问时间、内容、结果及请求用户的ip等关键信息

    影响较大的漏洞:
    CVE-2016-1240 tomcat地权用户提权漏洞。(2016-10)
    5.2.17.其他组件安全
    5.2.17.1.Nginx
    官网安全漏洞先关链接:http://nginx.org/en/security_advisories.html

    影响较大的漏洞:
    CVE-2016-1247 提权漏洞,借助nginx日志,提取到root。(2016-10)
    5.2.17.2.Jquery
    http://192.168.1.120:8080/amol-hospital/js/jquery-1.9.1.min.js
    http://192.168.1.120:8080/amol-hospital/js/ueditor/third-party/jquery-1.10.2.min.js

    在官网上没有找到相应的安全漏洞列表
    https://blog.jquery.com/2013/02/04/jquery-1-9-1-released/

    Jquery两个版本间更新日志,其中有两处vulnerable字样
    https://github.com/jquery/jquery/compare/1.9.1...1.12.3
    5.2.17.3.Java漏洞
    (放到操作系统部分,nessus可以很好的检查这个)
    5.2.17.4.百度Ueditor(1.4.3)
    5.2.17.5.Node.js(超声视频使用)
    node -v
    v0.10.42

    5.2.17.6.Spring
    5.2.17.7.Mybitas
    5.2.17.8.Druid
    数据库连接池组件,包括四部分:DruidDriver、DruidDataSource、SQLParsr、扩展组件。
    可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
    1、访问没有权限控制

    5.2.17.9.Turnserver
    TurnServer 是一个TURN协议的开源实现。
    该协议允许一个客户端以relay方式获得IP地址和端口。这对于symmetric 类型的NAT或者防火墙两边设备的通信非常有用。
    TurnServer项目旨在兼容地处理 TURN 和 STUN请求 (RFC 5766 , RFC 5389),同时也支持 RFC6156 即 TURN-IPV6 (relay between IPv4-IPv6, IPv6-IPv4 and IPv6-IPv6 addresses) 和 RFC6062 即TURN-TCP (relay data with TCP)

    5.2.17.10.Terracotta(session共享)
    5.2.17.11.phpMyAdmin
    http://www.phpmyadmin.net/security/

    5.2.17.12.Redis
    1、指定redis服务使用的网卡 (需要重启redis才能生效)
    在 redis.conf 文件中找到 “# bind 127.0.0.1” ,把前面的#号去掉,然后保存。注:修改后只有本机才能访问Redis。
    2、设置访问密码 (需要重启redis才能生效)
    在 redis.conf 中找到“requirepass”字段,在后面填上你需要的密码,Redis客户端也需要使用此密码来访问Redis服务。
    3、修改Redis服务运行账号 (需要重启redis才能生效)
    请以较低权限账号运行Redis服务,且禁用该账号的登录权限。另外可以限制攻击者往敏感写入文件,但是Redis数据还是能被黑客访问到,或者被黑客恶意删除。
    4、设置防火墙策略

    如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。
    参考:
    https://help.aliyun.com/knowledge_detail/37447.html?spm=5176.7837442.2.10.nCzE5s

    5.2.17.13.Fastjson开源jar
    https://github.com/alibaba/fastjson/wiki/security_update_20170315
    fastjson最新远程代码执行高危安全漏洞,当前涉及1.2.24之前版本
    我们用的1.1.41
    5.2.18.Web木马
    常见的简单形式--诱导优化打开具有网页木马的页面,一般是写入js引用大马的代码网页,用户打开诱导网页后在电脑上实际上已经默认运行了下载大马和执行大马的操作

    5.3.敏感数据保护
    5.3.1.加密算法
    算法列表能用,不能用
    弱算法:md2,md4,md5(2004年的国际密码学会议(Crypto’2004)王小云证明了MD5可以被碰撞,至此,MD5不再安全) ,sha1,blowfish
    推荐算法:sha256,aes128
    可逆的加密算法:des 3des aes128
    可逆加密算法又分为两大类:“对称式”和“非对称式”。
    对称式加密特点:加密和解密使用同一个密钥,通常称之为“Session Key ”。
    DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6和AES
    非对称式加密特点:加密和解密所使用的不是同一个密钥,而是两个密钥:一个称为“公钥”,另一个称为“私钥”;它们两个必须配对使用,否则不能打开加密文件。这里的“公钥”是指可以对外公布的,“私钥”则只能由持有人本人知道。
    常见的非对称加密算法:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)
    不可逆加密算法:sha256 sha512 md5
    不可逆加密算法的特征是,加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文。这种加密后的数据是无法被解密的,只有重新输入明文。
    常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1
    参考:
    http://www.360doc.com/content/13/0402/15/3862791_275529254.shtml
    http://book.51cto.com/art/201109/294599.htm
    MD5输出128bit
    SHA1输出160bit
    SHA256输出256bit
    另外还有SHA244,SHA512
    分别输出244bit,512bit

    问题分析
    数据库中的密码的机密算法推荐:
    1、使用不可逆加密算法
    2、使用加盐(避免预先计算彩虹表)

    建议的用户密码加密形式:
    http:若通道未加密,密码在客户端使用可逆加密算法AES-256并加盐(从服务端获取挑战码即盐值),传输到服务端再解密。
    https:服务端接受到明文密码后使用不可逆加密算法对密码进行哈希加密SHA256并加盐(使用安全随机盐值,长度建议跟密码最长一致),再存入密码密文和盐值到数据库。
    5.3.2.证书
    我们一般说的证书都是服务端证书,即浏览器使用的验证服务器身份的证书。
    我们的证书是自生成的证书。
    证书:证明身份的凭据,证书中心用自己的私钥对信息发送者的公钥和一些信息一起的加密,证书可以保证公钥的安全性和有效新,公钥可以验证私钥持有方的身份。常规信息有:颁发给的通用名、组织、组织单元、序列号和颁发者的通用名、组织、组织单元,有效时间开始于、过期时间,指纹SHA-256指纹和SHA1指纹。详细信息还有证书的签名算法、公钥算法、公钥等。

    签名哈希算法:证书编码完整性保证的哈希算法
    签名算法:私钥对证书编码的哈希加密的算法;证书签名使用的算法是发布者自己规定的
    上面两个是发布机构搞得,用来CA验证的

    指纹算法:计算出指纹的哈希的算法,就是哈希算法,一般就是sha1
    指纹:证书的哈希值并用私钥加密。

    鉴别用户的真伪可以通过鉴别用户的私钥的真伪来确认,就是看加密的信息服务端是否可以解密。
    公钥:连接建立时浏览器端加密时使用的秘钥。
    私钥:连接建立时服务器端加密时使用的秘钥。
    使用时:
    步骤一:
    1、浏览器输入网址访问yizhen.cn(应用层的)
    2、浏览器底层的TSL协议发送明文的Hello信息给服务器(网络层)
    3、服务器响应一个Hello信息给浏览器
    步骤二:
    服务器端发送它的证书给浏览器(图中的三,图中的二是之前就生成好的,存储在服务端的公钥、私钥、证书)
    步骤三:
    1、客户端验证服务端发来的证书
    2、验证证书的签名、完整性等信息
    3、去浏览器证书管理中心验证证书是否可信,是否为可信机构的证书或者子证书
    4、如果不可信,浏览器抛出警告,提示用户,需要用户确认选择是否继续
    步骤四:
    1、浏览器产生一个随机的值,作为秘钥,对称加密的秘钥,此处就称为秘钥。
    2、使用证书中的公钥对产生的秘钥进行加密生成密文串
    步骤五:
    1、发送密文串给服务器
    2、服务器接受到密文串,使用证书的私钥进行解密,获得对称加密的秘钥。
    3、服务器使用对称秘钥加密响应报文内容发送给浏览器。
    步骤六:
    服务器和浏览器可以通讯了。
    浏览器发送的数据都是公钥加密,使用对称秘钥解密收到的数据。
    服务器发送的数据都是对称秘钥加密的,收到的数据使用私钥解密。
    简单示意图如下:

    证书介绍和攻击
    Pem格式的证书详细信息查看:
    https://www.trustasia.com/tools/cert-decoder.htm
    SSL证书被攻击、假冒的风险分析
    http://wenku.baidu.com/link?url=LkghTfA11JWJBLFJrgBZfCrIBFJoqfcH1q4xBEbzt3xmGtkR7mdkV91mUnRobYQKYz2ekVTo7XNQdOMHIuOpWZv4TBDBVsBo52dYNeX1zRi
    一个合法有效的SSL证书误签发给了假冒者(--)
    破解SSL证书签发CA的私钥(关注签名算法)
    SSL证书签发CA的私钥泄露(如果是自签名证书需要关注)
    破解SSL证书的私钥(关注指纹算法)
    SSL证书的私钥泄露(服务器端私钥的存贮)
    认证机构主动为假冒网站签发合法有效的证书(--)
    利用可信的SSL服务器证书进行中间人攻击(--)
    在用户主机中植入伪造的根CA证书(或一个完整的CA证书链)(--)
    旁路证书的可信性的验证(--浏览器操作系统漏洞)

    ---如果证书的跟证书没有,第一次访问会去证书网站获取根证书或者中间证书

    5.3.2.1.证书加密算法的检查
    1、证书的指纹算法是否安全,不安全的算法造成证书加密传输的信息可以被解密
    2、证书的签名算法是否安全,不安全的签名算法可能造成证书被伪造
    5.3.2.2.证书对应的秘钥保存检查
    1、证书私钥在服务器端存储是否加密
    2、证书私钥在服务器端的存储文件权限是否只有所有者可以访问
    ----浏览器端客户的CA根证书是否安全可信,这个无法保证(不涉及)
    5.3.3.明文密码
    客户端
    1、浏览器Cookie中存储,浏览器Cookie中记录密文密码
    2、浏览器记录密码保存明文密码
    服务端明文密码检查
    1、 配置文件明文密码
    2、日志中记录明文密码
    3、程序中硬编码密码、密钥
    (针对秘钥场景的理解,主要针对当前的弱算法秘钥爆破的场景,原理是通过对多次的加密后的密文对比差异尝试推倒秘钥,有些场景可以认为是分问题的,如数据库密码以DES加密密文存储在配置文件中,密钥在代码中硬编码,这种场景的密钥硬编码就是没有问题的,他的密钥在配置文件和代码中其实

  • Jmeter实现WebSocket协议的性能测试方法

    2018-12-26 09:34:22

    一、场景选择
        websocket协议性能测试场景通常包括:
        1、websocket并发连接和关闭;
        2、websocket消息并发连接的大数据推送;
        3、websocket长时间链接,稳定性测试;
    二、工具选择
        Jmeter+websocket sampler
    三、方法
        1.获取websocket samplar   https://github.com/maciejzaleski/JMeter-WebSocketSampler
          下载源码并打成jar包
        2、在maven 仓库中下载依赖的jar包
           https://mvnrepository.com/


          jetty-http-9.1.1.v20140108.jar
          jetty-io-9.1.1.v20140108.jar
          jetty-util-9.1.1.v20140108.jar
          websocket-api-9.1.1.v20140108.jar
          websocket-client-9.1.1.v20140108.jar
          websocket-common-9.1.1.v20140108.jar
       3、将jar包放到jmeter的 lib/ext/文件下面
     
       4、重启jmeter
    四、测试过程
        1、创建线程组、websokcet sampler、结果集,查看结果树等内容;
        2、输入内容解释
           
    一、Web Server

    1.Server Name or IP:被测 WebSocket服务器的域名或IP

    2.Port Number: 被测WebSocket服务器的端口号。

    二、Timeout

    1.Connection:链接建立的最大超时时间,单位毫秒。如果达到超时时间设置后链接未建立,则sampler失败。

    2.Response:对响应消息的最大等待时间,单位毫秒。到达设定时间后WebSocket链接关闭。

    三、WebSocket Request

    1.Implementation:仅支持 RFC6455(v13)

    2.Protocol:ws——普通的WebSocket链接,或wss——安全的WebSocket链接(WebSocket Secure connection)

    3.Path、同请求一起发送参数、Request Data:与http采样器类似,结合被测接口说明文档来进行配置



  • 不能以代码能力评价测试人员

    2018-12-16 23:10:12

    测试人员的核心价值和能力包括多个方面,代码能力只是其中一项,测试人员的代码能力比开发人员弱,并不能说明测试人员价值低。

    测试人员需要具备的能力包括:不同的时刻,不同的能力占领主导,这里缺少了业务的理解能力。



  • 随行付微服务测试之单元测试

    2018-12-12 15:06:28


    单元测试为代码质量保驾护航,是提高业务质量的最直接手段,实践证明,非常多的缺陷完全可以通过单元测试来发现,测试金字塔提出者Martin Fowler 强调如果一个高层测试失败了,不仅仅表明功能代码中存在bug,还意味着单元测试的欠缺。因此,无论何时修复失败的端到端测试,都应该同时添加相应的单元测试。 而越早发现发现Bug,造成的浪费就会越小,单元测试本身就能够提供了快速反馈的机制。另外,单元测试是一个优秀的开发工程师必备技能之一,优秀的单元测试是业务快速投产的加速器。

    微服务架构下开展单元测试的意义

    虽然对于100%的单元测试覆盖率我们持有保留态度,但在一个微服务架构基础设施还不完善、开发人员能力参差不齐、DDD(领域驱动设计)能力不足以应对复杂业务的情况下,单元测试是性价比最高的实践。单元测试可以充当一个设计工具,它有助于开发人员去思考代码结构的设计,让代码更加有利于测试,满足架构的可测性设计要求。

    单元测试的意义包括如下内容:

    尽早发现缺陷,降低开发投入成本

    85%的缺陷是代码阶段产生的,单元测试阶段可以发现绝大部分软件缺陷。同时软件产品的缺陷发现的越早往往会大大的降低其开发的投入成本,其缺陷的发现时间与修复缺陷的成本如下图中红色曲线。红色曲线表明随着软件开发的进行,漏洞越早发现,其修复的成本越低,并且其修复成本与开发进度的上升趋势越在后期越接近于指数上升。
    img01.png
    放心重构

    无论是对单体项目还是单体项目向微服务架构迁移,代码都在不断的在变化和重构,通过单元测试,开发可以放心的修改重构代码,减少改代码时心理负担,提高重构的成功率。
    改进设计

    越是良好设计的代码,越容易编写单元测试,多个小的方法的单测一般比大方法(成百上千行代码)的单测代码要简单、要稳定,一个依赖接口的类一般比依赖具体实现的类容易测试,所以在编写单测的过程中,如果发现单测代码非常难写,一般表明被测试的代码包含了太多的依赖或职责,需要反思代码的合理性,进而推进代码设计的优化,形成正向循环。
    选择测试驱动开发(TDD)的模式进行项目开发,以单元测试引导项目实现。这种模式下单元测试先行,根据单元测试代码开发功能代码,进而非常精准的实现业务需求,减少返工和缺陷率,可提高项目质量和效率。

    单元测试的常见误解

    单元测试浪费了太多的时间

    虽然不进行单元测试可以更快的交付到后续测试阶段,但是在后续集成测试阶段、系统测试阶段会发现更多的缺陷甚至软件无法运行的致命缺陷,这些缺陷修复的时间远超过单元测试的时间。另外没有单元测试的代码后期软件进行重构或者改进时花费的时间也比有单元测试的所花费的时间要多很多。所以说完整计划下的单元测试是对时间的更高效的利用。
    已经有接口集成测试、系统功能测试进行质量保证了,集成测试阶段对接口进行全面测试就可以达到单元测试的要求,没必要做重复工作在进行单元测试。

    接口测试和功能测试无法覆盖所有的代码,这样如果缺陷存在则将被遗漏,并且Bug将被带到生产上去。一旦用户使用过程中触发了这些没有测试的代码就会带来严重的经济后果。
    跑通一个业务主流程等价于做过单元测试

    目前有很多开发人员认为,开发完代码之后,写个main方法,从入口调完所有的模块,最后验证下返回结果,就认为做过单元测试了,这种想法是及其错误的,这充其量算一种不全面的冒烟测试,是对单元测试概念的错误认知。
    ##微服务架构下如何开展单元测试
    下面将从单元测试所处的阶段、单元测试用例设计规范、单元测试实现几个维度分别介绍如何在微服务模式下开展单元测试。
    首先看下单元测试所处的阶段,下图为非TDD模式下单元测试所处的阶段

    img02.png
    由图可见单元测试处在特性分支开发完成之后,具体的描述如下:

    1.开发人员从Master分支拉取特性分支作为开发分支;
    2.开发完特性分支后、代码构建、单元测试、静态代码扫描;
    3.通过后合并到Master分支,用于投产。
    下面看下什么样的单元测试用例是优秀的用例,是即满足运行速度又满足高覆盖率的用例。随行付定制了单元测试规范,下面节选了强制要求的部分规范。优秀的单元测试用例要符合以下用例设计规范的要求。

    1.必须遵守 AIR 原则

    【说明】单元测试在线上运行时,感觉像空气(AIR)一样并不存在,但在测试质量的保障上,却是非常关键的。好的单元测试宏观上来说,具有自动化、独立性、可重复执行的特点。
    A:Automatic(自动化)
    I:Independent(独立性)
    R:Repeatable(可重复)
    2.单元测试应该是全自动执行的,并且非交互式的

    【说明】测试框架通常是定期执行的,执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。单元测试中不准使用 System.out 来进行人肉验证,必须使用 assert 来验证。
    3.保持单元测试的独立性

    【说明】为了保证单元测试稳定可靠且便于维护,单元测试用例之间决不能互相调用,也不能依赖执行的先后次序。反例:method2 需要依赖 method1 的执行,将执行结果做为 method2 的输入
    4.单元测试是可以重复执行的,不能受到外界环境的影响

    【说明】单元测试通常会被放到持续集成中,每次有代码 check in时单元测试都会被执行。如果单测对外部环境(网络、服务、中间件等)有依赖,容易导致持续集成机制的不可用。
    5.对于单元测试,要保证测试粒度足够小,有助于精确定位问题。单测粒度至多是类级别,一般是方法级别

    【说明】只有测试粒度小才能在出错时尽快定位到出错位置。单测不负责检查跨类或者跨系统的交互逻辑,那是集成测试的领域
    6.核心业务、核心应用、核心模块的增量代码确保单元测试通过

    【说明】新增代码及时补充单元测试,如果新增代码影响了原有单元测试,请及时修正
    7.单元测试代码必须写在如下工程目录:src/test/java,不允许写在业务代码目录下

    【说明】源码构建时会跳过此目录,而单元测试框架默认是扫描此目录
    随行付在推行单元测试落地过程中采用循序渐进的方式,逐步增加单元测试用例达到单元测试规范中规定的覆盖率要求。需要说明的是我们不是追求覆盖率这个数字指标,那样就舍本求末了,我们是通过覆盖率这个可以量化的指标实现提高代码质量的这个根本目的。

    第一阶段:单元测试覆盖率要求至少25%
    第二阶段:单元测试覆盖率要求至少60%
    第三阶段:单元测试覆盖率要求至少80%
    随行付单元测试覆盖率统计同样采用SonarQube平台结合Jenkins工具,Jacoco单元测试覆盖率工具完成,这个同上篇介绍的静态代码扫描流程是一脉相承的。同时要求开发人员本地的IDE工具中安装Jacoco覆盖率插件,当本地开发完单元测试用例并构建后,即可看到覆盖率信息,进而可以快速补充用例,达到覆盖率要求。
    以Eclipse为例,当开发完单元测试代码后,按照如下操作即可查看覆盖率信息。

    1.选择需要统计的java测试代码或者包;
    2.右键,Coverage as->Junit
    3.覆盖率结果会自动在Coverage 视图中展示出来;
    4.在Java编辑器中用不同的颜色标识代码的覆盖情况。
      【说明】 绿色----全覆盖
            红色----未覆盖
            黄色----部分覆盖
    img03.png
    下面介绍下在微服务下应该如何进行单元测试。为了有效的进行单元测试,需要遵循一定的方法,通常采用路径覆盖法设计单元测试用例。所谓路径覆盖法就是选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。具体设计过程参见如下步骤:

    1.画出程序控制流程图
    2.计算圈复杂度
    3.找出所有程序基本路径
    4.根据路径设计测试数据
    以下图代码为例说明路径覆盖法的设计单元测试的过程

    img04.png
    首先根据代码画出其对应的流程图如下,图中数字代表行号。当条件语句中包含多个条件时应予以拆分,如第13行,拆分为13.1和13.2;对于没有分支和循环的语句可忽略,如第16行。
    img05.png
    有了流程图后,我们可以根据它计算出圈复杂度,这个可以作为测试用例数的上限,圈复杂度计算公式如下:

    V(G)= E - N + 2,E是流图中边的数量,N是流图中结点的数量。 V(G)= P + 1 ,P是流图G中判定结点的数量。

    两个公式用哪个都行,最后的结果应该是一样的。这里我们用第二个公式,V(G)= 3 + 1 = 4,也就是我们只需要设计4条用例即可覆盖所有路径

    接下来就是找出所有基本路径,基本路径是从程序的开始结点到结束可以选择任何的路径遍历,但是每条路径至少应该包含一条已定义路径不曾用到的边,所有的基本路径如下

    A
    B C
    B D E F
    B D E G E F

    得到了所有的基本路径,剩下的简单了,只需要按照路径设计出对应的入参数据即可

    案例1:a = 0, b = 1, 期望值 -1

    案例2:a = 1, b = 0, 期望值 -1

    案例3: a = 4, b = 2, 期望值 2

    案例4:a = 8, b = 12, 期望值 4

    除此之外,单元测试用例设计还需要考虑以下场景:

     边界值
         业务边界
         溢出边界
        字符串、数组、集合等的边界
    异常场景
        业务异常
        输入异常(如参数不合法)
    正常场景
        单个模块的用例设计都可以按照路径覆盖法达到语句覆盖和分支覆盖,但是对于有依赖关系的模块
    在微服务模式下,每个模块之间会存在依赖的情况,为了保持单元测试的独立性原则,在不依赖于外部条件的情况下制造各种输入数据,需要借助Mock技术,其本质是用一个模拟的对象代替真实的对象(例如一个类、模块、函数或者微服务)。模拟对象的行为特征和真实对象非常相似,采用相同的调用逻辑,返回内容按照之前预定义的内容返回,提供返回数据。Mock技术的原理可以用如下案例进行解释。

    img06.png
    当要进行单元测试时,需要给A注入B和C,但是C又依赖D,D又依赖E。这就导致了,A的单元测试不满足独立性原则。 但使用了Mock来进行模拟对象后,就可以把这种依赖解耦,只关心A本身的测试,它所依赖的B和C,全部使用Mock出来的对象,并且给MockB和MockC指定一个明确的行为。

    img07.png
    在单元测试工具的选择方面,随行付单元测试借助Junit工具和Mockito工具进行单元测试,微服务模式下不管是spring boot还是spring cloud,通常使用@SpringBootTest注解进行单元测试。一个单元测试的实现步骤主要包括4步:

    设置测试数据
    Mock依赖的系统并给定预期值,如果没有依赖这步可以省略
    在测试中调用方法
    断言返回的结果是否符合预期
    下面以一个非常简单的例子介绍在微服务模式下如何对spring boot中的controller层和service层进行单元测试。

    img08.png
    调用逻辑简化版如图所示,Controller调用ServiceA,ServiceA依赖ServiceB。

    被依赖ServiceB的代码如下

    package cn.vbill.quality.service;
    import org.springframework.stereotype.Service;

    @Service
    public class ServiceB {
         public boolean serve(int param) {
         return param % 2 == 0;
         }
    }
    被测ServiceA的代码如下

    package cn.vbill.quality.service;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    @Service
    public class ServiceA {
       @Autowired
       private ServiceB srvB;

       public String doSomething(int param) {
          if (srvB.serve(param)) {
            return "even";
          }
        return "obb";
      }
    }
    ServiceA和ServiceB的逻辑非常简单,现在测试ServiceA,步骤如下:

    首先:在gradle中增加测试需要的依赖包

    // 可根据实际情况添加版本号
    testCompile("org.springframework.boot:spring-boot-starter-test")
    其次:在src/test/java下面创建测试类,采用@SpringBootTest注解和Mockito技术对ServiceB进行测试和Mock,更多Mockito的使用可以参考其他文章,这里不过多介绍。代码如下:

     package cn.vbill.quality.service;
     import static org.junit.Assert.assertEquals;
     import static org.mockito.Mockito.when;
     import org.junit.Before;
     import org.junit.Test;
     import org.junit.runner.RunWith;
     import org.mockito.InjectMocks;
     import org.mockito.Mock;
     import org.mockito.Mockito;
     import org.mockito.MockitoAnnotations;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.boot.test.context.SpringBootTest;
     import org.springframework.test.context.junit4.SpringRunner;

     // 以下两个注解在Spring测试中可以说是固定写法
     @RunWith(SpringRunner.class)
     @SpringBootTest
     public class ServiceATest {
     @InjectMocks  //创建被测试类实例
     @Autowired
     private ServiceA srvA; // 先自动装配ServiceA,然后用Mock的ServiceB替换原来的ServiceB

     @Mock
     private ServiceB srvB; // 自动生成ServiceB的Mock实例

     @Before
     public void setup() {
        // 必须在ServiceA完成自动装配后在调用此方法
        // 处理@Mock注解,注入Mock对象
        MockitoAnnotations.initMocks(this);
     }

     // 用Mock对象替换真实的ServiceB可以轻松创造出我们所需的场景
     @Test
     public void doSomething_Even_Success() {
        // 设置Mock预期值
        when(srvB.serve(Mockito.anyInt())).thenReturn(true);
        // 因为Mock的缘故,此处doSomething的实参可随意写
        String result = srvA.doSomething(0);
        // 验证预期值
        assertEquals("even", result);
      }

    @Test
    public void doSomething_Obb_Success() {
        // 覆盖另一条分支
        when(srvB.serve(Mockito.anyInt())).thenReturn(false);
        String result = srvA.doSomething(0);
        assertEquals("obb", result);
      }

    }
    最后,使用覆盖率工具查看单元测试覆盖率,如下图所示,实现了100%覆盖。

    img09.png
    ServiceB没有任何依赖,因此对它测试就按照常规的Junit测试即可,这里不过多介绍。下面介绍Controller层的单元测试,整体上看 Controller 层的测试和 Service 层大致相同,只不过是我们不去直接调用 Controller 的方法,而是通过MockMvc模拟HTTP请求。从逻辑图上看Controller是直接调用ServiceA,因此需要使用Mockito模拟ServiceA。

    被测Controller代码逻辑如下:

    package cn.vbill.quality.web;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;

    import cn.vbill.quality.service.ServiceA;

    @RestController
    @RequestMapping("/")
    public class DemoController {
    @Autowired
    private ServiceA srvA; // ServiceA 代码见上一节

    @GetMapping
    public String doSomething(@RequestParam("p") Integer param) {
        return srvA.doSomething(param);
      }
    }
    测试类如下

    package cn.vbill.quality.web;

    import static org.mockito.Mockito.when;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.Mockito;
    import org.mockito.MockitoAnnotations;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc // 使用该注解自动配置 MockMvc
    public class DemoControllerTest {
     @Autowired
     @InjectMocks
     private DemoController controller;

     @Mock
     private ServiceA srvA;

    @Autowired
    private MockMvc mvc; // 自动配置 MockMvc

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void doSomething_Success() throws Exception {
        when(srvA.doSomething(Mockito.anyInt())).thenReturn("mock");
        // 使用MockMvc模拟HTTP请求
        // 下面三个类经常使用,常通过静态导入简化代码
        // MockMvcRequestBuilders, MockMvcResultHandlers, MockMvcResultMatchers
        mvc.perform(get("/").param("p", "1")).andExpect(content().string("mock"));
    }
    }
    最后,通过覆盖率工具查看单元测试覆盖率为100%,做到了全覆盖。

    img10.png
    以上是如何在微服务模式下进行单元测试进行了详细的介绍,在微服务架构下高覆盖率的单元测试是保障代码质量的第一道也是最重要的关口,应该持之以恒。

    总结

    本篇分别从微服务模式下开展单元测试的意义、对单元测试的常见误解以及如何开展单元测试三个方面进行介绍,单元测试是一项成本低、收益高的实践,要利用好这把利剑,打好代码质量基础,为后续的质量保证过程添砖加瓦。
  • 随行付微服务测试之接口测试和契约测试

    2018-12-12 14:48:49

    日常开发过程中,项目的接口通常由服务提供方约定和提供,微服务模式下接口被多个消费者调用更是常态,那么提供方接口的变更如何快速、高效、无遗漏的通知给消费者呢?另外,当一个service同时被多个使用者调用,如何保证对service的修改可以让其它所有使用者造成的影响都能被感知到?这些问题契约测试可以给你答案。另外,微服务模式下,接口测试是非常重要的测试手段,它在实际的项目中帮助验证微服务之间的协同和交互,大幅降低测试成本和提高测试效率方面提供了很大帮助,可以说接口测试是业务功能测试前置的助推器。因此,这里对这两种测试手段进行介绍。


    接口测试和契约测试所处的阶段

    在实际的工作中,结合随行付的实际情况我们对自动化测试金字塔原理进行了定制,加入契约自动化测试内容,形成如下新版自动化测试金字塔结构。




    由图可知,一个项目的测试过程,从项目推进的维度,首先进行单元测试,其次接口自动化测试、契约测试,最后UI自动化测试和手工测试。


    微服务模式下如何开展接口测试

    接口测试属于集成测试范畴,他是单元测试的扩展和延续。它主要的关注点是内部接口功能实现是否完整,比如说内部逻辑是不是正常,异常处理是不是正确。它是单元测试和契约测试的过渡阶段,它是项目单个代码逻辑最终串联形成有价值业务逻辑的桥梁。因此,其作用举足轻重。随行付开展接口测试,采用的思路是规范和方法先行,其次是工具选择、人员培训,然后是实施和过程优化,最后常态化持续提效和质量保证的过程。


    接口测试规范化要求

    接口测试的质量保证和测试过程的流程化需要通过规范和方法进行指导和约束。我们定制了如下要求(部分内容):


    需求存在新增接口或者接口变更时,要求进行新增接口测试案例的编写或存量接口案例的维护;


    需求涉及到的存量接口需要进行回归测试;


    接口测试覆盖率要求达到100%;


    需求测试结束前至少进行一轮接口回归测试,且回归通过率达到100%


    测试流程规范涉及从需求提出、脚本编写、执行到测试报告的各个过程。


    接口文档。接口文档是接口测试案例设计的依据,接口文档的全面性和准确性决定了接口测试范围的全面性和接口测试结果的正确性、有效性。随行付采用swagger进行接口文档管理。


    接口用例设计。根据接口文档设计接口测试案例,接口测试案例通过接口测试平台进行编写,且需要满足不重不漏原则。


    接口用例评审。根据项目实际情况,接口测试案例编写完成后,需组织相关干系人进行案例评审,记录并发送会议纪要。


    接口用例执行。需求测试结束前接口测试案例至少在测试环境中执行了一次回归测试,要求案例执行通过率达到100%


    缺陷管理和测试报告。


    脚本纳入回归体系,定时回归,持续保障接口的质量,以及接口质量的持续和及时反馈。


    脚本命名规范和编写规范如下(部分内容):


    接口命名要求:采用“接口名称_接口描述”进行命名,用于定义唯一接口。


    方法命名要求:采用“方法名_描述”进行命名,用于定义唯一方法。


    案例命名要求:采用“序号场景操作期望结果”进行命名,用于定义唯一案例。


    【强制】每个接口测试案例都必须包含至少一个断言;


    【强制】对于json格式的报文,接口入参和断言响应的预期值需要使用严格的json格式;


    【强制】swagger脚本导入到接口测试平台时,需要导入.json文件,且文件内容为无BOM的UTF-8编码;


    【强制】数据初始化和断言的sql必须带where条件,且能唯一定位到期望的数据;


    【强制】数据库回退的sql必须带where条件,且能唯一定位到需要回退的数据;


    【强制】影响公共表(如:TBAPCDE_BNK表)或者其他组数据库表(如:资金组)的sql,在数据初始化、回退、接口影响的数据回退、断言回退时必须严格审查;


    【强制】数据库断言sql中的where条件的主键组合需要放到前面,用于断言失败时快速定位问题;


    接口测试用例设计要求

    为了保证接口的质量,需要进行全面的接口测试,因此在涉及接口测试用例时需要依赖方法,因此我们总结了接口测试用例的设计要求,如下图所示。




    接口测试工具

    接口测试过程提效、测试过程自动化需要依赖自动化测试工具,武器不好很难打胜仗。经过调研,市面上很多接口自动化测试工具均无法满足所有的测试要求,因此我们自研了接口自动化测试平台。自动化测试平台具有如下能力:


    案例自动生成。http/https接口案例自动化生成和导入。

    测试过程集中可视化管理。通过将自动化测试过程web化实现了自动化测试计划、自动化测试用例编写、自动化测试用例执行、自动化测试用例管理和自动化测试报告管理各个过程的可视化。

    模拟性能场景。自动化测试实现了通过接口案例模拟性能测试场景的能力。通过使用平台中提供的接口案例,进行并行执行模拟性能场景。

    多协议多报文类型支持。支持http/https协议、dubbo协议、socket协议、rabbitMQ协议等协议的自动化测试,并支持对协议的扩展。同时支持xml、json、sop、8583等多种报文类型以及报文类型的扩展。

    测试资产有效积累。

    自动化调度执行和邮件发送。自动化测试执行通过定时对案例进行调度执行,可对指定的构建版本对应的案例进行自动化的分批、定时调度执行并邮件发送测试报告。

    系统质量的可视化反馈。通过对自动化案例的执行结果统计,分析出系统的质量趋势,做到系统质量的持续化反馈。通过根因分析,统计系统问题的根本原因的比例,更有针对性的解决质量问题。


    通过接口测试持续运行1年多的持续运营,随行付核心业务接口基本实现接口测试用例全覆盖,且均纳入到定期回归过程,持续为接口的质量保驾护航。


    微服务模式下如何开展契约测试

    契约测试的价值


    契约测试分两种类型,一种是消费者驱动,一种是提供者驱动。其中最常用的,是消费者驱动的契约测试(Consumer-Driven Contract Test,简称 CDC)。核心思想是从消费者业务实现的角度出发,由消费者端定义需要的数据格式以及交互细节,生成一份契约文件。然后生产者根据契约文件来实现自己的逻辑,并在持续集成环境中持续验证该实现结果是否正确。对于基于Restful API的微服务来说,它的契约就是指 API 的请求和响应的规则。 如下图所示:



    对于请求,包括请求 URL 及参数,请求头,请求内容等;

    对于响应,包括状态码,响应头,响应内容等。

    对于元数据,指对消费者与提供者间一次协作过程的描述。譬如消费者/提供者的名称、上下文及场景描述等。


    那么契约测试能给微服务带来什么价值呢?文章开头已经提到了契约测试的一部分价值,即接口变更快速通知,servise修改的快速感知。除此之外,它还带来下列价值:


    降低服务集成的难度。把服务集成这个过程分解成了更细的单元测试和接口测试,它从消费者的需求为出发点,把消费者的需求作为测试用例驱动实现一份契约,然后验证提供者端的功能。

    开发并行,提高开发效率。契约隔离了消费者和提供者,双方可以并行开展工作,开发过程中就利用契约进行预集成测试,不用等到联调再来集成调通接口,一旦**,在保证质量的前提下,联调的成本可以减低到几乎为0。

    确保变动的安全性和准确性。只要有变化,契约测试即可第一时间发现,保证安全和对接的准确性。

    作为Mock server为消费者提供Mock服务。集成测试为服务者提供


    微服务下如何开展契约测试


    随行付采用在Spring Cloud Contract开展契约测试。其核心流程包括2步:


    对消费者的业务逻辑进行验证时,先对其期望的响应做模拟提供者(Mock);并将请求(消费者)-响应(基于模拟提供者)的协作过程,记录为契约;

    通过契约,对提供者进行回放,保证提供者所提供的内容满足消费者的期望。

    下面用一个简单的例子说明设计契约测试的方法。这个例子中,一个微服务提供了一个包含三个字段(“IP”、“name”和“password”)的资源,供三个消费者微服务使用。这三个微服务分别使用这个资源中的不同部分。消费者 A 使用其中的 IP 和 name 这两个字段。因此,测试脚本中将只验证来自提供者的资源中是否正确包含这两个字段,而不需要验证 password 字段。消费者 B 使用 IP 和 password 字段,而不需要验证 name 字段。消费者 C 则需要确认资源中包含了所有这三个字段。现在,如果提供者需要将 name 分为姓(first name)和名(last name),那么就需要去掉原有的 name 字段,加入新的 first name 字段和 last name 字段。这时执行契约测试,就会发现消费者 A 和 C 的测试用例就会失败。测试用例 B 则不受影响。这意味着消费者 A 和 C 服务的代码需要修改,以兼容更新之后的提供者。修改之后,还需要对契约内容进行更新。



    下面以一个例子介绍如何使用Spring Cloud Contract开展契约测试的。


    1. Spring Cloud Contract契约是用基于Groovy的DSL定义的,下面是一个契约测试的代码段

     package contracts

      org.springframework.cloud.contract.spec.Contract.make {

      request {

        method 'PUT'

        url '/fraudcheck'

        body([

               "client.id": $(regex('[0-9]{10}')),

               loanAmount: 99999

        ])

        headers {

            contentType('application/json')

        }

       }

     response {

        status OK()

        body([

               fraudCheckStatus: "FRAUD",

               "rejection.reason": "Amount too high"

        ])

        headers {

            contentType('application/json')

        }

       }

     } 

    2. 服务方-server (HTTP) / producer (Messaging) 端增加Spring Cloud Contract Verifier的gralde插件,它用于解析契约文件生成测试。生成测试的命令。

    ./gradlew generateContractTests  

    下面是自动生成的测试脚本


    @Test

    查看(1048) 评论(0) 收藏 分享 管理

  • 自动化测试的演进之路

    2018-08-27 18:24:45

    自动化测试演进之路
    https://mp.weixin.qq.com/s/NpYtrfv_0r-14oUzVJgkmw
  • 朱少民:敏捷测试的思考和新发展

    2018-06-05 11:37:56


    TDD 向ATDD、BDD转化?

    以前人们谈到敏捷方法,就会谈到TDD或UTDD(Unit TDD),但是究竟有多少个公司在采用TDD方法来写代码?而在采用TDD开发方法的公司中,又有多少程序员在全面使用TDD方法呢?TDD是一个纠结的问题。一方面,TDD的确是一个好东西,先写测试用例、后写代码,保证程序员第一次就把代码写对,也彻底解决了代码的可测试性问题,在代码层次上把缺陷的预防做到淋漓尽致。另一方面,多数项目很紧张,不可能给程序员足够时间去实施TDD,程序员对实现有极大兴趣,而对测试缺乏兴趣,多数程序员也不愿意或不会主动去做TDD。这样,TDD实践还存在较大困难,有比较多的争议。我看到一位作者写道:组里头TDD说了3年,据我所知,看完两本TDD名著,并坚持写单元测试的人只有我一个(我组里有开发人员15名)。

    图1 TDD和ATDD之间的关系

      为了解决TDD实施不力,在过去一年,越来越多的人关注ATDD,即验收测试驱动开发(Acceptance Test Driven Development)。从2003年开始,人们逐渐实践TDD,而ATDD 是在2007年Lasse Koskela写了一本书《测试驱动:Java开发人员的TDD和ATDD》 ,才开始引起大家的更多关注。从那时算起也有四年了,但在国内,则是最近一两年的事。当然,我们可以将TDD和ATDD结合起来使用,形成一种混合的方法模型。TDD和ATDD之间的关系,可以用图1来描述。

    接着,BDD(行为驱动开发,Behavior. Driven Development)也开始大行其道,那BDD是不是“做得比较好的TDD”呢?概念越来越多,概念的界限就难以确定,BDD可以看成ATDD的延伸,只是BDD更强调用户的视角、用户的行为,为ATDD注入了“Given,When,Then”这样特定的需求描述语言。2009年,BDD创始人在伦敦发表的“敏捷规格、BDD和极限测试交流”中,对BDD给出了如下定义:

    BDD是第二代的、由外及内的、基于拉动的(pull)、多方利益相关者的(stakeholder)、多尺度的、高度自动化的敏捷方法。它描述了一个交互循环,可以具有带有良好定义的输出(即工作中交付的结果):已测试过的软件。

    但这个定义看起来还不够好,至少让我们明白起来还有一定的困难。实际上,BDD具有自己特定的“Given,When,Then”行为描述语言,和敏捷的user story极为吻合。所以“Given,When,Then” 行为描述语言才是BDD最显著的特征。

      TDD在写测试用例时,常常会提出“我们应该先测什么”,然后针对测试的条件来填充代码,而BDD则试图换一种方式去思考问题,即问自己“预期的行为是什么?”,可能会写出结构更好的代码。说到底,BDD更关注客户的需求,通过了解客户的不同行为,对客户的需求有更深刻的理解,从而借助对需求逐渐深入的理解来驱动软件开发。

    TDD更重要的价值是其思想,就像传统的制造业,一定是先知道产品的质量标准或验收标准之后,才去设计、制造。从这个思想来看,TDD、ATDD和BDD都是一样的。不一样的是其具体的操作方法或实践,我们可以说,ATDD和BDD有一定的进步,但还没有到达完美的地步,还有提升的空间。在未来,首先就是如何灵活结合BDD、ATDD和TDD来构成一个测试体系,是一个发展方向;其次,就是在BDD、ATDD和TDD最根本的、共同的思想基础上,构成一个全新的、更完善的敏捷测试框架。后者的可能性更大。

    探索式测试的地位

    在过去一两年,在敏捷方法中探索式测试(Exploring Test,ET)也是一个热门话题,甚至有些人想用探索式测试来代替传统的用例测试(case-based test)或脚本测试(scripted test),走向另一个极端。探索式测试是对用例测试的补充,在非敏捷开发方法中也可以使用。只是在非敏捷开发方法中,有较为严格的需求规范和设计文档,有充分的时间去设计足够的测试用例,探索式测试只是作为一种辅助的手段发现一些隐藏很深的缺陷,并成为一种产品学习的工具以完善测试用例。然而,在敏捷测试中,由于迭代快、需求变化相对频繁,缺乏详细的需求描述文档和足够的设计描述文档,探索式测试发挥更大的作用,甚至在新功能测试中发挥决定性的作用。需要提醒的是,在敏捷测试中,回归测试应该仍然以用例测试为主,可以这样说,回归测试还是百分之百的用例测试。

    探索式测试,实际早在1984年就由James Bach和Cem Kaner提出来,但为什么直到最近几年才比较热呢?这主要得益于敏捷开发方法的兴起,而敏捷开发方法的兴起又得益于互联网应用的迅速扩张。大家都知道,互联网应用越来越普遍,竞争越来越激烈,迫切要求互联网应用产品发布要快,再加上许多互联网产品的开发,都极具创新性、摸着石头过河,其需求不明确,要求开发周期短,频繁发布新的版本,及时获得市场和用户的反馈,不断修正以更好地满足用户的需求。针对被测对象,所掌握的信息不够充分的情况下,探索式测试就是一种很有效的测试方法。而且,把测试过程写下来(脚本化)需要时间,在敏捷测试中,时间显得更为珍贵。如果需求变化快,脚本化的测试用例维护成本也过高、甚至是极大的浪费。探索式测试的倡议者还认为,测试执行过程应该是智力活动的过程,这一过程越善于思考、越流畅,我们越有机会发现缺陷。而用例测试方法,有太多的停顿、不够流畅,会破坏这一过程。

    在敏捷测试中,当我们没有清晰的可参照文档、没有机会创建测试,我们自然会采用探索式测试。在James A.Whittaker 的《探索式软件测试》出版之后,探索式测试再次被推向高潮,人们觉得有更多**的探索方法可以使用,例如:卖点测试法、破坏测试法、地标测试法、收藏家测试法、极限测试法、超模测试法、深巷测试法、配角测试法、强迫症测试法、取消测试法、通宵测试法、混票测试法。

    但探索式测试缺乏良好的系统性、复用性,而且有些探索执行最终被证明是没有价值的。而我们关注有价值的探索式测试,将它们记录下来,使之成为固定的测试用例,用于将来的(后继的迭代周期)回归测试。回归测试验证已有功能是否正常运行,需要良好的系统性和很高的覆盖率,确保发布产品的质量,而且回归测试是不断重复的,在极有限的时间内完成越来越多的测试任务,这需要自动化执行、高效率执行回归测试。而这一切,依赖于相对稳定的测试用例。概括起来,敏捷测试可以看成:新功能的(手动)探索式测试 + 脚本化(基于测试用例的)自动回归测试。

    敏捷测试的自动化

    没有自动化,就没有持续集成,也就没有敏捷。在敏捷测试中自动化测试就更加迫切,这一点比较容易理解,每个迭代(如Scrum中的Sprint)都在增加新的功能,而迭代周期的时间相对固定,随着时间的推移,已实现的功能越来越多,这就要求越来越多的回归测试在时间相对固定的周期内完成。如果没有自动化测试,这是不可能完成的任务。

    在过去一年中,敏捷测试的自动化又发生了哪些变化?如何重构自动化测试脚本以提高产出投入比(ROI)?下面就简单讨论一下敏捷自动化测试框架和敏捷测试工具等内容。

    敏捷测试对测试工具要求简单、实用,随时可用,而对敏捷测试来说,自动化测试框架更为重要,它将负责集成各种测试工具,包括单元测试工具和验收测试工具等,还负责与持续集成、缺陷管理系统等整个开发环境集成。作为敏捷测试的自动化框架,一般会选择轻量型、开放类型的框架。说到这种类型的框架,可以参考RobotFramework(code.google.com/p/robotframework/ )。在最近一年,其版本发布比较频繁,也日渐**。RobotFramework是基于Python开发的、可扩展的框架,所以适用于多种接口的复杂软件(如用户接口、命令行、Web Service、编程接口等)的测试。适合敏捷测试的框架还有Thoughtworks Mingle + Cruise + Twist,它能帮助测试人员和开发人员敏捷项目管理和协同工作、持续集成、测试自动化,允许使用BDD开发模式和Groovy动态语言来编写测试脚本,包括手动和自动方式来创建可复用的自动化测试脚本,并结合测试领域特定语言(DSL)实现自动化测试。无论是RobotFramework,还是Twist,它们都支持Selenium 2.0,这也反映了Selenium在敏捷自动化测试中的重要地位。当然,敏捷测试也可以采用类似Selenium 2.0+ WebDriver +PushtoTest那样的组合框架。

    敏捷测试工具很多,但对敏捷测试来说,我们更要关注能够适应ATDD或BDD的测试工具,如Cucumber、RSpec、NBehave /CBehave /JBehave、EasyB、JDave等。也可以结合先前熟悉的测试工具开展工作,例如用自己熟悉的WatiN来结合SpecFlow 完成BDD模式的自动化测试。采用传统的微软Visual Studio也是可以的,因为在其 2010版本中,增强了对敏捷测试的支持,包括:

    • 发布了Scrum流程模板Visual Studio Scrum 1.0;
    • 支持“测试优先”的开发,支持ATDD;
    • TDD的插件TestDriven.NET。

    敏捷测试管理

    基于敏捷测试的管理,更多体现了基于需求测试和基于风险测试的平衡。对于新功能测试,不仅采用探索式测试,还要考虑基于需求的测试方法,借助类似BenderRBT这样的工具,进行需求的因果分析,建立其判定表并进行优化,从而建立非常高效的测试用例,使敏捷测试跟上开发的节奏成为可能。但整个测试周期,包括跨迭代周期的回归测试,都需要对测试风险进行有效的评估,在效率和质量上达到平衡,以保证所发布的产品的质量。

    敏捷测试的管理,一定不要急躁、不要急于求成,要循序渐进获得改进,特别是从相对传统的测试方法转型到敏捷测试的团队来说,更要逐渐转型,如同敏捷方法本身所追求的“小步快跑”式迭代,这种转型本身也应被视为迭代过程,而不是突然某个早上,一切都变了。在敏捷测试管理中,不要试图通过一个迭代解决所碰到的各种问题,而是一个迭代只解决一两个问题,随着时间的推移,踏踏实实地、逐步地解决各个问题,即进入一个良性的循环,最终解决各种问题,使团队转型成功,无论在测试效率和质量上获得质的飞跃。

    在敏捷测试管理中,尽管有比较多的原则要支持,例如“以人为本、为客户创造价值、面对面的沟通、简单化、响应变化和享受乐趣”等,但最重要的是以下几个方面。

    • 持续的质量反馈:在整个开发过程中,持续关注质量,关注用户需求,发现任何阶段性成果的问题,持续向产品经理、开发人员等提供质量反馈。
    • 持续改进测试方法,不断学习新方法和提高测试技术能力,不仅和开发人员保持技术同步,而且团队成员能力保持同步成长,想方设法把工作做到极致。
    • 让团队具有很高的自我组织能力,每个成员都积极主动工作,自己能够解决自己的问题。

    让我们享受敏捷测试的乐趣,享受成功!

  • AI自动化测试:AI测试机器人即将到来

    2018-03-01 14:00:41

    或许你已经听说过人工智能(AI)。自从Allen Newell 、 Herbert A. Simon和Cliff Shaw 在十九世纪五十年代写了第一个人工智能的程序“Logic Theorist ”,人工智能开始逐渐被大家了解。
      从历史上来看,可以肯定的是,你并没有经常听说AI测试自动化。但现在事情正在发生着改变,AI自动化测试将在未来的自动化测试中发挥越来越重要的作用。
      对我来说,AI自动化测试仍然是一个相对新的概念,但它是我在自动化测试领域中积极探索的一个方向。在这篇文章中,我想借这个机会来强调一下为什么AI自动化测试如此的重要,并且将阐述AI在自动化测试中能够发挥的作用,同时也会讨论为了能最大程度地利用AI进行自动化测试我们所面临的挑战。
      AI在测试中的作用
      在如今的软件开发中,自动化测试是必要的。对广大的测试人员来说这是一个激动人心的时刻——每个人都认同进行全面测试的重要性。但是AI在测试中能够有什么作用呢?如果运用得当,它或许能够帮助我们减少很多测试工作。理论上,在我们的测试系统中我看到了两个及以上的可以用AI解决的潜在的问题。
      首先,我们可以借助AI来帮助我们进行自动化的测试管理和测试用例创建。它通过内置标准降低了工作量,并保持每个人工作的一致性。其次,可以使AI通过阅读用户故事接受标准自动生成测试代码或伪代码。最后,可以利用AI实现无代码自动化测试,它会自动在您的Web或移动应用程序上创建和运行测试,而无需编写任何代码。
      如今AI应用随处可见,从Siri、Alexa和Google Search到Google Assistant、Slackbot等。这些AI应用中的每一个都有自己特定的角色和功能。为了让AI能帮助我们进行测试,你需要为AI应用定义一个特定的目标,无论是自动化的创建测试用例,生成测试代码,实现无代码测试或其他的目标。
      训练你的AI机器人
      AI的一般概念是应用程序具有理解环境、处理输入数据并执行智能行为的能力,并且能够学习如何自动改进自身的表现。几年前,在Android Auto中,语音驱动的搜索已经出现。通过按下我的大众GTI方向盘上的一个按钮来激活Google助手,并说:“播放Chris Stapleton的音乐”,Google助手使用AI来处理输入并执行智能操作。在几秒钟内,Chris Stapleton的音乐将被播放。它增加了我每天的通勤安全,并能够更快地检索我最喜欢的音乐艺术家。
      这里有一个教训:最聪明的开发人员让错误通过,大多数时候开发团队是对Bug进行反应而不是预防。如果你是一个测试人员或者与测试人员一起工作,你就知道测试人员会问很多问题。要构建AI测试机器人,我们必须训练机器人通过提问来执行智能操作和处理输入数据,就像Google Assistant一样。随着我们不断加强识别输入模式和行为的算法,AI应用程序会变得越来越好。
      AI测试机器人面临的挑战
      AI自动化测试如果要真正的应用于实践,仍然存在一些需要被解决的问题。当你尝试构建AI应用程序进行测试时,你可能面临的挑战和问题是:
      1.识别、完善所需要的算法
      2.收集大量的输入数据来训练AI应用程序
      3.对于输入数据AI应用程序如何处理
      4.即使数据输入是新的,机器人也可以重复执行任务。
      5.训练你的AI应用程序的过程永远不会结束,因为我们需要不断地改进算法
      在许多方面,人工智能测试就像是以身作则。 这是一个艰巨的过程,但是如果做得好的话,这个过程也是值得的
      结束语
      AI不再只是流行语,它实际地在生活中应用着。同样它也能在自动化测试领域中所应用,就像它在其他领域的所带来的作用。
      如果您花一点时间思考我们每天使用的所有技术,AI已经开始默默融入我们的生活。 做好准备! 自动化软件测试的角色正处于人工智能急剧变化的边缘,AI自动化测试的时代即将到来。
  • 80后测试人员中年危机

    2018-03-01 13:10:25

    2017年网上对于“中年危机”的话题,谈不绝于耳,而前不久,更因为华为裁员34周岁以上的工程师,行业里像炸了锅。这是我们终将迎来、跨不过去的坎,测试技术人员随着年龄越大,功能测试的技能如果依然一成不变,随着40岁的到来,40岁以后的前景令人深思。


    80后90初的测试人员已经到了或者接近35岁大关,在职场上也已经工作好几年,但面临的来自工作或者生活方面的压力却越来越大。但是技能还是老样子,天天以点点点为生,流程检查几乎为职业生涯的全部。职位的核心价值缺失,大多在IT为代码组成的世界里,却对代码几乎都没掌握,每天跟操作系统及数据库打交道,却没多少认知。如今90后已经全部成年,大多数人也已经走向职场,在一些岗位更是90后占主导地位,而80后则面临很尴尬的地位。如果不是技术专业方向的技术牛人,则面临和90后一起竞争的局面。论年龄没有90后年轻,比加班又平不过90后。

    就算走上管理的80后,技能短板太明显,很多90后不服技术上或业务上没有自己强的纯管理者,有些80后管理者自己也在招聘环节中无法辨明哪些是有能力的,哪些是”水货“。有些比较幸运捡到了宝贝技术员,因技术理解深度的缺乏,无法跟技术牛人下属或开发运维相关领导,进行进行深层次的沟通,最后导致测试部门地位低下,测试团队士气低靡。

    有一同事,物流行业经过2年,然后培训转行做测试工程师工作。从WEB到手机端,从电商到银行业务。他对其他不感兴趣,只关心流程方面通不通的问题,工作好几年如今已经是公司测试部门负责人,但由于是小公司,做的事情基本还是比较杂。如今已经37岁的年纪,收入也是不上不下,谈及自己的状况,他有时候也是说很尴尬。跳槽无望,自动化测试会个半吊子,性能只会一些工具,架构诊断等不深入。年纪这么大转行也很难,想过做生意,但是问了一圈后,实业很难做,100家店铺,1年换掉半数,半辈子的辛苦钱打水漂,轻易不敢下水。

    最近几年工资涨幅已经越来越慢了。因为工作年头的资历在那儿摆着,但是,同组的另外一个同事 211 的本科毕业,比他小好几岁,工作产出的质量其实一点也不逊色于他。


    虽然大家都有责任心和主动性,但是人家更加年轻有活力,能加班,不要市场顾及家庭老小。慢慢的产生了强烈的中年危机,自己能做的工作,那些毕业1-2年的也能胜任,而自己工资还比别人高出一大截。而自己的精力却没有年轻人好,因为家庭和身体各方面原因,他加班也比较少。想在技术上深耕,成为技术专家。但是代码永远是压在自己头上的一块大石头。

    自学吧,年轻的时候尝试了好几次,终究不是碰到问题,自己无法解决,慢慢就遗忘了初衷,要么就是不知怎么的学了一小半没坚持住。

    37岁面试总是被刷下来了,(理由是年纪太大,潜力不大)。内心很忧愁,他该何去何从?

1661/9123456789>
Open Toolbar