系统测试利器之挡板实战(四)

responses常用设置

响应这块主要分三部分:代理模式、脚本注入以及利用shell脚本的动态行为。

代理

代理是mb是responses的一个配置项,与注射相媲美,支持记录、缓存行为,可以对其head、body进行修改,
可轻松捕获测试场景的丰富测试数据集。
代理就是给个地址,代理访问下录制各种场景的响应报文,录制以后我们可以设为静态服务响应数据。

"stubs": [{
  "responses": [{
    "proxy": {
      "to": "http://localhost:8083/mockjs"
            ....
    }
  }]
}]

proxy参数如下:

参数 默认 类型 描述
to 需要 代理的url地址,带http的全路径 定义请求应代理的源服务器。
predicateGenerators [] 数组 一组对象,用于定义如何创建新存根的谓词,就是为了生成谓词的配置,数组中的每个对象都定义了从中生成谓词的字段。请参阅下面 的示例。
mode proxyOnce proxyOnce、proxyAlways、proxyTransparent proxyOnce 相同的条件只访问代理地址一次,获取的响应数据会缓存在本地。proxyAlways缓存所有响应数据,要和mb replay 配合使用,否则缓存数据越来越多,proxyTransparent模式代理请求但不记录任何数据
addWaitBehavior false 布尔 如果为true,则mountebank将以wait 与代理调用相同的延迟为响应添加行为。这在您希望模拟正在虚拟化的下游服务的实际延迟的性能测试场景中非常有用。
addDecorateBehavior null 字符串,JavaScript 对已缓存的响应修改数据

从这几个参数开始我们逐步学习下mb的代理功能。

predicateGenerators 请求的条件判断

predicateGenerators 数组中的每个对象都包含以下字段:

参数 默认 类型 描述
matches {} 宾语 用于定义如何创建新存根的谓词,关键是定义、新建,相当于代码生成模板
caseSensitive false 布尔 确定匹配是否区分大小写,包括查询参数等对象的key。
except "" 定义在匹配之前从请求字段中剥离的正则表达式。
xpath null 宾语 (业务场景不多,可忽略)定义包含selector字符串的对象,以及可选的ns定义命名空间映射的 对象字段。谓词的范围仅限于请求字段中的选定值。
jsonpath null 宾语 业务场景不多,可忽略)定义包含selector字符串的对象。谓词的范围仅限于请求字段中的选定值。

如下面的代码设置matches的一个值为query。

"stubs": [{
  "responses": [{
    "proxy": {
      "to": "http://localhost:8083/mockjs",
      "predicateGenerators": [{
        "matches": {
          "query": { "q": "mountebank" }
        }
      }]
    }
  }]
}]

那么访问 http://localhost:8082/mockjs?q=mountebank 以后生成的谓词如下:

"stubs": [
  {
    "predicates": [{
      "equals": {
        "query": { "q": "mountebank" }
      }
    }],
    "responses": [{
      "is": { ... }
    }]
  }
    ]

如果是 http://localhost:8082/mockjs?q=mountebank1 ,那么生成的谓词是"query": { "q": "mountebank1" }

mode定义代理的行为

proxyOnce - 确保相同的请求(由谓词定义)永远不会被代理两次。mountebank仅记录每个请求的一个响应,并在下次请求谓词匹配时自动重放该响应。

proxyAlways - 将代理所有呼叫,允许为同一逻辑请求保存多个响应。利用这个模式必须及时把代理删除,否则生成的谓词将很多,

mb replay --port 2525
#命令执行后,代理模式清除,只有录制的谓词提供服务

proxyTransparent - 请求访问透传不做记录处理。

injectHeaders修改请求头

顾名思义就是通过代理请求而相应数据的http的head追加一些属性。

            "responses": [{
                "proxy": {
                    "to": "http://localhost:8083/mockjs",
                    "mode": "proxyOnce",
                    "addWaitBehavior": true,
                    "injectHeaders": {
                        "X-My-Custom-Header-One": "my first value",
                        "X-My-Custom-Header-Two": "my second value"
                    }
                    }}]

那么会在响应的head上追加了两行数据,具体如下:

Cache-Control →no-cache
Postman-Token →5aa8b6d1-c6aa-4660-93b5-af416bb87b55
host →localhost:8083
cookie →BDSVRTM=0
accept-encoding →gzip, deflate
Connection →keep-alive
X-My-Custom-Header-One →my first value
X-My-Custom-Header-Two →my second value
Date →Sun, 19 May 2019 15:28:21 GMT
Transfer-Encoding →chunked

mb考虑的很周到,通过代理可以录制谓词,录制的数据可以提供修改http的head、body,那么下面就是介绍下怎么修改响应的数据了。

addDecorateBehavior修改已保存的响应
"responses": [{
                "proxy": {
                    "to": "http://localhost:8083/mockjs"
                    },
                    "addDecorateBehavior": "<%- stringify(filename, './test/proxy.ejs') %>"
                }
            }]
//proxy.ejs代码,也是通过EJS模板调用,便于代码熟悉及维护
function(request, response) {
    response.body = response.body + ' DECORATED!123456';
    console.log("function(request, response)");
}

那么生成的代码如下:

"_behaviors": {
        "decorate": "function(request, response) {\r\n\tresponse.body = response.body + ' DECORATED!123456';\n\tconsole.log(\"function(request, response)\");\r\n}"
      }
addWaitBehavior

还有一个重要的参数,那就是addWaitBehavior,当为true时会记录代理请求的响应时间,方便录制的数据回放时比较逼真,说白了就是完全模拟回访。

"responses": [{
                "proxy": {
                    "to": "http://localhost:8083/mockjs",
                    "addWaitBehavior": true
                }
            }]

那么生成的代码

"_behaviors": {
        "wait": 534
      }
//534就是响应的时间

最后mb的代理就这样结束了,为了全面的了解,我把它贴出来:

//代理demo
{
    "port": 8082,
    "protocol": "http",
    "stubs": [{
            "predicates": [{
                "deepEquals": {
                    "path": "/mockjs"
                }
            }],
            "responses": [{
                "proxy": {
                    "to": "http://localhost:8083/mockjs",
                    "mode": "proxyOnce",
                    "addWaitBehavior": true,
                    "injectHeaders": {
                        "X-My-Custom-Header-One": "my first value",
                        "X-My-Custom-Header-Two": "my second value"
                    },
                    "predicateGenerators": [{
                        "matches": {
                            "query": {
                                "q": "mountebank"
                            }
                        }
                    }],
                    "addDecorateBehavior": "<%- stringify(filename, './test/proxy.ejs') %>"
                }
            }]
        }

    ]
}

http://localhost:8082/mockjs?q=mountebank2 访问生成的谓词代码:

{
    "predicates": [{
        "equals": {
            "query": {
                "q": "mountebank2"
            }
        }
    }],
    "responses": [{
        "is": {
            "statusCode": 200,
            "headers": {
                "User-Agent": "PostmanRuntime/7.11.0",
                "Accept": "*/*",
                "Cache-Control": "no-cache",
                "Postman-Token": "5aa8b6d1-c6aa-4660-93b5-af416bb87b55",
                "host": "localhost:8083",
                "cookie": "BDSVRTM=0",
                "accept-encoding": "gzip, deflate",
                "Connection": "keep-alive",
                "X-My-Custom-Header-One": "my first value",
                "X-My-Custom-Header-Two": "my second value",
                "Date": "Sun, 19 May 2019 15:28:21 GMT",
                "Transfer-Encoding": "chunked"
            },
            "body": "{\n    \"head\": {\n        \"rspcode\": \"200\"\n    },\n    \"body\": {\n        \"city\": \"山南地区\"\n    }\n}",
            "_mode": "text",
            "_proxyResponseTime": 534
        },
        "_behaviors": {
            "wait": 534,
            "decorate": "function(request, response) {\r\n\tresponse.body = response.body + ' DECORATED!123456';\n\tconsole.log(\"function(request, response)\");\r\n}"
        }
    }]
}

系统测试利器之挡板实战(一)
系统测试利器之挡板实战(二)
系统测试利器之挡板实战(三)
系统测试利器之挡板实战(五)
系统测试利器之挡板实战(六)
系统测试利器之挡板实战终结(七)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容