ai-test, ai-agent, llm, mcp-ai,

AI write script - Data-Driven Mongodb

Donald Donald Follow May 31, 2024 · 17 mins read
AI write script - Data-Driven Mongodb
Share this

How AI (Chatgpt) to write automation test script with Data-Driven Mongodb

Overview

Here is my self assignment, to work with Chatgpt to test the way it suggested us to write automation test for API as bellow:

I have the curl command to test Login and get token.

curl --location 'http://127.0.0.1:5000/login' \
--header 'Content-Type: application/json' \
--data '{
  "username": "admin",
  "password": "admin123"
}'

and the response data will be like:

{
    "data": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.vb1PIGc2ZoxpcJ0sPAYCjc4-D1o3nCzCyNZiWWYZy3E"
    },
    "message": "OK"
}

1 - Request ChatGPT write Python script to cover API test

And Here is the way I communicated with Chatgpt to complete my self-assignment :)

walking

Here is the content of suggested script from Chatgpt:

import requests

def test_login(url, username, password):
    headers = {'Content-Type': 'application/json'}
    data = {
        "username": username,
        "password": password
    }
    
    response = requests.post(url, headers=headers, json=data)
    
    if response.status_code == 200:
        response_data = response.json()
        if 'data' in response_data and 'token' in response_data['data']:
            token = response_data['data']['token']
            print(f"Login successful. Token: {token}")
            return token
        else:
            print("Token not found in response.")
            return None
    else:
        print(f"Login failed. Status code: {response.status_code}")
        return None

# Usage
url = 'http://127.0.0.1:5000/login'
username = 'admin'
password = 'admin123'
test_login(url, username, password)

And Chatgpt also explained us the meaning of scripts and the ways we should setup to make sure the scripts will be executed successfully as below:

walking

walking

2 - Test the scripts

walking

However, we should NOT use all data that Chatgpt suggested us, we will modify it how it is more useful, maintainable, clean-code, … test scripts.

3 - Request Chatgpt refactor code using Pytest test framework:

One the other hand, we can request chatgpt refactor code as Pytest with request as below:

walking


Content of the new version of test script:

We can get that Chatgpt also suggested me 2 test cases, it is quite good and useful for us.

import pytest
import requests

# Define the URL, username, and password as constants or fixtures
URL = 'http://127.0.0.1:5000/login'
USERNAME = 'admin'
PASSWORD = 'admin123'

@pytest.fixture
def login_data():
    return {
        "username": USERNAME,
        "password": PASSWORD
    }

@pytest.fixture
def headers():
    return {'Content-Type': 'application/json'}

def test_login_success(headers, login_data):
    response = requests.post(URL, headers=headers, json=login_data)
    assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"
    
    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    
    token = response_data['data']['token']
    assert token is not None, "Token should not be None"
    print(f"Login successful. Token: {token}")

def test_login_failure(headers):
    # Test with wrong credentials
    wrong_data = {
        "username": "wrong_user",
        "password": "wrong_pass"
    }
    response = requests.post(URL, headers=headers, json=wrong_data)
    assert response.status_code == 401, f"Expected status code 401, but got {response.status_code}"
    response_data = response.json()
    assert 'message' in response_data, "Response JSON does not contain 'message' key"
    assert response_data['message'] == 'Unauthorized', f"Expected message 'Unauthorized', but got {response_data['message']}"

if __name__ == "__main__":
    pytest.main()

As suggestions from Chatgpt, we have to install the essential library in our python project.

pip install pytest

From the response, we also have the explanation from Chatgpt as bellow:

walking

And here is the result, when I tested the new version of test script that Chatgpt suggested me

walking

The first test case is PASSED, however the second test case is FAILED. Actually, my example service has the contract API as:

  • The request login with failed credential will be received status code: 500 in response message
  • And body message:
{
    "data": {
        "token": null
    },
    "message": "Incorrect username or password"
}

We have 2 options:

  • we have to adjust and refactor this code, how it reflect correct our current contract
  • or we request Chatgpt help us refactor code.

I tried to request chatgpt help me refactor code more

Could you help me refactor the test script, how it reflects to current correct response in test_login_failure, it should be:
- status code: 401
- response message
{
    "data": {
        "token": null
    },
    "message": "Incorrect username or password"
}

Content of new version script:

import pytest
import requests

# Define the URL, username, and password as constants or fixtures
URL = 'http://127.0.0.1:5000/login'
USERNAME = 'admin'
PASSWORD = 'admin123'

@pytest.fixture
def login_data():
    return {
        "username": USERNAME,
        "password": PASSWORD
    }

@pytest.fixture
def headers():
    return {'Content-Type': 'application/json'}

def test_login_success(headers, login_data):
    response = requests.post(URL, headers=headers, json=login_data)
    assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"
    
    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    
    token = response_data['data']['token']
    assert token is not None, "Token should not be None"
    print(f"Login successful. Token: {token}")

def test_login_failure(headers):
    # Test with wrong credentials
    wrong_data = {
        "username": "wrong_user",
        "password": "wrong_pass"
    }
    response = requests.post(URL, headers=headers, json=wrong_data)
    assert response.status_code == 401, f"Expected status code 401, but got {response.status_code}"
    
    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    assert response_data['data']['token'] is None, "Expected token to be None"
    
    assert 'message' in response_data, "Response JSON does not contain 'message' key"
    assert response_data['message'] == 'Incorrect username or password', f"Expected message 'Incorrect username or password', but got {response_data['message']}"

if __name__ == "__main__":
    pytest.main()

And I test again the test scripts. And it is working well as we expected.

walking

4 - Enhancing our test framework to build Data-driven framework

Asking Chatgpt guide us to build up a Mongodb to save all testing users, and our testing framework will interact with mongodb to get the available users for each execution.

Here is the message which I contacted with Chatgpt:

Could you help me upgrade the above framework testing to save all testing data as the list of users into a mongodb, how each execution of testing framework will get an available user.

Chatpt suggested us to:

  • Install the essential library for mongodb: pip install pymongo
  • Especially, We have the Mongodb server, where we input all users.

walking

Python Script to Manage Users in MongoDB:

import pytest
import requests
from pymongo import MongoClient

# MongoDB configuration
MONGO_URI = 'mongodb://localhost:27017/'
DATABASE_NAME = 'test_db'
COLLECTION_NAME = 'users'

# Define the URL
URL = 'http://127.0.0.1:5000/login'

# MongoDB setup
client = MongoClient(MONGO_URI)
db = client[DATABASE_NAME]
collection = db[COLLECTION_NAME]

def get_available_user():
    # Find an available user in the database
    user = collection.find_one({"used": False})
    if user:
        collection.update_one({"_id": user["_id"]}, {"$set": {"used": True}})
    return user

@pytest.fixture
def login_data():
    user = get_available_user()
    if user:
        return {
            "username": user["username"],
            "password": user["password"]
        }
    else:
        pytest.fail("No available users in the database.")

@pytest.fixture
def headers():
    return {'Content-Type': 'application/json'}

def test_login_success(headers, login_data):
    response = requests.post(URL, headers=headers, json=login_data)
    assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"
    
    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    
    token = response_data['data']['token']
    assert token is not None, "Token should not be None"
    print(f"Login successful. Token: {token}")

def test_login_failure(headers):
    # Test with wrong credentials
    wrong_data = {
        "username": "wrong_user",
        "password": "wrong_pass"
    }
    response = requests.post(URL, headers=headers, json=wrong_data)
    assert response.status_code == 401, f"Expected status code 401, but got {response.status_code}"
    
    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    assert response_data['data']['token'] is None, "Expected token to be None"
    
    assert 'message' in response_data, "Response JSON does not contain 'message' key"
    assert response_data['message'] == 'Incorrect username or password', f"Expected message 'Incorrect username or password', but got {response_data['message']}"

if __name__ == "__main__":
    pytest.main()

I highly recognize the Chatgpt’s capabilities.

Last but not least, Chatgpt not only supported us write the test scripts how we can work with a local Mongodb, but also suggest us a script to populate more testing data into our mongodb.

from pymongo import MongoClient

# MongoDB configuration
MONGO_URI = 'mongodb://localhost:27017/'
DATABASE_NAME = 'test_db'
COLLECTION_NAME = 'users'

# MongoDB setup
client = MongoClient(MONGO_URI)
db = client[DATABASE_NAME]
collection = db[COLLECTION_NAME]

# Insert test users
users = [
    {"username": "admin1", "password": "admin123", "used": False},
    {"username": "admin2", "password": "admin123", "used": False},
    # Add more users as needed
]

collection.insert_many(users)
print("Users inserted into MongoDB.")

However, Chatgpt suggested me run a Mongodb server by command, let us ask it to build up Mongodb via Docker.

walking

walking

And here is the suggestions from Chatgpt:

walking

Now, let us test the information about what Chatgpt suggested me.

walking

Run a local mongodb container:

docker run --name mongodb -d -p 27017:27017 -v mongodb_data:/data/db mongo

Install pip install pymongo

walking

Run polulate_script_data.py:

walking

Validating the data is already inserted into my local Mongodb.

walking

Update the new test script that Chatgpt suggested me and execute it again.

import pytest
import requests
from pymongo import MongoClient

# MongoDB configuration
MONGO_URI = 'mongodb://localhost:27017/'
DATABASE_NAME = 'test_db'
COLLECTION_NAME = 'users'

# Define the URL
URL = 'http://127.0.0.1:5000/login'

# MongoDB setup
client = MongoClient(MONGO_URI)
db = client[DATABASE_NAME]
collection = db[COLLECTION_NAME]

def get_available_user():
    # Find an available user in the database
    user = collection.find_one({"used": False})
    if user:
        collection.update_one({"_id": user["_id"]}, {"$set": {"used": True}})
    return user

@pytest.fixture
def login_data():
    user = get_available_user()
    if user:
        return {
            "username": user["username"],
            "password": user["password"]
        }
    else:
        pytest.fail("No available users in the database.")

@pytest.fixture
def headers():
    return {'Content-Type': 'application/json'}

def test_login_success(headers, login_data):
    response = requests.post(URL, headers=headers, json=login_data)
    assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"

    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"

    token = response_data['data']['token']
    assert token is not None, "Token should not be None"
    print(f"Login successful. Token: {token}")

def test_login_failure(headers):
    # Test with wrong credentials
    wrong_data = {
        "username": "wrong_user",
        "password": "wrong_pass"
    }
    response = requests.post(URL, headers=headers, json=wrong_data)
    assert response.status_code == 401, f"Expected status code 401, but got {response.status_code}"

    response_data = response.json()
    assert 'data' in response_data, "Response JSON does not contain 'data' key"
    assert 'token' in response_data['data'], "Response JSON does not contain 'token' in 'data' key"
    assert response_data['data']['token'] is None, "Expected token to be None"

    assert 'message' in response_data, "Response JSON does not contain 'message' key"
    assert response_data[
               'message'] == 'Incorrect username or password', f"Expected message 'Incorrect username or password', but got {response_data['message']}"

if __name__ == "__main__":
    pytest.main()

walking

Join Newsletter
Get the latest news right in your inbox. We never spam!
Donald
Written by Donald
Hi, I am Donald (Doai Tran), the author of Testing4Everyone. I hope you like it!