性格内敛

  • Junit 与 TestNG 并无本质性差别,都是测试基础框架

  • 回归二线 at 2022年05月13日

    重庆欢迎你

  • 我们用的测试网管 + 测试 MOCK 的思路,所有服务请求到第三方的请求都会通过我们的测试网管(修改服务的配置,将第三方服务的域名更改为测试网管的域名)。然后根据一些白名单配置,决定对应接口是否请求到第三方服务/测试 MOCK。按照这个逻辑,就可以决定特定第三方服务/特定接口/特定数据是否需要走第三方还是 MOCK。

  • 我们当前用的是 TestNG,只是之前某些测试用例由于某些无法抗拒的原因用的 junit5。目前用的 allure,使用监听的方式生成测试报告没详细了解过,网上应该有很多的 demo 的,可以去了解一下。

  • 5.0 相对 4.0 做了很大的改动,应该不支持你那种(你可以了解看看有没有兼容方案)。在 4.0 上也是可以做数据驱动的,没有 junit5 好用,你可以参考一下这种,http://www.51testing.com/html/44/316844-3483525.html


  • @CsvSource是 junit5 里面的一个注解,是以 csv 格式提供数据的,你可以很明显的看到一组测试数据里的逗号分隔。junit5 里面还有其他的数据提供/参数化的注解,可以有空了解一下。整体上和 testNG 里面的@DataProvider大差不差。

  • 不好意思,没太明白你这边的问题点。数据驱动?

  • 其实,思路才是测试过程最重要的。虽然这个文档/demo 是三年前的的,但其实我们当前也只是在这个上面根据业务内容的调整不断优化而已。相关的功能点都在上面的回帖中提及到了的。置于新的 demo,我这边目前没有太多时间来将新的实践整理出 demo 来,抱歉!

  • 一、展示一个流程数据构造的例子:
    1、如下是一个完整的业务流程

    @RepeatedTest(1) // 为当前用例执行的次数
    @Execution(CONCURRENT)  // CONCURRENT表示支持多线程
    @DisplayName("申请 + 商户录单 + 风控初审 + 风控复审 + 绑卡 + 在线签约 + 面签合同 + 抵押办理 + GPS安装 + 请款/等待放款成功")
    public void applyWorkFlowCase6() throws Exception {
        String userMobile = MobileUtil.generate();
        String agentMobile = agentDefaultMobile;
        String productNo = "379968089799786497";
    
        // 借款提交
        String bizNo = applyService.loanApply(userMobile, agentMobile, productNo);
    
        // 商户录单
        merchantAppDealOrderService.merchantReplenish(bizNo);
    
        // 初审
        approvalService.firstTrial(bizNo);
    
        // 复审
        approvalService.retrial(bizNo);
    
        // 绑卡
        bindBankService.bindBank(bizNo);
    
        // 签约
        signService.sign(bizNo);
    
        // 面签合同
        contractService.signContractFace2Face(bizNo);
        // 办理抵押
        mortgageService.registerUpload(bizNo);
        // GPS安装
        contractService.gpsInstall(bizNo);
    
        // 等待请款/放款
        fundingService.waitFundingSuccess(bizNo);
    }
    

    从这上面看我们是看不到任何的接口调用,它是一个业务流程
    2、我们展开上面的 “借款提交” applyService.loanApply

    public String loanApply(Boolean caseMockHF,
                                String userMobile, String agentMobile, String productNo) throws InterruptedException {
            // 注册/登录
            LoginDataVO loginDataVO = loginService.appUserLoginBySms(userMobile);
            String authorization = loginDataVO.getAuthorization();
            String userId = loginDataVO.getUserId();
    
            // 身份信息认证
            userInfoService.identifySave(authorization, userId);
    
            // 用户信息
            userInfoService.userInfoSave(authorization, userId);
    
            // 征信授权
            CreditDataVO creditDataVO = userInfoService.creditAuth(authorization, agentMobile, productNo);
            String bizNo = creditDataVO.getBizNo();
    
            // 提交
            apply(authorization, caseMockHF, userId, bizNo, agentMobile, productNo);
    
            return bizNo;
        }
    

    从这上面我们也看不到任何的接口调用,他是完整业务流程中的某一个节点
    3、我们再展开上面的 “身份信息认证” userInfoService.identifySave

    public void identifySave(String authorization, String userId) {
            Response response;
            String name;
            String certNo;
            String bankCardNo;
    
            response = identifyApi.identifyStatus(authorization, null);
            Assertion.isSuccess(response);
            // 认证未通过的需要进行认证
            if (!response.then().extract().path("data.identifyStatus").equals("2")) {
                // 姓名生成
                name = NameUtil.generate();
                // 身份证号生成
                certNo = CerNoUtil.generate();
                // todo 银行类型可选择
                bankCardNo = BankCardNoUtil.generate("621700");
    
                // todo mock适配
                // 卡bin
                response = bankApi.bankCardBin(authorization, bankCardNo);
                Assertion.isSuccess(response);
    
                // todo mock适配
                // 协议绑卡发送短信验证码
                BaofooSmsRequestVO baofooSmsRequestVO = new BaofooSmsRequestVO()
                        .setName(name)
                        .setCertificateNo(certNo)
                        .setBankCardNo(bankCardNo)
                        .setBankMobile(bankMobile);
                response = orderBankApi.baoFooSms(authorization, baofooSmsRequestVO);
                Assertion.isSuccess(response);
                // 协议号
                String platformBindApplyNo = response.then().extract().path("data");
    
                // todo 四要素验证
                //  可暂时不调用,可mock
    
                // 保存身份认证信息
                IdentifySaveRequestVO identifySaveRequestVO = new IdentifySaveRequestVO()
                        .setName(name)
                        .setCertificateNo(certNo)
                        .setBankCardNo(bankCardNo)
                        .setMobile(bankMobile)
                        // todo 地址生成
                        .setAddress("这只是一个地址")
                        .setBirthday(certNo.substring(6, 14))
                        .setExpiryDate("20210802")
                        .setIdCardBackUri("uri")
                        .setIdCardFrontUri("uri")
                        .setIssue("公安局")
                        .setIssueDate("20110802")
                        .setNation("汉")
                        .setPlatformMsgCode("111111")
                        // 根据身份证号来判定
                        .setSex(CerNoUtil.isMen(certNo) ? "1" : "2")
                        .setPlatformBindApplyNo(platformBindApplyNo);
                response = identifyApi.identifySave(authorization, identifySaveRequestVO);
                Assertion.isSuccess(response);
            }
        }
    

    从上面看 identifyApi.identifySave 才算是一个接口调用,而我们整个业务流程中有很多节点,而每个节点可能都有多个接口调用才最终推动流程的开展。所以,通过相应接口的组合,就可以完成业务流程数据的构造。

    二、再展示一个接口测试的例子
    1、如下是一个接口测试的用例

      @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}")
      @CsvSource({
              "【机构案件有效期为长期,单机构】, true, false",
              "【机构案件有效期非长期,多机构】, false, true"
      })
      @DisplayName("案件认领(单个机构/多个机构认领,机构有效期长期/非长期)")
      @Tag("CaseHandleApi.claim")
      public void testAppOutsourceCaseClaimInterfaceCase1(String des, boolean forever, boolean multiOrg) {
          RecoverModeEnum recoverModeEnum = RecoverModeEnum.SHARED;
          RecoverWayEnum recoverWayEnum = RecoverWayEnum.AMOUNT;
    
          OutsourceCasePreconditionVO outsourceCasePreconditionVO = appOutsourceCaseHandleService.outsourceLoginInfo(
                  authorization, forever, recoverModeEnum, recoverWayEnum);
          String bizNo = outsourceCasePreconditionVO.getOutsourceCase().getApplyBizNo();
          String caseNo = outsourceCasePreconditionVO.getOutsourceCase().getCaseNo();
          String outsourceAdminAuth = outsourceCasePreconditionVO.getOutsourceAdmin().getAuthorization();
    
          // 机构案件认领
          BindResult<Void> result = caseHandleApi.claim(outsourceAdminAuth, new ClaimRequestVO().setCaseNo(caseNo));
          Assertion.isSuccess(result);
          // 认领后的案件数据
          OutsourceCase outsourceCaseClaim = outsourceCaseDataSourceBiz.getCaseByBizNo(bizNo);
    
          // 数据验证
          assertCaseClaim(outsourceCasePreconditionVO.getOutsourceCase(), outsourceCaseClaim,
                  outsourceCasePreconditionVO.getOrganizationResponseVO());
    }
    

    caseHandleApi.claim 才是该接口的调用,在此调用之前的 appOutsourceCaseHandleService.outsourceLoginInfo 其目的只是为了构造前置数据(而在这里面,其实也是不同接口调用/SQL 等的数据构造而已),assertCaseClaim 就是接口测试的验证了

    通过上面的两个例子,应该可以说明我所说的了

  • 我们的测试流程其本质就是一个接口一个接口的调用,从而推进流程。所以,你需要根据对应的业务场景,通过组合不同的接口调用来完成对应的流程,在对应过程中加上各个接口调用后相应数据的验证。这样的话,就实现了通过接口来开展业务流程的测试

性格内敛