Kotlin如何在API测试中提供帮助:Rusfinance Bank的案例





Kotlin的名称声称与Android开发更相关,但是为什么不做实验呢?在它的帮助下,我们找到了一种方法,可以稍微简化测试其中一项服务的API的自动化,并简化不熟悉编程和Java语言细微差别的测试人员的工作。



我们在做什么?我们正在开发一种服务,用于发送经纪调查表以计算和接收有关它们的决定。尽管事实上这是一个银行解决方案,但开发工作还是由一个小的Scrum团队进行的,该团队中有1-2位专家参与测试,具体取决于项目的负载和情况。



削减后,我们将向您介绍我们的实验结果,我们很高兴将其转移到生产中。



没有脸



我们的服务是为了与合作伙伴的界面集成而开发的,没有自己的UI。因此,在这种情况下,直接测试API是唯一可用的选项。尽管API测试即使具有接口也具有许多优点:



  • 允许您在开发服务的阶段就已经开始测试;
  • 简化错误定位;
  • 通常会减少测试时间。


我们的服务包括一组API,用于传输客户调查表中的数据以进行计算并获得汽车贷款解决方案。以下检查可以区分为主要的高级测试任务:



  • 字段和参数的格式;
  • 状态代码和错误消息的正确性;
  • 必填字段和服务逻辑。






关键时刻



团队在很短的时间内准备了服务的MVP,而自动化测试最初是由产品开发人员编写的。在项目中包含自动测试更快,更方便,因此最初它们与它的代码紧密相关,并且基于Java堆栈,REST保证的和TestNG测试框架。



随着项目的发展,测试人员在自动化过程中的参与不断增加。目前,支持和更新自动测试的任务完全由测试部门承担。在这方面,有必要调整自动化方法-尽可能简化测试并使它们独立于主代码。因此,为了解决出现的困难:



  • 与代码的通信使测试更容易受到任何设计更改的影响,需要大量人力来保持性能;
  • 复杂的关系增加了查找信息和调查错误的时间;
  • 要让测试部门的新员工参与Java代码的工作很困难,这需要测试人员的培训和大量时间才能进入项目。


因此,我们决定更改测试方法,并对新工具制定了以下要求:



  • 与Java完全兼容,允许您分阶段重写检查,同时继续使用旧测试;
  • 简单,直观的代码;
  • 自由和稳定的语言;
  • 在一个单独的项目中选择自动测试。




Kotlin与它有什么关系



Kotlin语言尽可能满足我们的需求。







除了与Kotlin中的Java完全兼容之外,我们还对以下功能感兴趣:



  • 语言的简洁性使代码清晰易读。
  • 句法糖
  • 直观的代码,专家容易进入项目;
  • 从Java到Kotlin的自动测试功能,可以逐渐轻松地传输,如有必要,可以进行部分转换。


当然,也有缺点,特别是与Java相比。首先,是一个相对较小的社区:找到Java问题的帮助和答案比使用Kotlin容易得多。其次,一般来说,Java是一种更通用的语言,具有更多的功能以及大量的开发和库。



但是,坦率地说,出于测试目的,我们不需要仅Java可以提供的如此广泛的功能。因此,我们更喜欢Kotlin的简洁性和简洁性。



从言语到行动



由于部分过渡到一种新语言,我们收到了明显的专家人工成本增加,大大简化了代码,并减少了代码量。从我们处理经纪人资料的服务的特定示例中可以清楚地看出这一点。



在Kotlin中,您可以使用一行代码来初始化请求对象。例如,ApplicationDTO类(用于向解决方案发送调查表)和ErrorDTO(来自服务的错误)如下所示:







Kotlin允许您在初始化期间设置字段值。这节省了编写测试的时间:创建对象时,字段中已经填充了有效数据,我们仅更改引用当前检查的值。



如果不需要进行测试并且不需要检查,则JsonIgnoreProperties批注允许您不指定类中的所有字段。如果收到描述中未指定的字段,则测试不会失败并显示错误。



变量类型上的问号表示在某些情况下它可以为null。但是,在使用变量时,需要将其考虑在内并进行处理。最后,与Java测试不同,此处可以优雅地避免NullPointerException。



让我们用一个简单的错误登录示例来说明问题:



class ApplicationTests {

    val DEFAULT_LOGIN = "consLogin"
    val ERROR_CODE = "3"
    val BASE_URI = "https://base_url.com"

    @Test
    fun incorrectLogin() {
        val incorrectLogin = DEFAULT_LOGIN + "INCORRECT";
        val res = given()
                .spec(spec)
                .body(ApplicationDTO)
                .`when`()
                .post(endpointApplication(incorrectLogin)
                        .then()
                        .statusCode(400)
                        .extract().`as`(ErrorDTO::class.java)
                        assertThat(res.error_message).containsIgnoringCase("    ")
                        assertThat(res.error_code).isEqualToIgnoringCase(ERROR_CODE)
    }

    companion object{
        private var spec: RequestSpecification? = null

        @JvmStatic
        @BeforeClass
        fun initSpec() {
            spec = RequestSpecBuilder()
                    .setContentType(ContentType.JSON)
                    .setBaseUri(BASE_URI)
                    .addFilter(ResponseLoggingFilter())
                    .addFilter(RequestLoggingFilter())
                    .build()
        }
    }
}


我们在BeforeClass中创建查询规范,并在此类的所有测试中重复使用。 Jackson序列化和反序列化json对象,从而简化了事情:您不需要像处理字符串那样使用它们,因此,错误的数量大大减少了。







使用Kotlin,我们大大减少了代码量,这意味着我们使“作家”和“读者”的生活更加轻松。 ApplicationDTO类已经包含一个构造函数和一些其他方法(hashCode(),copy()等)-我们不需要用它们“重载”代码,并且新手自动测试开发人员也不会被它们分散注意力。如果有任何更改,则无需更新它们,从而减少了对测试进行编辑的时间。



Kotlin支持命名参数也非常方便-代码非常易于阅读,并且无需自己为json对象类编写设置器。



免费尝试新事物



我想指出Kotlin以及我们使用的所有库的开放性和自由性,它们极大地简化了工作,并扩展了尝试和引入新方法的可能性。同意,免费尝试新事物总是比较容易,如果失败,请恢复旧的做法。



将来,我们计划开发一种新方法并将其扩展到其他项目,并将其余的API和用户界面测试转换为Kotlin。



PS:尽管Kotlin主要与Android开发有关,但据了解,其使用范围不限于此。减少花费在编写代码上的时间,其简洁性和简洁性将有助于减少解决许多问题的人工成本。如果我们有Kotlin的新案子,我们一定会告诉您。在这里



All Articles