接口测试之——Karate框架搭建

相信做过接口测试的童鞋都习惯用Jmeter, Rest-Assured,Postman来编写,可能对Karate还比较陌生。Karate DSL是一种新的API测试工具,它帮助以一种简单的方式为基于API的BDD测试创建场景,而无需编写步骤定义。之前项目用Karate做API测试,跟着开发写了一段时间API测试代码,我发现只需一点编程基础就能轻松上手,现在Karate已经成为Top10的API工具了,于是呼我决定普及一下,说一说Karate的框架搭建。

搭建Karate框架
1.创建一个gradle/maven工程,以下以gradle为例


image.png

2.然后在build.gradle文件里添加所需要得jar包
testCompile 'com.intuit.karate:karate-junit4:0.9.2'
testCompile 'com.intuit.karate:karate-apache:0.9.2'
3.再在build.gradle里添加以下配置(为什么要添加这个配置呢,因为Karate测试有文件扩展名.feature,一般gradle是将非java源文件存放在src/test/resources结构中,配置这个得目的是将非java源文件与.java文件可以放在并排的位置,让程序知道src/test/java下.java以外的文件都是资源文件)

sourceSets {
test {
resources {
srcDir file('src/test/java')
exclude '*/.java'
}
}

image.png

4.添加日志配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/karate.log</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.intuit.karate" level="DEBUG"/>
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
image.png

5.添加karate配置文件 karate-config.js
这里面的配置都是全局配置,在执行每个Scenario前都会先获取karate-config里的配置,当然不存在这个文件也可以正常工作,具体根据你的工程来决定。karate.configure可以设置很多参数的值,具体可以参见git hub上Managing Headers, SSL, Timeouts and HTTP Proxy,这里有一个例子:
image.png

我们项目的配置:

function config() {
karate.configure('connectTimeout', 10000);//设置连接超时时间10s
karate.configure('readTimeout', 10000);//设置读取超时时间10s
karate.configure('logPrettyRequest', true);//使用缩进打印请求
karate.configure('logPrettyResponse', true);//使用缩进打印响应
karate.configure('retry', {count: 3, interval: 2000});//设置重试机制为3次,间隔时间为2s
var env = karate.env;//获取java系统属性“kara .env”,跑流水线时传入env参数值,可以在不同的环境运行api测试
if (!env) {
env = 'sit';
}
var config = read('classpath:karate-env.json')[env];
//这里是读取env配置文件,相当于我们是把上面例子的config文件写在了一个karate-env.json文件中,由于我们有多个环境,每个环境以对象的形式存储,当想获取某个环境的数据时,直接把对象名传过去就能获取到该环境的所有全局变量了
var customerInfo = karate.callSingle(
'classpath:apiTests/toC/common/customer/customer.feature', config);
//这里使用 karate.callSingle方法将配置传入customer.feature文件下面,也可以使用call方法,callSingle与call方法的区别是执行Scenario时call每执行一次调一次,而callSingle只会在第一次执行时调用,后面取之前执行的缓存。customer.feature是用来获取用户token的

config.customerToken = customerInfo.customerToken;
config.customerId = customerInfo.customerId;
return config;
}


image.png

6.添加运行案例的类

由于我们希望用例并行运行,这里面我们使用Runner.parallel方法,可以参考官方文档


image.png

下的DemoTestParallel类,如果是想串行运行,直接用@RunWith(Karate.class)即可。

@Test
public void testParallel() {
Results results = Runner.parallel(getClass(), 5);//设置5个线程,并行运行
generateReport(results.getReportDir());//输出报告,在执行每个特性之后,HTML报告将输出到target/surefire-reports文件夹,你也可以自己定义报告输出路径
Assert.assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
}

public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "demo");//这里的target填写报告文件根目录,demo是填写你的工程名称
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
这里由于有些包没有引入导致部分类找不到,需要在gradle下引入这些包:
testCompile 'commons-io:commons-io:2.5'
testCompile 'net.masterthought:cucumber-reporting:3.8.0'


image.png

在这里,如果我们不想要全部案例都运行,我们可以使用@KarateOptions 注解,
可以选择想要运行的案例,例子:

//运行1个feature
@KarateOptions(features = "classpath:animals/cats/cats-post.feature")
//运行多个feature
@KarateOptions(features = {
"classpath:animals/cats/cats-post.feature",
"classpath:animals/cats/cats-get.feature"})
//运行features 在classpath:animals/cats路径下的,且tag非@ignore的
@KarateOptions(features = "classpath:animals/cats", tags = "~@ignore")
//运行tags为非@ignore,且含@customer、@bargain的
@KarateOptions(tags = {"~@ignore", "@customer", "@bargain"})

7、下面可以开始写feature了,feature格式如下:
Feature \描述该特性的测试内容
Background\这里是场景执行的前置条件,一般在这里定义该特性的全局变量,在每个Scenario执行前都会执行
Scenario\这里是执行步骤,如我要测试创建拼团活动的api,对拼团活动进行创建,判断是否创建成功
Feature: brief description of what is being tested
more lines of description if needed.

Background:
-this section is optional !
-steps here are executed before each Scenario in this file
-variables defined here will be 'global' to all scenarios
-and will be re-initialized before every scenario

Scenario: brief description of this scenario
-steps for this scenario
Scenario: a different scenario
-steps for this other scenario
如下,是一个创建商品的feature,在接口测试中,有几个最重要的项:
1、url
2、header
3、请求参数
首先,我们要保证我们拿到的接口能正常调通,可以在postman试验

image.png

可以看到,我们在background里配了url及headers,background里的配置运用于所有的scenario,然后定义参数,这里我们使用read()方法读取variables.json文件获取入参,然后使用post方式发送请求,获取response,比较response和期望的结果是否一致,如果一致就pass,不一致就抛出错误。
image.png

在运行过程中,可能会抛出如下错误
image.png

那是因为我们没有添加log4j2的配置文件,只需添加log4j2.xml文件即可,或者把官方文档karate.demo下的log4j2.properties的文件copy过来也行
如果我们想创建多个商品呢?我们可以写一个方法执行for循环,调用feature多次,如下是用js写的一个方法:
因为创建多个商品时的code不一样,所以需要传入参数到createProduct.feature中,这里我们传入了一个对象进去
image.png

现在createProduct.feature也需要优化一下了,把入参传给对应的值
image.png

然后,我们需要再写一个feature,传入开始和结束值,来调用该function,这样就能创建多个商品了
image.png

当然,Karate的功能远不止我说的这些,如果想要了解Karate更多用法的可以直接访问它的官方文档查看 ~ https://github.com/intuit/karate

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

推荐阅读更多精彩内容