HttpRunner HttpRunner 的测试用例分层机制

九毫 · 2017年12月24日 · 最后由 张荣山 回复于 2018年11月01日 · 5657 次阅读
本帖已被设为精华帖!

背景描述

HttpRunner中,测试用例引擎最大的特色就是支持YAML/JSON格式的用例描述形式。

采用YAML/JSON格式编写维护测试用例,优势还是很明显的:

  • 相比于表格形式,具有更加强大的灵活性和更丰富的信息承载能力;
  • 相比于代码形式,减少了不必要的编程语言语法重复,并最大化地统一了用例描述形式,提高了用例的可维护性。

以最常见的登录注销为例,我们的测试用例通常会描述为如下形式:

- config:
name: demo-login-logoff
variable_binds:
- UserName: test001
- Password: 123456
request:
base_url: http://xxx.debugtalk.com
headers:
Accept: application/json
User-Agent: iOS/10.3

- test:
name: Login
request:
url: /api/v1/Account/Login
method: POST
json:
UserName: $UserName
Pwd: $Password
VerCode: ""
validators:
- eq: ["status_code", 200]
- eq: ["content.IsSuccess", True]
- eq: ["content.Code", 200]

- test:
name: Logoff
request:
url: /api/v1/Account/LoginOff
method: GET
validators:
- eq: ["status_code", 200]
- eq: ["content.IsSuccess", True]
- eq: ["content.Code", 200]

相信大家已经对该种用例描述形式十分熟悉了。不过,该种描述形式的问题在于,接口通常会出现在多个测试场景中,而每次都需要对接口进行定义描述,包括请求的URL、Header、Body、以及预期响应值等,这就会产生大量的重复。

例如,在某个项目中存在三个测试场景:

  • 场景A:注册新账号(API_1/2)、登录新注册的账号(API_3/4/5)、查看登录状态(API_6);
  • 场景B:登录已有账号(API_3/4/5)、注销登录(API_7/8);
  • 场景C:注销登录(API_7/8)、查看登录状态(API_6)、注册新账号(API_1/2)。

按照常规的接口测试用例编写方式,我们需要创建3个场景文件,然后在各个文件中分别描述三个测试场景相关的接口信息。示意图如下所示。

在本例中,接口(API_1/2/6)在场景A和场景C中都进行了定义;接口(API_3/4/5)在场景A和场景B中都进行了定义;接口(API_7/8)在场景B和场景C中都进行了定义。可以预见,当测试场景增多以后,接口定义描述的维护就会变得非常困难和繁琐。

接口的分层定义描述

那要如何进行优化呢?

其实也很简单,在编程语言中,如果出现重复代码块,我们通常会将其封装为类或方法,然后在需要时进行调用,以此来消除重复。同样地,我们也可以将项目的API进行统一定义,里面包含API的请求和预期响应描述,然后在测试场景中进行引用即可。

示意图如下所示。

具体地,我们可以约定将项目的所有API接口定义放置在api目录下,并在api目录中按照项目的系统模块来组织接口的定义;同时,将测试场景放置到testcases目录中。

此时测试用例文件的目录结构如下所示:

 tree tests
tests
├── api
└── v1
├── Account.yml
├── BusinessTrip.yml
├── Common.yml
└── Leave.yml
├── debugtalk.py
└── testcases
├── scenario_A.yml
├── scenario_B.yml
└── scenario_C.yml

而对于API接口的定义,与之前的描述方式基本一致,只做了两点调整:

  • 接口定义块(block)的标识为api
  • 接口定义块中包含def字段,形式为api_name(*args),作为接口的唯一标识ID;需要注意的是,即使api没有参数,也需要带上括号,api_name();这和编程语言中定义函数是一样的。
- api:
def: api_v1_Account_Login_POST($UserName, $Password)
request:
url: /api/v1/Account/Login
method: POST
json:
UserName: $UserName
Pwd: $Password
VerCode: ""
validators:
- eq: ["status_code", 200]
- eq: ["content.IsSuccess", True]
- eq: ["content.Code", 200]

- api:
def: api_v1_Account_LoginOff_GET()
request:
url: /api/v1/Account/LoginOff
method: GET
validators:
- eq: ["status_code", 200]
- eq: ["content.IsSuccess", True]
- eq: ["content.Code", 200]

有了接口的定义描述后,我们编写测试场景时就可以直接引用接口定义了。

同样是背景描述中的登录注销场景,测试用例就描述为变为如下形式。

- config:
name: demo
variable_binds:
- UserName: test001
- Password: 123456
request:
base_url: http://xxx.debugtalk.com
headers:
Accept: application/json
User-Agent: iOS/10.3

- test:
name: Login
api: api_v1_Account_Login_POST($UserName, $Password)

- test:
name: Logoff
api: api_v1_Account_LoginOff_GET()

不难看出,对API接口进行分层定义后,我们在测试用例场景中引用接口定义时,与编程语言里面调用函数的形式基本完全一样,只需要指定接口的名称,以及所需传递的参数值;同样的,即使没有参数,也需要带上括号。

实现接口的分层定义描述后,我们就可以避免接口的重复定义。但是,我们回过头来看之前的案例,发现仍然会存在一定的重复。

如上图所示,场景A和场景C都包含了注册新账号(API_1/2)和查看登录状态(API_6),场景A和场景B都包含了登录已有账号(API_3/4/5),场景B和场景C都包含了注销登录(API_7/8)。

虽然我们已经将接口的定义描述抽离出来,避免了重复的定义;但是在实际业务场景中,某些功能(例如登录、注销)会在多个场景中重复出现,而该功能又涉及到多个接口的组合调用,这同样也会出现大量的重复。

接口的模块化封装

玩过积木的同学可能就会想到,我们也可以将系统的常用功能封装为模块(suite),只需要在模块中定义一次,然后就可以在测试场景中重复进行引用,从而避免了模块功能的重复描述。

具体地,我们可以约定将项目的所有模块定义放置在suite目录下,并在suite目录中按照项目的功能来组织模块的定义。

后续,我们在testcases目录中描述测试场景时,就可同时引用接口定义和模块定义了;模块和接口的混合调用,必将为我们编写测试场景带来极大的灵活性。

此时测试用例文件的目录结构如下所示:

 tree tests
tests
├── api
└── v1
├── Account.yml
├── BusinessTrip.yml
├── Common.yml
└── Leave.yml
├── debugtalk.py
├── suite
├── BusinessTravelApplication
├── approve-application.yml
├── executive-application.yml
├── reject-application.yml
└── submit-application.yml
└── LeaveApplication
├── approve.yml
├── cancel.yml
└── submit-application.yml
└── testcases
├── scenario_A.yml
├── scenario_B.yml
└── scenario_C.yml

需要注意的是,我们在组织测试用例描述的文件目录结构时,遵循约定大于配置的原则:

  • API接口定义必须放置在api目录下
  • 模块定义必须放置在suite目录下
  • 测试场景文件必须放置在testcases目录下
  • 相关的函数定义放置在debugtalk.py

至此,我们实现了测试用例的接口-模块-场景分层,从而彻底避免了重复定义描述。

脚手架工具

得益于约定大于配置的原则,在HttpRunner中实现了一个脚手架工具,可以快速创建项目的目录结构。该想法来源于Djangodjango-admin.py startproject project_name

使用方式也与Django类似,只需要通过--startproject指定新项目的名称即可。

$ hrun --startproject helloworld
INFO:root: Start to create new project: /Users/Leo/MyProjects/helloworld
INFO:root: created folder: /Users/Leo/MyProjects/helloworld
INFO:root: created folder: /Users/Leo/MyProjects/helloworld/tests
INFO:root: created folder: /Users/Leo/MyProjects/helloworld/tests/api
INFO:root: created folder: /Users/Leo/MyProjects/helloworld/tests/suite
INFO:root: created folder: /Users/Leo/MyProjects/helloworld/tests/testcases
INFO:root: created file: /Users/Leo/MyProjects/helloworld/tests/debugtalk.py

运行之后,就会在指定的目录中生成新项目的目录结构,接下来,我们就可以按照测试用例的接口-模块-场景分层原则往里面添加用例描述信息了。

总结

如果看到这里你还不明白测试用例分层的必要性,那也没关系,测试用例分层不是必须的,你还是可以按照之前的方式组织测试用例。不过当你某一天发现需要进行分层管理时,你会发现它就在那里,很实用。

最后,在HttpRunner项目的examples/HelloWorld目录中,包含了一份完整的分层测试用例示例,相信会对大家有所帮助。

附言 1  ·  2018年02月09日

HelloWorld 示例已经上传。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 97 条回复 时间 点赞

哈哈,今天占到沙发了
最近一直在学习你的测试框架;随便也学习了yaml,和flask web开发j;收益非常多,非常感谢你!
目前已打算在项目中使用。

meiyo 回复

好的,有问题跟我反馈就好啦

更新的很快!期待HttpRunner变得更好。努力学习中。。

学习一下

学习了 赞👍👍👍

支持啦~~ 不错。。

@debugtalk 你好 git 上 https://github.com/HttpRunner/HttpRunner/tree/master/examples 下并没有你提到的 HelloWorld
“最后,在HttpRunner项目的examples/HelloWorld目录中,包含了一份完整的分层测试用例示例,相信会对大家有所帮助。”

思寒_seveniruby 将本帖设为了精华贴 12月26日 22:55

招人啦招人啦,想跟楼主一起工作,速度简历投过来

小马 回复

我也刚想问这个问题

@debugtalk 大神,如果我要在测试用例里面使用同一个方法里返回的两个值,有语法可以实现吗?
类似这样:

def get_talk_ttkey():
str1 = 'a'
str2 = str1 + 'b'
return str1 , str2

代码简单了些,就是说我在报文里用到的两个参数,它们之间是有关联关系的,只能在一个方法里生成.

在YAML文件里试了好几种语法都不行, 不知道是我用错了语法,还是这个暂时没法实现呢?

variables:
- talk_ttkey: ${get_talk_ttkey()}
- ttkey_value : $talk_ttkey[0]
- talk_value : $talk_ttkey[1]
variables:
- ttkey_value : ${get_talk_ttkey()}[0]
- talk_value : ${get_talk_ttkey()}[1]
variables:
- ttkey_value : ${get_talk_ttkey()[0]}
- talk_value : ${get_talk_ttkey()[1]}

很棒的帖子,想了解下 你自己这边写的框架,是否有跟jmeter的测试数据做对比呢,框架对资源的消耗 是否会影响测试数据的不准确?

九毫 #13 · 2018年01月02日 作者
yyy 回复

针对你说的这种场景,当前的确没法比较优雅的实现,但是也能实现。

def get_talk_ttkey():
str1 = 'a'
str2 = str1 + 'b'
return str1 , str2

def get_str1(content):
return content[0]

def get_str2(content):
return content[1]
variables:
- talk_ttkey: ${get_talk_ttkey()}
- ttkey_value : ${get_str1($talk_ttkey)}
- talk_value : ${get_str2($talk_ttkey)}

后续我再想下是否有更好的方式吧。

九毫 #14 · 2018年01月02日 作者

这个对比其实就是Locust和Jmeter的对比;我还没有做过,后面我试下哈。

九毫 回复

这样确实可以解析出来,谢谢~~😊

@debugtalk 请问这种情况可以做到吗? test B里面要使用test A的变量.
因为这个变量跟随机数有关,每个用例的随机值都不一样,所以不能放到config里面...

我只能想到的是,testA一个文件夹,放一个debugtalk.py , testB一个文件夹,放一个debugtalk.py.
执行A的时候,把B需要的变量写入到testB文件夹的debugtalk.py,然后testB直接调自己文件夹里的这个变量😁

九毫 #17 · 2018年01月03日 作者
yyy 回复

感觉你把问题复杂化了。
我先问下,你的talk_ttkey: ${get_talk_ttkey()}在单个测试场景中需要调用多次么?还是说只生成一次talk_ttkey就行了?

九毫 回复

是只生成一次的。

九毫 #19 · 2018年01月03日 作者
yyy 回复

只生成一次,那就可以把talk_ttkey: ${get_talk_ttkey()}放置到config中;另外,我看到你的aes_key在第一个test中都没有使用,干嘛不就在第二个test中定义?

九毫 回复

是的 放在config里就行了.🙏 我上午不知道怎么搞懵了..误以为在config里的方法,每个test都会调用.

你好,suite文件夹下的模块定义是如何写的?在testcase中是如何引用模块定义的呢?
git 上 https://github.com/HttpRunner/HttpRunner/tree/master/examples 下并没有你提到的 HelloWorld
谢谢!!😀

九毫 #22 · 2018年02月09日 作者

HelloWorld 示例已经上传。

九毫 回复

谢谢!我已经知道suite如何实现的了

D:\echart2\HttpRunner-master\examples\HelloWorld\tests\testcases>hrun smoketest.yml
Traceback (most recent call last):
File "C:\Users\dell\AppData\Local\Programs\Python\Python36\Scripts\hrun-script.py", line 11, in
load_entry_point('HttpRunner==0.9.0', 'console_scripts', 'hrun')()
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\cli.py", line 70, in main_ate
task_suite = TaskSuite(testset_path)
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\task.py", line 57, in init
testsets = testcase.load_testcases_by_path(testcase_path)
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\testcase.py", line 201, in load_testcases_by_path
testset = load_test_file(path)
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\testcase.py", line 418, in load_test_file
test_info = get_testinfo_by_reference(ref_name, "suite")
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\testcase.py", line 444, in get_testinfo_by_reference
test_info = get_test_definition(func_name, ref_type)
File "c:\users\dell\appdata\local\programs\python\python36\lib\site-packages\httprunner\testcase.py", line 479, in get_test_definition
raise exception.SuiteNotFound(err_msg)
httprunner.exception.SuiteNotFound: suite setup_and_reset not found!

楼主好,请问运行demo 以后报这个错,这是什么问题?

九毫 #25 · 2018年02月12日 作者

@a1l9e8x6 你运行时所在的目录不对,应该在 HelloWorld 的根目录

26楼 已删除
九毫 回复

谢楼主,可以了

在编写用例过程中发现,需要在suite中引用其他suite的接口,能实现不?

九毫 #29 · 2018年02月27日 作者
马尾 回复

可以,所有的接口都定义在 api 中,在suite中都是引用。

九毫 回复
- config:
name: "forward_emoj"
def: forward_emoj($sid,$topic,$content,$attachments,$content_emoj)

- test:
name: upload_emoj
suite: upload_emoj($sid,$topic,$content,$attachments,$topic,$content_emoj)

以上为具体suite,在suite中引用其他的suite会报错如下,麻烦看看是不是引用语法不对。

httprunner.exception.SuiteNotFound: suite upload_emoj not found!

@debugtalk

api
suite
testcases

这么分,起名起的脑仁子疼. 能不能推荐或整理个 命名原则规范.....

九毫 #32 · 2018年02月28日 作者
小马 回复

在整理了,这块儿的确规范还不清晰

仅楼主可见

请教一个问题,output 标签是用来干什么的呢?在config和test中都可以使用吗?

九毫 #35 · 2018年03月07日 作者

@Nuanyang2333 @Donly 当前 output 关键字是用在 config 中,可以将整个用例集的部分extract内容输出。
这块儿我还没有想清楚,所以还没有写文档进行介绍。

九毫 回复

原来如此

九毫 回复

ok.
还有另外一个问题需要请教一下,debugtalk.py中定义的变量,能在suite和api中直接引用吗?request,header有底层覆盖上层的功能吗?
这边使用如下:
在suite中定义了base_url,在case中也定义了。但两者是不同的。
最后执行case后,发现使用的是case中的base_url,却不是suite中的。。。。

因为我们系统涉及到多个不同模块的端口是不一样的,所以没有办法使用同一个request和header。所以我希望在case中登录后,拿到token,放到后续接口的header中,然后再对不同的端口,执行具体模块的操作。
具体配置如下:
debugtalk.py定义:

case:

suite:

api:

def api(*args),*args参数不添加也是可以的吧,只要config中定义了api里面用到的变量

九毫 #39 · 2018年03月21日 作者
张艳祺 回复

需要添加的;在运行时会进行参数映射。

遇到个情况,html的报告log中,response的中文显示为乱码,

楼主您好,我有个疑问想请教下。比如说1条用例需要调用3个接口,3个api封装到1个suite中,suite中有3个 - test 集合,testcases中只有一个- test集合仅调用suite中定义的方法,按我理解的这种情况只算是运行1条用例,但实际测试报告中会统计成3条用例。如果用例传参不同又分3个场景,此时测试报告的用例数就是 3*3 条,这样测试报告的用例数量太多重复了。

九毫 #42 · 2018年03月25日 作者
hyman 回复

的确会存在这样的问题。当前统计测试用例条数的时候,是根据实际请求的次数(api调用次数)来统计的。这块儿我再想下怎么优化吧。

九毫 回复

楼主你好,有个情况帮我看下:1.我hrun场景A,然后场景A会生成一个ID,我再hrun场景B的时候要用到这个ID。

这个ID要怎么存,然后hrun场景B的时候怎么引用。

九毫 #44 · 2018年03月27日 作者
caige 回复

你可以将 A 和 B 分别放置到两个 suite 中,然后在 testcase 中引用 A 和 B;从 A 中 extract 的 ID 在 B 中也是可以引用的。

九毫 回复

谢谢楼主,ERP系统,一个场景无关接口一大堆,所以目前还没用分层思想,接口太多了。

仅楼主可见
九毫 #47 · 2018年04月12日 作者
Imp 回复

使用分层运行时,需要你运行命令时处于项目根目录。

$ hrun tests/testcases/smoketest.yml
仅楼主可见
九毫 #49 · 2018年04月12日 作者
Imp 回复

嗯,在运行前会先加载 api 和 suite 目录。

@debugtalk 问下大神,关于output 具体如何使用,我在用的时候在控制台没有输出我想要的数据,是一定要在config你配置吗

九毫 #51 · 2018年05月04日 作者
吴佳佳 回复

在config中配置后,执行时若使用 debug 模式,则会在运行结果末尾打印出 output 值。

仅楼主可见
九毫 #53 · 2018年05月07日 作者
回复

升级到 1.4.1 再试下

仅楼主可见
九毫 #55 · 2018年05月09日 作者
回复

可以这样

- test:
name: XXX
api: xxx
validate:
- str_eq: ["content.openid", 15004448]
仅楼主可见
九毫 #57 · 2018年05月12日 作者
回复

可否到github上提个issue?

九毫 回复

好的

您好,suite文件夹下的模块定义是如何写的?在testcase中是如何引用模块定义的呢?
git 上 https://github.com/HttpRunner/HttpRunner/tree/master/examples 下可能链接失效了 404,并没有你提到的 HelloWorld
谢谢!!😀 麻烦告知一下,谢谢您,

请教一下,testcase里面是不能再写validate了吗?

riku 回复

可以的

回复

是写在test里面还是config里面呢,我试过好像不行啊,有啥要求吗

riku 回复

都可以的,看下文档多试下,或者帖下代码看看

@debugtalk 下午好,我在写用例时发现User-Agent直接赋值,用例是运行通过的。但是通过$传参后就报错

明明 回复

“&”传不了值吧。。。

回复
- config:
parameters:
- companyCode-companyName-companyAddress-provinceName-cityName-countyName-hasCertify-pollutionFactor-illegalType-officers-situation-advice-imgUrl-createdBy-except_code-except_message: ${parameterize(patrolRecord_NG_testcase1.csv)}
request:
base_url: http://10.1.170.85:80/
method: POST
headers:
Content-Type: "application/x-www-form-urlencoded"


- test:
name: patrolRecord_savePatroRecordNG
suite: patrolRecord_savePatroRecordNG()
validate:
- eq: ["content.code",$except_code]
- eq: ["content.message",$except_message]

测试报告:

第一条- eq: ["content.code",$except_code],就没有做校验啊
会不会是不支持参数引用的校验?

riku 回复

有2种思路:
1.你可以试试 先在variables下 定义个参数接收$except_code 再将该参数传到 validate 里面去试试
2.参考下https://testerhome.com/topics/11207 里面的
断言方式,已经有 判断 值为空的断言
祝你排坑成功

回复

作为一个测试,我表示忏悔😂 😂 😂

仅楼主可见
70楼 已删除

我也是同求解答~~~

珂珂可可 回复

你这个应该是yml文件内容格式错了,如果对 YAML 或 JSON 格式不太了解的话,建议参考下用户手册里录制生成测试用例的方法,得到json文件或者yml文件后根据实际情况编辑更改即可。http://cn.httprunner.org/testcase/recorder/

蒲公英 回复

windows上,一般用什么工具生成har文件呀?也是Charles Proxy吗?

珂珂可可 回复

嗯,这个工具windows、Mac系统都能用,按手册里生成的方法就行。

@debugtalk 楼主好,请教一下,如果case里调用debugtalk.py文件里定义的函数时,需要传入的参数是字符串,要怎么处理呢?我试了下如果传入参数是数字的话是可以的,字符串一致没找到好使的方法


九毫 #76 · 2018年07月23日 作者
蒲公英 回复

这个地方当前的确处理的不好,匹配函数名称和参数的时候是采用的正则匹配。

建议对于复杂类型的参数,可以先将参数值赋值给一个变量,然后在调用函数的时候传入引用变量。

- test:
variables:
- url: "api/users/login"
request:
url: ${get_1010hr_url($url)}
九毫 回复

好的

@debugtalk ,https://github.com/HttpRunner/HttpRunner/issues/299这个问题啥时候能够解决啊,迫在眉睫

九毫 #79 · 2018年07月26日 作者
吴佳佳 回复

已经排期了,近期会重点梳理下分层机制。

80楼 已删除
蒲公英 回复

请问一下,我用csv保存数据在yml中引用的时候老师运行报错是怎么回事呀? 然后我把引用去掉直接写值就不会报错

你上面只写到了api和testcases的格式,没有写到suite的可是,api用 -api标识,testcases用 -test, suite的用 -suite么?

请问一下,可以用hrun 多场景运行么?

蒲公英 回复

这个问题建议看下,我这边也遇到这个问题,关键还是代码层处理的问题,代码查找是查找相对路径,直接扫描HttpRunner文件夹下的tests目录导致(就是我注释掉的地方),其他代码忽略,我自己这边为了调试,直接改的

目前单独创建用例文件夹是跑不了case,直接报用例文件找不到

@debugtalk 最近发现了你的测试框架 发现功能很强大,但是有需求需要debug调试,请问下,要怎么在pycharm里面进行debug调试啊

追加:
已找到在pycharm的调试方法

@debugtalk 运行用例 函数里面调用debugtalk.py里面的函数,报下面的错

追加:已解决(环境 win10,修改在 Windows 下获取文件路径就 ok 了)

httprunner-docker 中提及了此贴 08月23日 14:51
ccinn httprunner-docker 支持 api 分层和 suite 化 中提及了此贴 08月24日 09:55
DarkLi 回复

怎么在pycharm调试啊,求指导。。。。
报错信息太少无法定位

riku 回复

给我个你的联系方式 我加你

testcase中可以对suite进行skip操作么?或者有类似的方法可以选择行的跳过某个suite么?
另外在debugtalk.py中可以调用api中的方法么?

gqq112 回复

@gqq112 支持skip,相关链接:http://debugtalk.com/post/HttpRunner-skip-feature/
@debugtalk 我也很想知道 在debugtalk.py中可以调用api中的方法么?

九毫 #94 · 2018年09月10日 作者

@gqq112 @DarkLi 在 API 中定义的是接口描述,在 debugtalk.py 中是没法进行引用的。

九毫 回复

@debugtalk 最新版本不支持 -test:(testset)级别的参数化了么 ,这个功能对我们现在的测试场景非常重要 ,请问能支持么

九毫 #96 · 2018年09月10日 作者
DarkLi 回复

对于测试用例(testcase,配置在config中)层面的参数化还是支持的;
对于测试步骤(teststep,配置在test中)层面的参数化不支持了。

九毫 回复

😭 😭 现在就是急需teststep层面的参数化 惆怅啊

能不能testcase,teststep都支持啊

九毫 回复

在功能性的测试中 一个case中需要调用多个接口 某些接口(主要是做数据准备的接口)需要重复调用多次准备大量数据

DarkLi 回复

这个是对api使用的skip但是在testcase里面对suite使用skip或者skipif的时候是无效的,比如下面的:

  • test:
    name: 获取城市公司门店组别

    skip: "abc"

    suite: getcity_store_group(city)

    extract:

    • companyID: output.companyID
    • storeID: output.storeID
    • groupID: output.groupID

问一下是否可以在testcae中对suite的执行结果进行校验呢?比如下面:

  • test:

    name: dialog_suggestion

    suite: dialog_suggestion(question)

    validate:

    • {"check": "content.data", "comparator": "eq_answer", "expect": chatbot_web.csv}
仅楼主可见
回复

请问一下这个问题有解答吗?我最近也遇到这个问题!

其实我想问问大家,testcases可以直接引用api中的接口吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册