BATJ 测试大佬藏着掖着的神技 -HttpRunner

一、思考

image.png

1.自动化测试要做哪些事?


2.HttpRunner 是什么?

简洁

设计理念

image.png


二、HttpRunner

1.安装

pip install httprunner


2.创建项目目录


3.测试准备

image.png

image.png


4.初体验

image.png

testcases/register.yaml

-   config:
        name: testcase description
        variables: {}
-   test:
        name: /users/register/
        request:
            headers:
                Content-Type: application/json
                User-Agent: PostmanRuntime/7.15.0
            json:
                mobile: '18044441116'
                password: '123456'
                password_repeat: '123456'
                username: python6
            method: POST
            url: http://127.0.0.1:8088/users/register/
        validate:
        -   eq:
            - status_code
            - 200
        -   eq:
            - headers.Content-Type
            - application/json
        -   eq:
            - content.errno
            - '0'
        -   eq:
            - content.errmsg
            - 恭喜您,注册成功!
        -   eq:
            - content.data
            - null


5.优化用例

image.png

安装 fake-useragent 第三方模块,随机生成 user-agent

pip install fake-useragent

在 debugtalk.py 文件中,添加随机生成 user-agent 的函数

from fake_useragent import UserAgent


def get_user_agent():
    """
    获取随机user agent
    :return:
    """
    return UserAgent().random


在 debugtalk.py 中创建生成未注册手机号、未注册用户名以及随机密码的函数

import random
import string

from scripts.handle_mysql import HandleMysql



def get_not_register_tel():
    """
    获取一个未注册的手机号
    :return:
    """
    do_mysql = HandleMysql()
    tel = do_mysql.create_not_existed_moblie()
    do_mysql.close()
    return tel


def get_not_register_username():
    """
    获取一个未注册的用户名
    :return:
    """
    do_mysql = HandleMysql()
    username = do_mysql.create_not_existed_username()
    do_mysql.close()
    return username


def get_random_password(count):
    """
    生成密码
    :param count: 密码位数
    :return:
    """
    passwd_list = [random.choice(string.digits + string.ascii_letters) for _ in range(count)]
    return ''.join(passwd_list)


优化后的 YAML 格式的用例文件

-   config:
        name: "注册接口测试"
        variables: {}
        base_url: http://127.0.0.1:8088
-   test:
        name: /users/register/
        variables:
          password: ${get_random_password(5)}
        request:
            headers:
                Content-Type: application/json
                User-Agent: ${get_user_agent()}
            json:
                mobile: ${get_not_register_tel()}
                password: $password
                password_repeat: $password
                username: ${get_not_register_username()}
            method: POST
            url: /users/register/
        validate:
        -   eq: [status_code, 200]
        -   eq: [headers.Content-Type, application/json]
        -   eq: [content.errno, '0']
        -   eq: [content.errmsg, '恭喜您,注册成功!']
        -   eq: [content.data, null]


使用 pymysql 模块,对 MySQL 执行 SQL 语句,将相关操作进行封装,封装后的代码,如下所示:

handle_mysql.py

import random
import string

import pymysql

from scripts.handle_config import do_config


class HandleMysql:
    """
    处理mysql
    """

    def __init__(self):
        self.conn = pymysql.connect(host=do_config("mysql", "host"),
                                    user=do_config("mysql", "user"),
                                    password=do_config("mysql", "password"),
                                    db=do_config("mysql", "db"),
                                    port=do_config("mysql", "port"),
                                    charset=do_config("mysql", "charset"),
                                    cursorclass=pymysql.cursors.DictCursor
                                    )

        self.cursor = self.conn.cursor()

    @staticmethod
    def create_mobile():
        """
        随机生成11位手机号
        :return: 返回一个手机号字符串
        """
        start_mobile = ['130', '131', '132', '133', '134', '135', '136', '137', '138', '139',
                        '150', '151', '152', '153', '155', '156', '157', '158', '159',
                        '180', '181', '182', '183', '184', '185', '186', '187', '188', '189']
        start_num = random.choice(start_mobile)
        end_num = ''.join(random.sample(string.digits, 8))

        return start_num + end_num

    def create_username(self):
        """
        创建用户名
        :return: 返回用户名字符串
        """
        sql = "SELECT username FROM `tb_users` ORDER BY username DESC LIMIT 0, 1;"
        username_src = self(sql=sql)['username']
        one_list = list(username_src)
        random.shuffle(one_list)

        return ''.join(one_list)

    def is_existed_mobile(self, mobile):
        """
        判断给定的手机号在数据库中是否存在
        :param mobile: 11位手机号组成的字符串
        :return: True or False
        """
        sql = "SELECT mobile FROM `tb_users` WHERE mobile=%s;"
        if self(sql, arg=(mobile, )):   # 手机号已经存在,则返回True,否则返回False
            return True
        else:
            return False

    def is_existed_username(self, username):
        """
        判断给定的用户名在数据库中是否存在
        :param username: 用户名
        :return: True or False
        """
        sql = "SELECT username FROM `tb_users` WHERE username=%s;"
        if self(sql, arg=(username, )):   # 用户名已经存在,则返回True,否则返回False
            return True
        else:
            return False

    def create_not_existed_moblie(self):
        """
        随机生成一个在数据库中不存在的手机号
        :return: 返回一个手机号字符串
        """
        while True:
            one_mobile = self.create_mobile()
            if not self.is_existed_mobile(one_mobile):
                break

        return one_mobile

    def create_not_existed_username(self):
        """
        随机生成一个在数据库中不存在的用户名
        :return: 返回一个用户名字符串
        """
        while True:
            one_username = self.create_username()
            if not self.is_existed_username(one_username):
                break

        return one_username

    def get_existed_moblie(self):
        """
        获取一个在数据库中已经存在的手机号
        :return: 返回一个手机号字符串
        """
        sql = "SELECT mobile FROM `tb_users` LIMIT 0, 1;"
        one_mobile = self(sql)  # 获取数据库中第一个手机号

        return one_mobile["mobile"]

    def get_existed_username(self):
        """
        获取一个在数据库中已经存在的用户名
        :return: 返回一个用户名字符串
        """
        sql = "SELECT username FROM `tb_users` LIMIT 0, 1;"
        one_username = self(sql)  # 获取数据库中第一个用户名

        return one_username["username"]

    def __call__(self, sql, arg=None, is_more=False):
        """
        :param sql: 传入的sql语句,组成的字符串
        :param is_more: 是否获取多个值,默认获取单条数据
        :param arg: 传给sql的额外参数
        :return:
        """
        self.cursor.execute(sql, arg)
        self.conn.commit()

        if is_more:
            result = self.cursor.fetchall()
        else:
            result = self.cursor.fetchone()

        return result

    def close(self):
        self.cursor.close()
        self.conn.close()


if __name__ == '__main__':
    do_mysql = HandleMysql()
    print(do_mysql.create_not_existed_moblie())
    print(do_mysql.get_existed_moblie())
    print(do_mysql.create_not_existed_username())
    print(do_mysql.get_existed_username())
    do_mysql.close()


6.总结

image.png


回帖
请输入回帖内容 ...