这里给大家介绍一款Salesforce测试数据生成工具Apex Test Kit。
每个Salesforce开发者最终都无法逃避的一个事情就是给测试类造假数据。Apex Test kit可以帮组我们快速的创建测试数据。它提供的主要功能有以下三点:
1. 给假数据起一个好听的名字,而不是用name001, email001@example.com这样看起来很机器化的命名。
2. 给必填字段赋值,并为唯一字段建立唯一性命名规则。
3. 建立多对多对象间的关系,中间可能牵扯到任意多的对象。
1. ATKWizard类
我们先依次为Microsoft,Google,Apple循环创建100条Account,每个Account下有两条Contact。我们可以使用field()关键字干涉数据生成规则。
ATKWizard me = new ATKWizard();
me.wantMany('Account')
.total(100)
.fields(new Map<String, Object> {
'Name' => new List<String> {
'Microsoft-{{###}}',
'Google-{{###}}',
'Apple-{{###}}'
},
'Fax' => '{{1##-###-####}}'
})
.hasMany('Contact')
.referenceBy('AccountId')
.total(200)
.fields(new Map<String, Object> {
'FirstName' => '{!name.firstName(female)}',
'LastName' => '{!name.lastName}'
})
.generate();
下面是以上代码生成的数据,无法识别语义的文字段落用的是业界惯用的希腊语:
2. 建立复杂关系
大家可能会好奇,这个库对于复杂的对象关系最难可以做到什么程度。举一个CloudCraze(被Salesforce收购的B2B电商平台)中的常用对象关系:
我们可以用一句话把数据都生成出来。为了演示效果,去除了不必要的field()关键字。
ATKWizard me = new ATKWizard();
ATKWizard.Bag bag = me.wantMany('Account')
.total(2)
.belongsTo('ccrz__E_AccountGroup__c')
.referenceBy('ccrz__E_AccountGroup__c')
.total(2)
.hasMany('ccrz__E_AccountGroupPriceList__c')
.referenceBy('ccrz__AccountGroup__c')
.total(4)
.belongsTo('ccrz__E_PriceList__c')
.referenceBy('ccrz__Pricelist__c')
.total(2)
.hasMany('ccrz__E_PriceListItem__c')
.referenceBy('ccrz__Pricelist__c')
.total(4)
.belongsTo('ccrz__E_Product__c')
.referenceBy('ccrz__Product__c')
.total(2)
.hasMany('ccrz__E_ProductMedia__c')
.referenceBy('ccrz__Product__c')
.total(6)
.generate();
我们还可以对生成的数据使用同样的语法做后期处理。我们可以从ATKWizard.Bag中取到已生成的数据。
me.wantMany('ccrz__E_Product__c')
.fromList(bag.get('ccrz__E_Product__c'))
.fields(new Map<String, Object> {
'ccrz__ProductStatus__c' => 'Released'
})
.generate();
3. ATKFaker类
ATKFaker是faker.js在Salesforce平台下的移植,它是数据生成的基石。底层使用UserInfo.getLanguage() 侦测生成数据的语言。目前只支持英文。中文和日语正在逐步支持中。
ATKFaker.internet.userName();
ATKFaker.internet.email();
ATKFaker.internet.url();
ATKFaker.internet.avatar();
ATKFaker.phone.phoneNumber();
ATKFaker.phone.phoneNumber('1xx-xxx-xxxx');
ATKFaker.name.firstName();
ATKFaker.name.firstName('male');
ATKFaker.name.firstName('female');
ATKFaker.name.lastName();
ATKFaker.random.boolean();
ATKFaker.random.number(); // => 0-999
ATKFaker.random.number(99); // number(max) => 0-99
ATKFaker.random.number(5, 2); // number(precesion, scale) => 123.45
ATKFaker.lorem.words();
ATKFaker.lorem.sentences();
ATKFaker.lorem.paragraphs();
ATKFaker.dates.past();
ATKFaker.dates.past(3, '2018-08-13');
ATKFaker.dates.future()
ATKFaker.dates.future(3, '2018-08-13');
ATKFaker.dates.between('2017-08-13', '2018-08-13');
4. ATKFaker动态插值
跟faker.js类似,以上的所有帮助方法都可以用在插值(interpolation)语句中。使用 {! } Visualforce格式插入帮助方法:
ATKFaker.fake('Hello {!name.firstName(female)} {!name.lastName}!');
// => 'Hello Jeff Jin!'
使用 {{ }} Handlebars格式插入符号, #代表数字,?代表字母,*代表数字或字母:
ATKFaker.fake('{{###-###-####}}'); // => '123-456-7890'
4. ATKWizard的设计
好的类库都会源自简单的设计。本类库的设计思想来源于法师使用魔法的过程:
- 打开魔法书ATKSpellBook,开始咏唱符文,说出您的愿望:hasMany(), belongsTo(), fields()等。
-
挥舞魔法棒。执行我们的愿望,建立对象,关联关系:generate()。
Apex Test Kit 核心类
5. 限制
目前有两种图结构不支持,等library稳定了才会考虑。
-
不支持sObject有2个以上的父亲:
多个父亲
所以请不要用also()关键字构建以上对象想关系,多数情况请使用hasMany()来接also()关键字,而不是用belongsTo():
ATKWizard me = new ATKWizard();
me.wantMany('D')
.belongsTo('A')
.also()
.belongsTo('B')
.also()
.belongsTo('C')
.generate();
-
不支持有向无环图
有向无环
目前的语法和底层也不支持这种结构。
还有一些后续的任务需要完善,比如:
- 移植更多的faker.js领域语言和翻译。
- 性能优化,特别是字符串拼接,没有StringBuilder可用。
- 处理未发现的bug等。
小结
Apex Test Kit还在beta测试阶段,预计2018年10月分可以上线。欢迎参与,提Bug,和给星星。给您带来的方便就是我持续的动力。