【Junit5】接口场景化解决方案1

2022-04-07 09:38:31 浏览数 (1)

重点

  • TestMethodOrder(MethodOrderer.OrderAnnotation.class)
  • ExecutionCondition
  • 自定义容器disabled策略

解决问题

接口测试过程中会有2种测试,一种是针对单接口进行测试,另外一种就是将接口串联起来形成具有业务链的场景化的接口测试用例。对于场景化用例在测试过程中又有哪些问题:

  • 接口之间有依赖关系,有执行顺序要求;
  • 场景化接口其中如果有接口失败,后续接口需要ignore;

针对上述2问题,我们看看Junit5框架如何解决以及通过ExecutionCondition自定义执行策略;

解决方案

业务场景

  • 用户登陆 -> 搜索产品 -> 用户下单-> 用户支付

代码实现

代码语言:javascript复制
@platform
@DisplayName("用户下单")
@Describe(service = "",module = "",development = "",test = "胡小天")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class demo3Test {

    @Test
    @Order(0)
    @DisplayName("用户App登陆")
    @Api(address = Host.eu,method = RequestMethod.POST,url = eu.login)
    public void login() {
        // 业务代码...
    }

    @Test
    @Order(1)
    @DisplayName("App搜索获取商品信息")
    @Api(address = Host.eu,method = RequestMethod.POST,url = eu.search)
    public void search() {
        // 业务代码...
    }

    @Test
    @Order(2)
    @DisplayName("用户下单")
    @Api(address = Host.eu,method = RequestMethod.POST,url = eu.OrderConfirmation)
    public void OrderConfirmation() {
        // 业务代码...
    }

    @Test
    @Order(3)
    @DisplayName("用户支付")
    @Api(address = Host.eu,method = RequestMethod.POST,url = eu.orderPay)
    public void orderPay() {
        // 业务代码...
    }
}

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)

  • 此注解主要用于使测试的方法顺序执行,需要与@TestMethodOrder与@Order结合使用
  • order值越小执行权限越高

通过TestMethodOrder就可以保证测试用例的执行按照预期的顺序执行;从上面的执行结果可以看出场景化用例的执行顺序和预期保持一致,但是第二个接口执行失败了后续相关的接口还是执行了,那如何保证如果中间有测试用例执行失败了后面的测试用例ignore?这就要说到ExecutionCondition扩展模块了。

  • The ExecutionCondition extension API in JUnit Jupiter allows developers to either enable or disable a container or test based on certain conditions programmatically. The simplest example of such a condition is the built-in DisabledCondition which supports the @Disabled annotation (see Disabling Tests). In addition to @Disabled, JUnit Jupiter also supports several other annotation-based conditions in the org.junit.jupiter.api.condition package that allow developers to enable or disable containers and tests declaratively. When multiple ExecutionCondition extensions are registered, a container or test is disabled as soon as one of the conditions returns disabled. If you wish to provide details about why they might be disabled, every annotation associated with these built-in conditions has a disabledReason attribute available for that purpose.

上面是官方给出的解释,通俗的来说,当了我们当实现了多个ExecutionCondition扩展时,一旦其中一个条件返回disabled,测试类或测试用例就会被禁用;

自定义disabled策略

代码语言:javascript复制
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import java.io.PrintWriter;
import java.io.StringWriter;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled;

@Slf4j
public class DisabledOnRelyTestCaseCondition implements ExecutionCondition {

    private static final ConditionEvaluationResult ENABLED_BY_TESTCASE_FAIL =
            disabled("@Disabled On TestCase fail");

    private static final ConditionEvaluationResult ENABLED_BY_TESTCASE_PASS =
            enabled("Test is pass");

    @Override
    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
     // NamespaceStore.key(NamespaceStore.TESTCASE_RESULT)是获取上一个测试用例的执行结果
        boolean flag = (boolean) NamespaceStore.key(NamespaceStore.TESTCASE_RESULT);
        if (flag)
            return ENABLED_BY_TESTCASE_PASS;
        return ENABLED_BY_TESTCASE_FAIL;
    }
}
代码语言:javascript复制
import com.platform.junit5.imp.DisabledOnRelyTestCaseCondition;
import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.*;

@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisabledOnRelyTestCaseCondition.class)
public @interface DisabledOnScenario {
}
代码语言:javascript复制
# 所有测试用例加上@DisabledOnScenario注解
@Test
@Order(1)
@DisplayName("App搜索获取商品信息")
@DisabledOnScenario
@Api(address = Host.eu,method = RequestMethod.POST,url = eu.search)
public void search() {
    // 业务代码...
}

今天我们解决了接口场景化用例中2个问题,在接口场景化测试中还有个问题需要解决,就是某个接口的参数依赖上个接口的返回值或者请求body的参数,针对这个难点下次我给你大家带来解决方案,敬请期待;

注:上述代码部分注解非Junit5官方注解如:@platform、@Api等后续篇章会讲到;

0 人点赞