hmu.ai
Back to Builder Agents
Builder Agent

Hyper-Focused Unit Test Cases for API Endpoint for Freelance Developers

Stop doing this manually. Deploy an autonomous Builder agent to handle unit test cases for api endpoint entirely in the background.

Zero-Shot Command Setup

Generate unit test cases for a Python Flask API endpoint `/api/v1/users` that handles POST requests to create a new user. The request body expects `username` (string, required) and `email` (string, required, unique). The endpoint returns HTTP 201 on success or 400 for validation errors (missing fields, duplicate email). Use `unittest` with `Flask.test_client()`.

Core Benefits & ROI

  • Ensures API reliability and correctness
  • Catches regressions early
  • Accelerates confident feature deployment
  • Improves code quality and maintainability
  • Validates input and output contracts
  • Boosts client and team trust

Ecosystem Integration

This "Builder" agent is fundamental to the *Quality Assurance & Testing* pillar, providing executable unit tests. It directly generates code to verify the functionality and robustness of an API endpoint, ensuring it adheres to its contract. This agent works in conjunction with "Builder" agents that create the API logic itself (e.g., Python functions for data handling) and ensures the reliability of components designed at the "Architect" level, safeguarding against bugs and regressions throughout the development lifecycle.

Sample Output

```python import unittest import json from app import app, db, User # Assuming app and db are imported, and User model exists # Ensure your app.py looks something like this (simplified): # from flask import Flask, request, jsonify # from flask_sqlalchemy import SQLAlchemy # # app = Flask(__name__) # app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' # Use an in-memory or test database # app.config['TESTING'] = True # app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # db = SQLAlchemy(app) # # class User(db.Model): # id = db.Column(db.Integer, primary_key=True) # username = db.Column(db.String(80), unique=True, nullable=False) # email = db.Column(db.String(120), unique=True, nullable=False) # # def __repr__(self): # return f'<User {self.username}>' # # def to_dict(self): # return {"id": self.id, "username": self.username, "email": self.email} # # @app.route('/api/v1/users', methods=['POST']) # def create_user(): # data = request.get_json() # if not data or not all(k in data for k in ['username', 'email']): # return jsonify({"message": "Missing username or email"}), 400 # # username = data['username'] # email = data['email'] # # if User.query.filter_by(email=email).first(): # return jsonify({"message": "Email already registered"}), 400 # if User.query.filter_by(username=username).first(): # return jsonify({"message": "Username already taken"}), 400 # # new_user = User(username=username, email=email) # db.session.add(new_user) # db.session.commit() # # return jsonify(new_user.to_dict()), 201 # # with app.app_context(): # db.create_all() class TestUserCreationEndpoint(unittest.TestCase): def setUp(self): # Set up a test client and a clean database for each test self.app = app.test_client() self.app_context = app.app_context() self.app_context.push() db.create_all() # Ensure tables are created for testing # Clear any existing data before each test User.query.delete() db.session.commit() def tearDown(self): # Clean up database after each test db.session.remove() db.drop_all() self.app_context.pop() def test_create_user_success(self): """Test creating a new user successfully.""" data = {'username': 'testuser', 'email': 'test@example.com'} response = self.app.post( '/api/v1/users', data=json.dumps(data), content_type='application/json' ) self.assertEqual(response.status_code, 201) response_data = json.loads(response.data) self.assertIn('id', response_data) self.assertEqual(response_data['username'], 'testuser') self.assertEqual(response_data['email'], 'test@example.com') self.assertIsNotNone(User.query.filter_by(username='testuser').first()) def test_create_user_missing_username(self): """Test creating a user with missing username field.""" data = {'email': 'missing_user@example.com'} response = self.app.post( '/api/v1/users', data=json.dumps(data), content_type='application/json' ) self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Missing username or email", response_data['message']) def test_create_user_missing_email(self): """Test creating a user with missing email field.""" data = {'username': 'missing_email'} response = self.app.post( '/api/v1/users', data=json.dumps(data), content_type='application/json' ) self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Missing username or email", response_data['message']) def test_create_user_duplicate_email(self): """Test creating a user with an email that already exists.""" # First, create a user successfully initial_data = {'username': 'firstuser', 'email': 'duplicate@example.com'} self.app.post('/api/v1/users', data=json.dumps(initial_data), content_type='application/json') # Try to create another user with the same email duplicate_data = {'username': 'seconduser', 'email': 'duplicate@example.com'} response = self.app.post( '/api/v1/users', data=json.dumps(duplicate_data), content_type='application/json' ) self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Email already registered", response_data['message']) def test_create_user_duplicate_username(self): """Test creating a user with a username that already exists.""" # First, create a user successfully initial_data = {'username': 'duplicate_name', 'email': 'unique1@example.com'} self.app.post('/api/v1/users', data=json.dumps(initial_data), content_type='application/json') # Try to create another user with the same username duplicate_data = {'username': 'duplicate_name', 'email': 'unique2@example.com'} response = self.app.post( '/api/v1/users', data=json.dumps(duplicate_data), content_type='application/json' ) self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Username already taken", response_data['message']) def test_create_user_empty_json(self): """Test creating a user with an empty JSON body.""" response = self.app.post( '/api/v1/users', data=json.dumps({}), content_type='application/json' ) self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Missing username or email", response_data['message']) def test_create_user_no_json_header(self): """Test creating a user without the application/json content type header.""" data = {'username': 'noheader', 'email': 'noheader@example.com'} response = self.app.post( '/api/v1/users', data=json.dumps(data) # No content_type specified ) # Flask's default behavior for missing content-type with json.dumps can be 400 # or 415 depending on how it's handled. Check your app's actual behavior. # For simplicity, if your app explicitly checks for request.is_json, this will fail. # Assuming the endpoint expects application/json explicitly. self.assertEqual(response.status_code, 400) response_data = json.loads(response.data) self.assertIn("Missing username or email", response_data['message']) # Or similar message from request.get_json() failing if __name__ == '__main__': unittest.main() ```

Frequently Asked Questions

Can this agent generate tests for other test frameworks like Pytest or Jest?

Yes, if specified in the command, this agent can generate test cases for various frameworks. You would need to explicitly request `Pytest` for Python, or `Jest` for JavaScript/Node.js, and provide context on the API (e.g., Express.js, FastAPI).

What kind of database interaction handling does this test use?

This example uses Flask-SQLAlchemy with a temporary SQLite in-memory database or a dedicated test database (configured in `app.config['SQLALCHEMY_DATABASE_URI']`) that is created and dropped for each test run. This ensures test isolation and prevents side effects between tests.