> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AI use-case: Generate load test scenarios with MCPs

> Automate Locust load testing by combining Chrome MCP and Context7 to generate realistic user behavior patterns with Claude Code.

export const PostMeta = ({data = {}}) => {
  const {author, date, image} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (!image && authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
      {image && <img src={image} alt="" className="post-meta-image" aria-hidden="true" />}
    </div>;
};

<PostMeta data={{ author: ["gmoigneu"], date: "2025-11-27T07:00:00+00:00", image: "/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/ai-use-case-generate-load-test-scenarios.webp" }} />

I don't know about you, but one task I have always been dreading for every critical project is actually creating the load-test performance scenarios... Whether that was with Apache JMeter or any other one, I've spent countless hours creating and debugging them. Handling cookies, customer login, etc.

As I needed to run another test on a new website, I started poking around the idea of using Claude Code to generate the test ... You can actually automate this process by connecting two Model Context Protocol (MCP) servers, Chrome MCP and Context7, to generate comprehensive test scenarios that match actual user navigation patterns.

## How MCPs automate scenario generation

Model Context Protocol (MCP) servers connect AI assistants like Claude Code to external data sources and tools. By combining two MCPs, you can automate load test creation:

1. **Chrome MCP** - Analyzes your live application by browsing pages, extracting navigation patterns, and understanding user flows
2. **Context7 MCP** - Retrieves current Locust documentation to generate syntactically correct test code

Here's how the workflow connects:

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'16px'}}}%%
graph LR
    A[Claude Code] -->|Browses & analyzes| B[Chrome MCP]
    A -->|Fetches docs| C[Context7 MCP]
    B -->|Navigation patterns| D[Your Website]
    C -->|Locust syntax| E[Locust Docs]
    A -->|Generates| F[locustfile.py]

    style A fill:#E8F9A3,stroke:#495867,stroke-width:3px,color:#495867
    style B fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style C fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style D fill:#ffa69e,stroke:#495867,stroke-width:2px,color:#495867
    style E fill:#ffa69e,stroke:#495867,stroke-width:2px,color:#495867
    style F fill:#E8F9A3,stroke:#495867,stroke-width:3px,color:#495867
```

## Setting up your environment

Before generating tests, configure both MCP servers in your Claude Code environment.

### Install Chrome MCP

The Chrome MCP lets Claude Code control a Chrome browser to explore your application:

```bash {filename="Terminal"} theme={null}
claude mcp add -t stdio npx chrome-devtools-mcp@latest --scope user
```

<Note>
  The `--scope user` parameter make the MCP global for all projects.
</Note>

### Configure Context7 MCP

Context7 provides access to technical documentation:

```bash {filename="Terminal"} theme={null}
claude mcp add --transport http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: YOUR_API_KEY"  --scope user
```

*Note: The API key is optional and only required if you are generating a high usage of Context7.*

### Install the Locust tool

Set up Locust in a virtual environment to keep dependencies isolated:

```bash {filename="Terminal"} theme={null}
# Create a virtual environment
python3 -m venv locust-env

# Activate it (macOS/Linux)
source locust-env/bin/activate

# Or on Windows
# locust-env\Scripts\activate

# Install Locust
pip install locust

# Verify installation
locust --version
```

Keep this environment activated when running your load tests. You can deactivate it later with `deactivate`.

## Generating load tests for an e-commerce site

Let's generate Locust tests for an e-commerce platform. This example demonstrates how Claude Code uses both MCPs to create realistic user scenarios.

We are going to use the Magento Association website as an example:

<img src="https://mintcdn.com/upsun-c9761871/ZBMwngApLEEeuab_/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/magento-association.webp?fit=max&auto=format&n=ZBMwngApLEEeuab_&q=85&s=dccacae6e3c281880fe8a74e179a5cc8" alt="Magento Association" width="3108" height="1972" data-path="images/posts/hands-on/ai-use-case-generate-load-test-scenarios/magento-association.webp" />

### Upsun resources for preview environments

Before running load tests, configure your test environment properly. Upsun now allows you to [customize resources for preview environments](/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/change-resources.webp), making it perfect for realistic load testing without impacting production.

You can temporarily provision the same resource levels as your production environment on a preview environment just for the duration of your tests. This means no more running tests against production at night or hoping staging accurately reflects production performance. Spin up a preview environment with production-equivalent CPU, memory, and storage, run your comprehensive load tests, analyze the results, and then scale it back down—all without risking your live site.

<img src="https://mintcdn.com/upsun-c9761871/ZBMwngApLEEeuab_/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/change-resources.webp?fit=max&auto=format&n=ZBMwngApLEEeuab_&q=85&s=ce3e8bca5af9dbdbc30485ad208524a9" alt="Change resources" width="3108" height="1972" data-path="images/posts/hands-on/ai-use-case-generate-load-test-scenarios/change-resources.webp" />

### Prompt Claude Code

Start by describing what you need:

```text {filename="claude"} theme={null}
Analyze the e-commerce site at https://example-shop.com/ and generate Locust 
load test scenarios. Create three user types:

1. Browser - go to the home page, views products, searches, but doesn't buy (70% of users)
2. Campaign - go to a product page directly 
3. Shopper - adds items to cart and review the cart (25% of users)

Use Chrome MCP to explore the site navigation and Context7 to get current 
Locust documentation. Generate a complete locustfile.py with realistic timing.

Once done, give me the instruction to run the test.
```

<iframe width="800" height="450" src="https://www.youtube.com/embed/4fHpFxnkoQo?si=6UCKjdte9TpffdLl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

### What Claude Code does

Claude Code executes this workflow:

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'14px'}}}%%
graph LR
    A[User Prompt] --> B[Analyze Site]
    B --> C[Chrome MCP Explores]
    C --> D[Extract Patterns]
    D --> E[Fetch Locust Docs]
    E --> F[Context7 Retrieves]
    F --> G[Generate Code]
    G --> H[locustfile.py]

    style A fill:#E8F9A3,stroke:#495867,stroke-width:2px,color:#495867
    style B fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style C fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style D fill:#ffa69e,stroke:#495867,stroke-width:2px,color:#495867
    style E fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style F fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style G fill:#ff686b,stroke:#495867,stroke-width:2px,color:#495867
    style H fill:#E8F9A3,stroke:#495867,stroke-width:3px,color:#495867
```

1. **Analyzes the site structure** using Chrome MCP:
   * Navigates through product categories
   * Identifies search functionality
   * Maps the checkout process
   * Notes authentication requirements

2. **Retrieves Locust documentation** via Context7:
   * Gets syntax for HttpUser classes
   * Checks task decorator usage
   * Reviews wait\_time configurations
   * Verifies weight attribute usage

3. **Generates the test file** combining both sources of information

### Example generated output

The generated test creates three distinct user types with different behaviors and weights:

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'14px'}}}%%
graph LR
    A[Load Test Users] --> B[Browser 70%]
    A --> C[Campaign 5%]
    A --> D[Shopper 25%]

    B --> B1[View Homepage]
    B --> B2[Browse Categories]
    B --> B3[View Products]
    B --> B4[Search]

    C --> C1[Campaign Landing]
    C --> C2[View Product]
    C --> C3[Explore Category]

    D --> D1[Browse Products]
    D --> D2[Add to Cart]
    D --> D3[View Cart]
    D --> D4[Update Cart]

    style A fill:#E8F9A3,stroke:#495867,stroke-width:3px,color:#495867
    style B fill:#B5A8FF,stroke:#495867,stroke-width:2px,color:#495867
    style C fill:#ff686b,stroke:#495867,stroke-width:2px,color:#495867
    style D fill:#ffa69e,stroke:#495867,stroke-width:2px,color:#495867
    style B1 fill:#B5A8FF,stroke:#495867,stroke-width:1px,color:#495867
    style B2 fill:#B5A8FF,stroke:#495867,stroke-width:1px,color:#495867
    style B3 fill:#B5A8FF,stroke:#495867,stroke-width:1px,color:#495867
    style B4 fill:#B5A8FF,stroke:#495867,stroke-width:1px,color:#495867
    style C1 fill:#ff686b,stroke:#495867,stroke-width:1px,color:#495867
    style C2 fill:#ff686b,stroke:#495867,stroke-width:1px,color:#495867
    style C3 fill:#ff686b,stroke:#495867,stroke-width:1px,color:#495867
    style D1 fill:#ffa69e,stroke:#495867,stroke-width:1px,color:#495867
    style D2 fill:#ffa69e,stroke:#495867,stroke-width:1px,color:#495867
    style D3 fill:#ffa69e,stroke:#495867,stroke-width:1px,color:#495867
    style D4 fill:#ffa69e,stroke:#495867,stroke-width:1px,color:#495867
```

<Note>
  You can review the generated [`locustfile.py` on Github](https://gist.github.com/gmoigneu/180fdc2516f734be69ed10628c4a1d6f)
</Note>

## Running your generated tests

Once you have the locustfile, start testing:

```bash {filename="Terminal"} theme={null}
# Install Locust if needed
pip install locust

# Run with web interface
locust -f locustfile.py --host=https://example-shop.com

# Run headless for CI/CD
locust -f locustfile.py \
  --host=https://example-shop.com \
  --users=100 \
  --spawn-rate=10 \
  --run-time=5m \
  --headless
```

Access the web interface at `http://localhost:8089` to monitor test execution, view statistics, and adjust user counts.

<img src="https://mintcdn.com/upsun-c9761871/ZBMwngApLEEeuab_/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/locust-graph.webp?fit=max&auto=format&n=ZBMwngApLEEeuab_&q=85&s=0c55528a22e181cd66b2679391f0379c" alt="Locust Graph" width="3108" height="1972" data-path="images/posts/hands-on/ai-use-case-generate-load-test-scenarios/locust-graph.webp" />

<img src="https://mintcdn.com/upsun-c9761871/ZBMwngApLEEeuab_/images/posts/hands-on/ai-use-case-generate-load-test-scenarios/locust-stats.webp?fit=max&auto=format&n=ZBMwngApLEEeuab_&q=85&s=ca20ee628d80eaf9648edf143c6fb847" alt="Locust Stats" width="3108" height="1972" data-path="images/posts/hands-on/ai-use-case-generate-load-test-scenarios/locust-stats.webp" />

## What's next?

Generating the test scenarios is just the beginning. Claude Code can continue assisting throughout your entire load testing workflow. Once your tests are running, you can ask Claude Code to **analyze the Locust output**, **identify performance bottlenecks** from the statistics, and interpret failure patterns. Simply share the results with Claude Code and request an analysis.

Beyond diagnostics, Claude Code can **suggest specific code optimizations based on your test results**. If certain endpoints show high response times or failure rates, Claude Code can examine your application code, propose caching strategies, recommend database query optimizations, or suggest architectural improvements. This closes the loop from test generation to actionable performance improvements, all within a single AI-powered workflow.

***

Ready to automate your load testing? [Create a free Upsun account](https://upsun.com) to deploy and run your generated Locust tests in isolated environments with full observability.
