本文来自 网易云社区
接下来是接口测试实战环节。
这个接口非常简单,HTTP Method为GET,只有一个header参数authorization(同时也会检查Cookie),返回值为一个包含个人信息的json。测试代码中,将使用HttpClient发送请求,使用TestNG控制测试流程。
首先创建一个工具类文件Ktutil.kt。虽然这个接口是GET方法的,可以直接使用HttpClient的HttpGet类型,但是考虑到以后可能会用到其他Method,因此决定仿照HttpGet的实现方式,继承HttpRequestBase类实现一个自定义的类型,代码实现如下:
internal class HttpSimpleMethods constructor(var uri:String, val METHOD_NAME:String): HttpRequestBase() {init {if(METHOD_NAME !in listOf("GET", "DELETE", "OPTIONS", "TRACE", "HEAD")){throw Exception("Method $METHOD_NAME not supported!")}ate(uri))}override fun getMethod(): String {return METHOD_NAME}
}
类似的,仿照HttpPost自定义一个类型:
internal class HttpEntityMethods constructor(var uri:String, val METHOD_NAME:String): HttpEntityEnclosingRequestBase() {init {if(METHOD_NAME !in listOf("POST", "PUT")){throw Exception("Method $METHOD_NAME not supported!")}ate(uri))}override fun getMethod(): String {return METHOD_NAME}
}
接着,封装一下HttpClient执行的过程(写过的同学可以对比一下Java的版本):
data class HttpResult(val code:String, val data:String) /** * 第二步, 执行HttpSimpleMethods类型的请求 */ fun httpSimpleRun(sp: HttpSimpleMethods): HttpResult {var client = ateDefault()var response = try {ute(sp)}catch (e:Exception){(e.toString())throw Exception("request falied") } val entity = ityval code = response.statusLine.statusCodeval data = String(entity, "utf-8")response.close()client.close()return String(), data) }
可携带body的请求类型(POST、PUT)要复杂一些,还需要一个添加body的函数:
/** * 第二步, 给HttpEntityMethods类型的请求添加body */
fun httpAddBody(em: HttpEntityMethods, data: String, type: String): HttpEntityMethods {when (type) {"json" -> em.addHeader("Content-Type", "application/json; charset=utf-8")"form" -> em.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")"xml" -> em.addHeader("Content-Type", "application/xml; charset=utf-8")else -> throw Exception("type $type not supported!") } // StringEntity,用于把字符串直接加进body,需要在之前先转换好格式 em.setEntity(StringEntity(data, Charset.forName("utf-8"))) return em }
这种类型的执行函数和上面的httpSimpleRun相同,这里就不再展示了,其实两者可以整合成一个泛型函数来处理。
最后,根据在之前部门的使用习惯,还定义了一些judge函数来进行判断,其中最常用的一个代码如下:
fun judge(desc:String, expect:Boolean, real:Boolean, debugInfo:String = ""){if(expect != real){("$desc:不通过, expect:$expect, real:$real, debug:$debugInfo")Assert.fail(desc)}else{logger.info("$desc:通过, debug:$debugInfo")}
}
工具类到此编写完毕。鉴于测试环境通常还有多套,因此我们还需要一种方式来指定测试执行的环境。由于测试的代码每次都是编译后再执行,个人习惯于直接写在类中,因此定义一个Environment.kt如下:
class Environment(env: String){var host = ""val this_env = envinit {when(this_env){"dev" -> host = """qa" -> host = "" "ci" -> host = """test" -> host = """yanlian" -> host = """public" -> host = ""}}
}
(更普遍的做法似乎是从配置文件中读取)
接下来就是对应接口了。创建一个ConsoleAPI.kt文件,给这个接口定义一个函数:
class ConsoleAPI(var host:String){val logger = Logger("ConsoleAPI")/*** @param authorization token签名* @param urs_t urs_t* @param urs_u urs_u*/fun basicInfo(authorization:String, urs_t:String, urs_u:String): HttpResult{val url = host + "/userinfo/basicInfo"var get = httpSimpleMethodInit(url, "GET")val cookie = "urs_t=$urs_t; urs_u=$urs_u"logger.info("run $url, authorization=$authorization, urs_t=$urs_t, urs_u=$urs_u")get.addHeader("authorization", authorization)get.addHeader("Cookie", cookie)return httpSimpleRun(get)}
}
然后是TestNG的环节。创建一个ConsoleTest.kt,代码如下:
class ConsoleTest constructor(){val logger = Logger("ConsoleTest") //这里是之前写JAVA时用的log4jlateinit var env: Environmentlateinit var api: ConsoleAPIlateinit var account: PrimaryAccountTestconstructor(environment: String):this(){//用于在main里调试logger.info("test start:env=$environment")env = Environment(environment)api = ConsoleAPI(env.host)account = PrimaryAccountTest(env.this_env)loginAndGetToken(true)}data class TokenInfo(var authorization:String, var urs_t:String, var urs_u:String)fun loginAndGetToken(needLogin:Boolean=false): TokenInfo {//这里调用了之前账号项目里的登录方法,返回签名authrization和Cookie里的两个值urs_t、urs_uif(needLogin){stNegotiateSecret()stLoginWithPhone()stCookieForToken()}val authorization = account.api.calTokenAuth(account.userId, kenId, kenKey, Nounce(), account.h)return TokenInfo(authorization, account.urs_t, account.urs_u)}@BeforeClass(alwaysRun = true)@Parameters("environment")fun init(environment: String) {logger.info("test start:env=$environment")env = Environment(environment)api = ConsoleAPI(env.host)account = PrimaryAccountTest(env.this_env)loginAndGetToken(true)}@Test(groups = arrayOf("p0", "all"))fun testBasicInfo(){var (authorization, urs_t, urs_u) = loginAndGetToken()var (code, data) = api.basicInfo(authorization, urs_t, urs_u)qcutil.judge("测试获取控制台用户基本信息", true, code == "200" && ains("userName"),"code=$code, data=$data)")}@Test(groups = arrayOf("p1", "all"), dependsOnMethods = arrayOf("testBasicInfo"), dataProvider = "basicInfoProvider")fun testBasicInfoFailed(desc:String, success: Boolean, authorization:String, urs_t:String, urs_u:String){var (code, data) = api.basicInfo(authorization, urs_t, urs_u)if(!success){qcutil.judge("测试获取控制台用户基本信息(非法值)-$desc", true, code=="400" && !ains("userName"),"code=$code, data=$data)")}}@DataProvider(name="basicInfoProvider")fun basicInfoProvider():Array<Array<Any>>{var (authorization, urs_t, urs_u) = loginAndGetToken()return arrayOf( arrayOf("签名错误", false, authorization.split("hash")[0], urs_t, urs_u),arrayOf("Cookie缺少urs_t", false, authorization, "", urs_u),arrayOf("Cookie缺少urs_u", false, authorization, urs_t, ""))}
}fun main(args: Array<String>) {//可以在main函数里直接启动指定的一个接口测试var test = ConsoleTest("ci")stBasicInfo()
}
最后,创建一个TestNG的xml配置文件,和以前一样执行即可:
<suite name="Suite1"><parameter name="environment" value="qa"/><test name="test1" verbose="2"><groups><run><include name="p[0-1]" /></run></groups><classes><class name=sole.ConsoleTest"/></classes></test>
</suite>
Kotlin是一门学起来像是Java框架的、吸收了C#和Python的一些优点、Google钦定、IDE给力、(日常)要火的语言。有时间的同学可以学习一下,现在看来,至少在Android领域Kotlin有很大机会取得成功。
相关阅读:
接口测试之Kotlin篇(上)
本文来自网易云社区,经作者hzsunzhengyu授权发布。
了解 网易云 :
网易云官网:
云创大会0元抢购早鸟票:
云产品全面促销5折起:
本文发布于:2024-01-31 22:09:20,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170671016331703.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |