Locust负载测试框架初探

Locust是一款类似于Jmeter开源负载测试工具,所不同的是它是用python实现,并支持python脚本。 locust提供web ui界面,能够方便用户实时监控脚本运行状态。

这里我以模拟公司OA系统登录、注销为例,简单的了解下locust的使用。

Locust的安装

Python的安装

Windows用户可以从Python官网下载适合你系统的安装程序进行安装;在安装完成后,建议将默认安装路径C:\Python27添加到系统环境变量中,另外一并将C:\Python27\Scripts(当前该目录可能不存在)也添加进去

Linux/Unix用户则可以略过这一步骤,系统本身已经有Python的存在,当然你如果对当前版本不满意的话,可以再自行安装熟悉的版本

完善Python环境

setuptools

setuptools, pip都是是python的包管理工具,建议安装,windows用户参照这篇文档进行安装: https://pypi.python.org/pypi/setuptools#windows-powershell-3-or-later

pip

完成上一个步骤之后,打开cmd窗口执行下列命令安装pip:

easy_install -U pip

这个时候就可以使用pip进行包管理了

国内用户使用easy_install,pip安装包过慢的话,可以使用国内镜像服务器安装,如:

pip install -i http://pypi.douban.com/simple/ -U selenium

virtualenv

virtualenv可以创建虚拟的python开发环境,一个专属于项目的开发环境,避免与其他环境冲突

通过pip安装如下:

pip install -U virtualenv

到此,一个完善的python开发环境搭建完成了

locust安装

locust同样可以使用pip进行安装

pip install -U locustio

然后安装pyzmq

pip install -U pyzmq

locust压力测试实战

了解OA系统登录行为

登录过程

公司OA系统的登录页面为http://oa.company.com/CasServer/login,从UI界面上看,只需要输入公司邮箱以及密码即可登录: 然而简单的猜测并不靠谱,必须要有详细的数据来佐证猜想,这里为了排查清楚登录OA系统到底post了什么的数据,可以借助第三方工具如wireshark进行抓包

从抓包结果来看,整个登录过程的确没有想象的简单,登录时不仅向系统postusername,password两个字段,还有随机产生的lt以及execution字段

查看网页的源代码,找到这两个字段的位置:

也就是说,要模拟用户的登录行为,就必须从网页的源代码中抠出这两个字段的值

注销过程

OA系统注销的过程很简单,只需要get特定的uri即可 http://oa.company.com/CasServer/logout

locust脚本

了解整个登录、注销过程后就可以进入实质的脚本开发过程了

提取lt execution字段值

这里我使用熟悉的xpath方式来提取这两个字段的值

首先安装xml处理库lxml

pip install -U lxml

lt字段值的xpath表达式为:

"//div[@class='btnbox']/input[@name='lt']/@value"

execution字段值的xpath表达式为:

"//div[@class='btnbox']/input[@name='execution']/@value"

提取的值的方法实现如下:

from lxml import etree
 
def get_lt(html):
    tree = etree.HTML(html)
    return tree.xpath("//div[@class='btnbox']/input[@name='lt']/@value")[0]
 
def get_execution(html):
    tree = etree.HTML(html)
    return tree.xpath(
        "//div[@class='btnbox']/input[@name='execution']/@value")[0]

模拟用户登录、注销

完成了lt execution字段的提取后就开始模拟用户操作了

from locust import TaskSet, task
 
class UserBehavior(TaskSet):
    
    @staticmethod
    def get_lt(html):
        tree = etree.HTML(html)
        return tree.xpath("//div[@class='btnbox']/input[@name='lt']/@value")[0]
 
    @staticmethod
    def get_execution(html):
        tree = etree.HTML(html)
        return tree.xpath(
            "//div[@class='btnbox']/input[@name='execution']/@value")[0]
    
    def login(self):
        html = self.client.get('CasServer/login').text
        username = 'user@compay.com'
        password = '123456'
        lt = self.get_lt(html)
        execution = self.get_execution(html)
        payload = {
            'username': username,
            'password': password,
            'lt': lt,
            '_eventId': 'submit',
            'submit': '',
            'rememberMetest': 'false',
            'vcode': '',
            'execution': execution
        }
        self.client.post('CasServer/login', data=payload)
 
    def logout(self):
        self.client.get('CasServer/logout')
        
    @task(10)
    def login_logout(self):
        self.login()
        self.logout()

然后设置每个client的相关属性

from locust import HttpLocust

class WebsiteUser(HttpLocust):
    host = 'http://oa.company.com/'
    task_set = UserBehavior
    min_wait = 5000
    max_wait = 9000

执行压力测试

重新打开cmd窗口进入脚本文件的目录之中,执行以下命令开启压力测试:

locust -f locustfile.py

执行完上面命令后用浏览打开http://127.0.0.1:8089,出现以下界面:

我这里尝试模拟100个虚拟用户,每秒发送30次请求,然后点击Start swarming开始进行压力测试

执行没一会儿,公司OA的服务器就顶不住了

测试结果

locust的运行界面,可以下载当前的运行结果到本地,但是这两份csv中的测试结果不够详细,不利于分析系统的瓶颈,这也是locust的不足之处。

好在locust提供很多hook,可以增强测试报告,这边暂时就不再展开