Automating Test Generation with LLMs at Scale

assembled · Tech · 2023 · source Agentic: no · promotional bias: med · source-backed · extracted with prompt 0.5.4 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Engineering productivity and test generation

Assembled wanted engineers to create more comprehensive unit, frontend, and integration tests without spending hours manually enumerating scenarios and writing boilerplate.

Constraints:

Architecture

Assembled uses LLMs as an internal developer workflow for test creation. Engineers provide a structured prompt containing the function under test, relevant type definitions, and an example test suite from the codebase. A strong code model such as OpenAI o1-preview or Claude 3.5 Sonnet generates candidate tests, engineers review and refine the output for compilation, edge cases, and style, and only then copy the tests into the codebase.

Diagram confidence: reconstructed (reconstructed from prose).

flowchart LR
  example-test-suite[Example test suite] --> engineer-prompt[Engineer prompt]
  engineer-prompt --> code-generation-llm[Code generation LLM]
  code-generation-llm --> generated-test-suite[Generated test suite]
  generated-test-suite --> engineer-review-gate[Engineer review gate]
  engineer-review-gate --> codebase[Codebase]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Engineer prompt Packages the target code, type definitions, and testing examples for the LLM. Code generation LLM
Code generation LLM Generates candidate unit, frontend, or integration tests from the prompt. Engineer prompt, Generated test suite
Example test suite Shows the model the repository's idioms, conventions, libraries, and preferred test style. Engineer prompt
Generated test suite Contains the candidate test code returned by the model. Code generation LLM, Engineer review gate
Engineer review gate Checks compilation, edge cases, style, and logic before tests are merged. Generated test suite, Codebase
Codebase Receives the reviewed tests and provides examples that improve future prompts. Example test suite, Engineer review gate

Data flow

An engineer assembles a prompt with the exact function, relevant struct definitions, and example tests. The prompt is submitted to a high-quality code-generation model. The model returns a test suite, which the engineer checks for compilation, missed edge cases, and style before pasting the acceptable tests back into the repository.

3 supporting quotes
“* Function to test: Copy and paste the exact code you’re looking to write tests for. * Struct definitions: Include any relevant definitions that the function uses (especially for any objects that appear in the input or output of the function).”article, stated
“Struct definitions: Include any relevant definitions that the function uses (especially for any objects that appear in the input or output of the function).”article, stated
“Once you’ve dropped this into an LLM and generated a result, you might need to review and refine the generated tests.”article, stated

Why this architecture

The workflow is deliberately manual and example-driven because tests must compile, assert the right behavior, and match local conventions. Assembled prioritizes the smartest available models because latency is not a major concern for this offline developer workflow, while human review keeps incorrect or poorly formatted tests from reaching production.

3 supporting quotes
“Since latency isn't a major concern, we tend to use the best available models. * Code structure reflects testability: If you’re having trouble getting the LLM to construct suitable tests, consider refactoring your code.”article, stated
“Remember that your examples are often your most important way to drive the LLM to do what you want. * Use the smartest models: Models like o1-preview or Claude 3.”article, stated
“We insist that all Assembled engineers read and run any LLM-generated tests before merging into production. * Customize your prompt to your specific context: Our engineers have found that tailoring their prompts can significantly enhance the quality of the generated tests.”article, stated

Models used: OpenAI o1-preview · Anthropic Claude 3.5 Sonnet · ChatGPT o1-preview

Scale

Alternatives considered (roads not taken)

Use faster or cheaper models for test generation

Rejected because: The team says latency is not a major concern and recommends the smartest available models for better results.

“Use the smartest models: Models like o1-preview or Claude 3.5 Sonnet generally provide better results. Since latency isn't a major concern”article, stated

Merge LLM-generated tests without human verification

Rejected because: LLMs can get test logic wrong, so Assembled requires engineers to read and run generated tests before production.

“* Double check your test logic: While LLMs are pretty good out of the box, they can sometimes get tests wrong.”article, stated
“We insist that all Assembled engineers read and run any LLM-generated tests before merging into production. * Customize your prompt to your specific context: Our engineers have found that tailoring their prompts can significantly enhance the quality of the generated tests.”article, stated

Use generic prompts without examples

Rejected because: Assembled found examples are the strongest way to drive the model toward local style and conventions.

“* Examples matter: LLMs do their best work when they have a good example of tests to learn from. The engineering team at Assembled has built a large repository of comprehensive and idiomatic tests over time, which makes it easier to use these techniques.”article, stated

Patterns

prompt-versioning (prompting)

The workflow depends on a reusable structured prompt recipe with fixed sections for code, types, examples, and output expectations.

“The example prompt provided in the case study is notably detailed, specifying requirements like using the "fixture pattern"”summary, implied
“Function to test: Copy and paste the exact code you’re looking to write tests for.”article, stated

human-in-the-loop-gate (quality)

Engineers must read, run, and refine generated tests before merging them.

“We insist that all Assembled engineers read and run any LLM-generated tests before merging into production.”article, stated

model-routing (modeling)

Assembled selects high-capability code models for quality because the task is offline and latency-insensitive.

“Models like o1-preview or Claude 3.5 Sonnet generally provide better results. Since latency isn't a major concern”article, stated

eval-driven-development (quality)

Generated tests are treated as candidates that must compile, cover edge cases, and fit codebase conventions before acceptance.

“You should check for compilation issues, add any potential edge cases the LLM missed, and adjust the style to match your codebase conventions.”article, stated

Tradeoffs

Choose strongest models for offline developer tooling

Chose o1-preview or Claude 3.5 Sonnet over lower-latency or cheaper models.

Rationale: Test generation is not interactive production serving, so model quality is prioritized over latency.

“Models like o1-preview or Claude 3.5 Sonnet generally provide better results. Since latency isn't a major concern”article, stated

Use LLMs as a drafting accelerator rather than an autonomous merge system

Chose human review and iteration before copying tests into the codebase over automatically accepting generated tests.

Rationale: LLMs accelerate the tedious draft but engineers still own correctness, compilation, style, and production readiness.

“a few iterations of back and forth are sometimes necessary to arrive at an acceptable test suite. Once you’re close enough, just copy and paste the resulting tests back into your codebase.”article, stated
“We insist that all Assembled engineers read and run any LLM-generated tests before merging into production.”article, stated

Do not over-test simple code

Chose focus test-generation effort where tests provide meaningful confidence over using LLMs to generate tests for every simple glue or UI component.

Rationale: The team warns that not all code requires testing, so the automation should not turn into indiscriminate test expansion.

“Don’t overdo testing: You generally want to test the functions that have clear input / output and which contain the most important pieces of logic.”article, stated
“Not all code needs tests: The team advises against over-testing, particularly for simple glue code or basic UI components”summary, stated

Gotchas (what bit them)

LLM-generated tests can be wrong or non-compiling.

Root cause: The model may miss edge cases, generate incorrect logic, or misunderstand formatting requirements.

Resolution: Engineers review, refine, read, and run the tests before production merge.

“You should check for compilation issues, add any potential edge cases the LLM missed, and adjust the style to match your codebase conventions.”article, stated
“one of our engineers had an experience where the model gave incorrect output because of improper formatting.”article, stated

Weak examples reduce output quality.

Root cause: The model relies heavily on examples to learn desired test style, libraries, and conventions.

Resolution: Use comprehensive, idiomatic examples from the existing codebase in the prompt.

“LLMs do their best work when they have a good example of tests to learn from.”article, stated
“The engineering team at Assembled has built a large repository of comprehensive and idiomatic tests over time”article, stated

Difficult test generation can reveal code-design problems.

Root cause: Poorly structured or overly complex inputs/outputs make tests harder for the LLM to construct.

Resolution: Refactor the code or ask the LLM to break it up using the same prompting principles.

“If you’re having trouble getting the LLM to construct suitable tests, consider refactoring your code.”article, stated
“It’s likely that whatever combination of inputs and outputs you have may be poorly structured or overly complex.”article, stated

Evaluation

The article evaluates the workflow through concrete generated-test examples, engineer review requirements, and anecdotal productivity outcomes rather than a formal benchmark.

Metrics: 48 seconds to generate one comprehensive test suite · hundreds of engineering hours reportedly saved · generated tests checked for compilation issues, missed edge cases, and style · extension to Go, TypeScript, React component tests, and integration tests

3 supporting quotes
“in just 48 seconds, it generated a comprehensive test suite that was ready to use straight out of the box.”article, stated
“Collectively, our engineers have saved hundreds of hours, reallocating that time to developing new features and refining existing ones.”article, stated
“You should check for compilation issues, add any potential edge cases the LLM missed, and adjust the style to match your codebase conventions.”article, stated

Outcomes

The article gives one 48-second example and aggregate time-saved claims, but it does not disclose team size, number of generated tests, or acceptance rates.

3 supporting quotes
“Tasks that previously required hours can now be completed in just 5–10 minutes.”article, stated
“Different programming languages. It’s relatively straightforward to adjust the prompt for other languages”article, stated
“Collectively, our engineers have saved hundreds of hours, reallocating that time to developing new features and refining existing ones.”article, stated