首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多种登录方式定量性能测试方案

多种登录方式定量性能测试方案

作者头像
FunTester
发布2020-02-17 15:57:08
5450
发布2020-02-17 15:57:08
举报
文章被收录于专栏:FunTesterFunTester

最近接到到一个测试任务,某服务提供了两种登录方式:1、账号密码登录;2、手机号+验证码登录。要对这两种登录按照一定的比例进行压测。

要求:

  • 每次登录的用户不相同
  • 手机号和验证码绑定
  • 能够定位和追踪到耗时较长的请求

难点:

  • 需要每次都获取一个不同的用户
  • 每次用户验证码登录都需要获取一个验证码和一个与手机号验证码绑定的tracono
  • 需要每一次测试都有一个标记mark(非mark请求,手机号登录有两个请求)

解决方案:

  • 创建足够大的用户池,依然使用线程安全类AtomicInteger类来解决用户重复的线程安全问题
  • 封装两个登录方法,多一个参数区别两中登录方式
  • 参数化比例,依然使用线程安全类AtomicInteger类来解决每一次登录场景需要哪种登录
  • 采取mark用户id的形式来mark每一次登录

下面是测试脚本:

package com.okayqa

import com.fun.base.constaint.ThreadBase
import com.fun.base.constaint.ThreadLimitTimeCount
import com.fun.base.interfaces.MarkThread
import com.fun.frame.excute.Concurrent
import com.fun.utils.ArgsUtil
import com.okayqa.appmiddle.base.OkayBase
import com.okayqa.common.OkayUsers

import java.util.concurrent.atomic.AtomicInteger

class OKAYTT extends OkayBase {

    static AtomicInteger num = new AtomicInteger(0)

    static AtomicInteger r = new AtomicInteger(0)

    static def split;

    public static void main(String[] args) {
        def argsUtil = new ArgsUtil(args)
        def thread = argsUtil.getIntOrdefault(0, 2)
        def time = argsUtil.getIntOrdefault(1, 5)
        split = argsUtil.getStringOrdefault(3, "1:2").split(":")

        def threads = []
        thread.times {
            thread << new Plus(time)
        }

        new Concurrent(threads, "多种登录模式压测").start()


        allOver()
    }

    public static boolean getType() {
        def var1 = split[0] as int
        def var2 = split[1] as int
        def var = var1 + var2
        def increment = r.getAndIncrement() % var
        if (increment < var1) true
        false
    }


    static class Plus extends ThreadLimitTimeCount {

        int i;

        public Plus(int time) {
            super(null, time, null)
            this.i = OKAYTT.num.getAndIncrement();
            this.mark = new Mark(OkayUsers.getStuUser(i))
        }


        @Override
        protected void doing() throws Exception {
            new OkayBase(i, getType())
        }
    }

    static class Mark implements MarkThread {

        String mark_name;

        @Override
        String mark(ThreadBase threadBase) {
            return mark_name;
        }

        public Mark(String name) {
            this.mark_name = name;
        }

        public Mark() {

        }

        @Override
        MarkThread clone() {
            return null
        }
    }
}

其中new OkayBase(i, getType())方法就是登录,第二个参数区分不同登录方法。i就是从用户池中获取的用户索引,下面是两种登录的封装方法:

    public JSONObject loginPwd(String tel, int role) {
        String url = LoginApi.LOGIN;
        JSONObject params = getParams();
        JSONObject types = new JSONObject();
        types.put("type", 1);
        types.put("phone", account);
        types.put("pwd", pwd);
        params.put("type", types);
        params.put("app_id", "1");
        params.put("role", role);
        return getPostResponse(url, params);
    }

    /**
     * @param tel
     * @param role 0家长 1学生 默认0家长
     */
    public JSONObject loginTel(String tel, int role) {
        String url = LoginApi.LOGIN;
        JSONObject params = getParams();
        JSONObject types = new JSONObject();
        types.put("type", 2);
        types.put("phone", tel);
        types.put("traceno", sendCode(tel));
        types.put("code", Common.TEL_CODE);
        params.put("role", role);
        params.put("type", types);
        return getPostResponse(url, params);

    }

    public String sendCode(String tel) {
        String url = LoginApi.SEND_CODE;
        JSONObject params = getParams();
        params.put("phone", tel);
        JSONObject response = getPostResponse(url, params);
        output(response);
        if (isRight(response)) {
            return response.getJSONObject("data").getString("traceno");
        }
        return EMPTY;
    }

下面是密码的加密算法:

    /**
     * 获取加密密文
     *
     * @param pwd
     * @return
     * @throws Exception
     */
    protected static String getPwd(String pwd) {
        try {
            String salt = "17802ec2980353bdc3f082b0668bd1e4";
            String key = StringUtils.substring(salt, 0, salt.length() / 8 * 8);
            // 生成一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key.getBytes());
            // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance(DES);
            // 用密钥初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
            byte[] bt = cipher.doFinal(pwd.getBytes());
            return new BASE64Encoder().encode(bt);
        } catch (Exception e) {
            return EMPTY;
        }
    }

在本案例中我依然采取了跟文章:性能测试如何减少本机误差中一样的方法,我把所有账号的密码都重置为相同的密码,获取统一的密码密文,取消了测试中加密密码的步骤。


  • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档