Load Testing With Python Faker & Flask -PART I

Photo by Damir Spanic on Unsplash

The exciting thing about DevOps is that you have opportunities, under controlled conditions, to push your machines to their limits. Doing so provides a number of benefits. One benefit is that your customer experiences less issues with the service you are providing because you planned ahead. The second benefit is that you can automate your response to incidents if you know how your systems work. This would mean that you and your colleagues will not get 3am calls, or at least get less of them. Load testing is foundational to planning and fine-tuning your Devops tooling. In this article, I plan to give you a very basic tool using the Python Faker class to get you started on this path.

The first thing you will want to do before testing your preprod environment is to have your own dev environment that you can test your scripts against. I have an example of something you can try on your local computer using the Python Flask class. You can clone the repo here. Lets walk through some of the code.

The first thing you will see is a list that contains a dictionary of different quotes. In most cases, you will want to reference a database, but for the purposes of testing your script, this will suffice.

author_quotes = [{“id”: 0, “author”: “A.W. Tozer”, “quote”: “Only an evil desire to shine \makes us want to appear other than we are.”},{“id”: 1, “author”: “G.K. Chesterton”, “quote”: “Truth, of course, must of necessity \be stranger than fiction, for we have made fiction to suit ourselves.”},{“id”: 3, “author”: “Upton Sinclair”, “quote”: “It is difficult to get a man to understand something, \when his salary depends on his not understanding it.”},]

Next, we define the get function that will return quotes at random.

def get(self, id=0):    if id == 0:        return random.choice(author_quotes), 200        for quote in author_quotes:            if(quote[“id”] == id):                return quote, 200        return “Quote not found”, 404

Then we define the post function that will allow you to create a new entry. Notice the parser and how that translates into the key/value arguments your message will pass along. This is also similar to the put function.

def post(self, id):    parser = reqparse.RequestParser()    parser.add_argument("author")    parser.add_argument("quote")    params = parser.parse_args()    for quote in author_quotes:        if(id == quote["id"]):        return f"Quote with id {id} already exists", 400    quote = {    "id": int(id),    "author": params["author"],    "quote": params["quote"]    }    author_quotes.append(quote)    return quote, 201

Once you are ready to try this, simply run the application in with Python. You will need to install Flask with pip. Once you have started the application you will see something similar to this message below:

Debug mode: on* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)* Restarting with stat* Debugger is active!* Debugger PIN: 339–025–536

Once you see that you are ready to test. Lets try using something like the Postman application to try a get command. Your url will look something like this:
http://127.0.0.1:5000/author-quotes

Everytime you make a request the application will log the origination IP, timestamp, HTTP method. Try this out with the other HTTP methods as well.

127.0.0.1 — — [27/Jan/2021 20:36:34] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:48] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:51] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:52] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:53] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:54] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:56] “GET /author-quotes HTTP/1.1” 200 -127.0.0.1 — — [27/Jan/2021 20:36:57] “GET /author-quotes HTTP/1.1” 200 -

Now let’s review the template for the Faker load test. The test application, as you can see, is not very complicated. It simply takes what you were doing in Postman and automates the task for you. I will break down the POST test to see how this works exactly.

fake = Faker()id = int(input(“Enter id to start testing from: “))messages = int(input(‘Enter number of messages to generate: ‘))next_send = float(input(‘Enter interval (in seconds) to send each message: ‘))

The fake variable calls the Faker class to pass on the generative data later on in the code. The id variable allows the user to choose which id to begin starting the messages at. The messages variable allows you to determine how many messages you would like to produce, and the next_send variable will allow you to choose the rate (in seconds) that you would like to send the messages.

url = ‘http://127.0.0.1:5000/author-quotes/' + str(id)params ={‘author’: fake.name(), ‘quote’: fake.text()}post_message = requests.post(url, data = params)print(url)print(post_message.text)id += 1time.sleep(next_send)

The next bit of code has your base url and your parameters (key/value pair) to pass along with your message. We call the Faker class to generate a random name for the author and to also generate random text for the quote. The variable, time.sleep() pauses the iteration for the amount of seconds you chose for the next_send variable.

This should be a very basic and simple example to start developing applications for your own load testing. In a follow up to this article I will deploy in AWS to measure how to view the logs and performance of multiple components while running this, and tweaking the components accordingly.