Karate中callonce如何在Background创建2个仅初始化一次独立数据
Karate框架实现Feature级一次性初始化多份独立共享测试数据的方法
问题复现
需求为:在Feature的Background环节创建2个宠物测试数据,要求整个Feature执行周期内仅执行一次创建逻辑,所有Scenario均可共享使用这两份独立数据。初始尝试的两种写法均不满足要求:
版本1使用call关键字实现,代码如下:
Feature: Manage pets version#1 Background: * def pet1 = call read('createPet.feature'){'cat'} * def pet2 = call read('createPet.feature'){'dog'} Scenario: Get single pet Scenario: Get all pets
该写法的缺陷:call不会缓存执行结果,每个Scenario运行时都会重复触发两次宠物创建逻辑,产生大量冗余测试数据。
版本2使用callonce关键字实现,代码如下:
Feature: Manage pets version#2 Background: * def pet1 = callonce read('createPet.feature'){'cat'} * def pet2 = callonce read('createPet.feature'){'dog'} Scenario: Get single pet Scenario: Get all pets
该写法的缺陷:callonce默认以被调用的feature文件路径作为缓存key,不会自动将传入参数纳入缓存判定逻辑,第二次调用createPet.feature时会直接命中第一次调用的缓存,导致pet2返回cat类型的pet1数据,无法得到独立的dog实体。
正确实现方案
两种方案均可满足需求,可根据场景选择:
方案1:显式区分callonce缓存标识(轻量无额外文件)
给两次callonce传入不同的唯一标识参数,让框架将两次调用识别为独立的缓存任务,分别执行创建逻辑,写法如下:
Feature: Manage pets correct version Background: * def pet1 = callonce read('createPet.feature') { type: 'cat', cacheTag: 'init-cat' } * def pet2 = callonce read('createPet.feature') { type: 'dog', cacheTag: 'init-dog' } Scenario: Get single pet Scenario: Get all pets
注意:两次传入的
cacheTag参数名可自定义,只要两次参数值不重复即可让callonce分别缓存两个创建结果。
方案2:封装统一初始化逻辑(全版本兼容,稳定性最高)
将多份测试数据的创建逻辑封装到单独的初始化feature文件中,仅需一次callonce调用即可拿到所有共享测试数据,完全规避同路径feature调用的缓存冲突问题,是Karate官方推荐的多数据初始化写法。
- 首先新建初始化文件
initTestPets.feature:
Feature: 初始化宠物共享测试数据 Scenario: 一次性创建两类宠物 * def petCat = call read('createPet.feature') {'cat'} * def petDog = call read('createPet.feature') {'dog'} * return { pet1: petCat, pet2: petDog }
- 在业务测试Feature中调用该初始化文件:
Feature: Manage pets correct version Background: * def testData = callonce read('initTestPets.feature') * def pet1 = testData.pet1 * def pet2 = testData.pet2 Scenario: Get single pet Scenario: Get all pets
两种方案的适用场景:
- 方案1适合仅需初始化2-3份数据、不想额外新建文件的简单测试场景
- 方案2适合初始化数据较多、需要跨多个Feature复用初始化逻辑的复杂测试场景,在所有Karate版本中均可稳定运行,维护成本更低
内容的提问来源于stack exchange,提问作者maryam ghani
相关产品推荐
相关产品推荐

