Headless browser and locust.io

﹥>﹥吖頭↗ 提交于 2021-02-08 06:35:34

问题


Is it possible to integrate a headless browser with locust? I need my load tests to process client side script that triggers additional requests on each page load.


回答1:


That's an old question, but I came across it now, and found a solution in "realbrowserlocusts" (https://github.com/nickboucart/realbrowserlocusts) - it adds "Real Browser support for Locust.io load testing" using selenium.

If you use one of its classes (FirefoxLocust, ChromeLocust, PhantomJSLocust) instead of HttpLocust for your locust user class

class WebsiteUser(HeadlessChromeLocust):

then in your TaskSet self.client becomes an instance of selenium WebDriver.


One drawback for me was that webdriver (unlike built-in client in HttpLocust) doesn't know about "host", which forces to use absolute URLs in TaskSet instead of relative ones, and it's really convenient to use relative URLs when working with different environments (local, dev, staging, prod, etc.). But there is an easy fix for this: to inherit from one of realbrowserlocusts' locusts and pass "host" to WebDriver instance:

from locust import TaskSet, task, between
from realbrowserlocusts import HeadlessChromeLocust


class UserBehaviour(TaskSet):
    @task(1)
    def some_action(self):
        # self.client is selenium WebDriver instance
        self.client.get(self.client.base_host + "/relative/url")
        # and then for inst. using selenium methods:
        self.client.find_element_by_name("form-name").send_keys("your text")
        # etc.


class ChromeLocustWithHost(HeadlessChromeLocust):
    def __init__(self):
        super(ChromeLocustWithHost, self).__init__()
        self.client.base_host = self.host


class WebsiteUser(ChromeLocustWithHost):
    screen_width = 1200
    screen_height = 1200
    task_set = UserBehaviour
    wait_time = between(5, 9)

============

UPDATE from September 5, 2020:

I posted this solution in March 2020, when locust was on major version 0. Since then, in May 2020, they released version 1.0.0 in which some backward incompatible changes were made (one of which - renaming StopLocust to StopUser). realbrowserlocusts was not updated for a while, and is not updated yet to work with locust >=1.

There is a workaround though. When locust v1.0.0 was release, previous versions were released under a new name - locustio with the last version 0.14.6, so if you install "locustio==0.14.6" (or "locustio<1"), then a solution with realbrowserlocusts still works (I checked just now). (see https://github.com/nickboucart/realbrowserlocusts/issues/13).

You have to limit a version of locustio, as it refuses to install without it:

pip install locustio
...
ERROR: Command errored out with exit status 1:
...
**** Locust package has moved from 'locustio' to 'locust'.
Please update your reference
(or pin your version to 0.14.6 if you dont want to update to 1.0)




回答2:


In theory you could make a headless browser a Locust slave/worker. But the problem is that the browser is much more expensive in terms of CPU and memory which would make it difficult to scale.

That is why Locust uses small greenlets to simulate users since they much cheaper to construct and run.

I would recommend you to break down your page's requests and encode them as requests inside of Locust. The Network tab in Chrome's Dev Tools is probably a good start. I've also heard of people capturing these by going through a proxy that logs all requests for you.




回答3:


You could use something like browserless to take care of the hosting of Chrome (https://browserless.io). Depending on how you brutal your load tests are there’s varying degrees of concurrency. Full disclaimer: I’m the maker of the browserless service




回答4:


I think locust is not desinged for that purposes, it is for creating concurrent user to make http requests so I didnt see any integration with locust and browser. However you can simulate browser by sending extra information in the header with that way client side scripts will also work.

r = self.client.get("/orders", headers = {"Cookie": self.get_user_cookie(user[0]), 'User-Agent': self.user_agent})



回答5:


The locust way of solving this is to add more requests to your test that mimic the requests that the javascript code will make.

I structure my locust tests to parse the JSON response from an early request in the app's workflow. I then randomly pick some interesting piece of data from that JSON, and then issue more requests that mimic what would happen in the browser if the user had clicked on that piece of data.



来源:https://stackoverflow.com/questions/32890209/headless-browser-and-locust-io

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!