Home / Insights / QA and Software Testing

QA and Software Testing

From AI-Generated Code to Maintainable Software: A Review and Quality Framework

AI coding assistants make it easy to produce code quickly; making it correct, secure and maintainable is still an engineering discipline. This guide shows how to give assistants the right context, review AI-generated changes by risk, enforce quality in CI and measure the real effect on delivery.

TopicsQA and Software TestingAI and Machine LearningWeb and SaaS Development

Key takeaways

  • “Vibe coding” — accepting generated code that seems to work — is fine for throwaway prototypes and risky for anything that will be maintained, secured or scaled.
  • Most poor AI output comes from missing context. Give assistants architecture notes, conventions, commands and examples in versioned context files, and keep tasks small.
  • Review by risk: authentication, payments, data access and migrations need senior human review regardless of who or what wrote the code.
  • Automate the checks machines do well — tests, types, linting, security scanning, dependency verification — and focus human review on design, intent and edge cases.
  • Measure change failure rate, escaped defects, review time and rework alongside speed; output volume alone says nothing about value.

AI coding assistants have changed how software is written. Developers generate functions, tests and whole features from a description, and agents can now make multi-file changes and run the tests themselves. The term “vibe coding” describes the extreme: describing what you want, accepting what the assistant produces and adjusting until it seems to work, without reading the code closely.

For a prototype or personal script, that can be perfectly reasonable. For software a business depends on, the costs arrive later — in security flaws, duplicated logic, inconsistent patterns and code nobody fully understands. Independent research gives reasons for caution. Veracode’s 2025 GenAI Code Security Report tested more than 100 language models on 80 coding tasks and found that 45% of the generated code samples introduced security flaws, with no meaningful improvement in security from newer or larger models. A USENIX Security 2025 study of 576,000 generated code samples found that models recommended non-existent packages at an average rate of at least 5.2% for commercial models and 21.7% for open-source models — names an attacker could register with malicious code.

None of this means teams should avoid AI tools. It means review and quality practices have to adapt. This guide sets out a practical framework from a QA perspective.

Where vibe coding is fine and where it is not

ContextAcceptable approachWhy
———
Throwaway prototype or spikeLight review; discard afterwardsLearning is the goal; code will not ship
Internal script or tool with low riskNormal review; basic testsLimited blast radius
Product feature in a maintained codebaseFull review against conventions; tests requiredOthers will maintain and extend it
Security, payments, personal data, infrastructureSenior review, security checks, threat considerationMistakes are costly and may be invisible
Regulated or safety-relevant systemsAll of the above plus documented verificationCompliance and accountability

The standard depends on the consequences of a defect, not on who wrote the code.

Context engineering: better input, better code

Many problems blamed on AI tools come from asking them to work blind. An assistant that does not know your architecture, conventions or constraints will invent its own. Context engineering means deliberately giving assistants the information a new team member would need.

Context files in the repository

Most coding assistants and agents can read instruction files kept in the repository. Whatever format your tools use, include:

  • Architecture overview: main modules, their responsibilities and the boundaries between them.
  • Conventions: naming, error handling, logging, state management, API patterns and preferred libraries.
  • Commands: how to build, run tests, lint and start the application locally.
  • Constraints: what must never be done — calling the database from the UI layer, adding dependencies without approval, logging personal data.
  • Examples: links to files that show the preferred pattern for a controller, a repository, a test.

Version these files with the code, review changes to them like code, and keep them short enough to stay accurate.

An illustrative excerpt from a repository context file:

# Project context for coding assistantsStack: TypeScript, Next.js (app router), PostgreSQL via Prisma.Run tests: pnpm test Lint and types: pnpm check Architecture- UI components never call the database. Use server actions in /app/actions.- All data access goes through repositories in /lib/repositories.- Authorisation: call requireAccountAccess(user, accountId) before reading  or writing any account-scoped record. Conventions- Validation with zod schemas in /lib/validation; reuse existing schemas.- Money is stored as integer minor units with an ISO currency code.- Log with logger.info/warn/error; never log personal data or tokens. Do not- Add new dependencies without approval in the pull request description.- Write raw SQL outside /lib/repositories.

Task-level context

  • Small, well-defined tasks produce better results than broad requests. “Add server-side validation for the postcode field in the address form, following the pattern in UserProfileValidator” beats “improve the checkout”.
  • Point to relevant files rather than relying on the assistant to find them.
  • State acceptance criteria and edge cases — the same ones you would give a developer.
  • Ask for tests first or alongside, and make the assistant run them.

Tool-level context

Agents that can run tests, linters and type checkers get immediate feedback and correct many errors before a human sees them. Give them a sandboxed environment with those commands available, without production credentials.

A risk-based review model

Not every change deserves the same scrutiny. Classify pull requests by risk and set review requirements accordingly — regardless of whether a person or a tool wrote the code.

TierTypical changesReview requirement
———
Tier 1: lowCopy changes, styling, test additions, internal tooling, isolated refactors with full test coverageOne reviewer; automated checks must pass
Tier 2: standardNew features and bug fixes in business logicOne reviewer familiar with the area; tests for new behaviour; manual check of edge cases
Tier 3: highAuthentication, authorisation, payments, personal data, cryptography, infrastructure, database migrations, public APIsSenior or specialist reviewer; security checklist; migration and rollback plan

Automate tier detection where possible, for example by file paths and labels, and let reviewers raise the tier.

Two additional rules work well for AI-assisted changes:

  • The author owns the code. Whoever opens the pull request must be able to explain every line. “The assistant wrote it” is not an answer in review.
  • Keep changes reviewable. AI tools make large diffs easy to produce. Set a soft limit on change size and split larger work.

The review checklist

Automated tools catch much of the mechanical, so human reviewers should focus here:

Intent and design

  • Does the change solve the stated problem and nothing else?
  • Does it follow existing architecture and patterns, or introduce a parallel way of doing the same thing?
  • Is there duplicated logic that already exists elsewhere in the codebase?

Correctness

  • Are edge cases handled: empty inputs, nulls, limits, time zones, currencies, concurrency, retries?
  • Are error paths handled deliberately, not swallowed?
  • Do the tests check behaviour, or merely mirror the implementation?

Security

  • Is all input validated and output encoded?
  • Are authorisation checks present on every new endpoint and data access?
  • Are secrets, tokens and personal data kept out of code and logs?
  • Are queries parameterised and file paths constrained?

Dependencies

  • Does every new package exist, come from the expected publisher and have healthy maintenance?
  • Was the dependency necessary, or could existing code do the job?

Maintainability

  • Would a new team member understand this in six months?
  • Are names, comments and structure consistent with the codebase?
  • Is there dead code, unused parameters or speculative generality?

Automate the gates

GateWhat it checksNotes for AI-generated code
———
Unit and integration testsBehaviour and regressionsRequire tests for new behaviour; check that tests fail without the change
Type checking and lintingType errors, style, common bugsCheap and catches many generated inconsistencies
Static application security testingInjection, unsafe functions, insecure patternsParticularly important given security findings in generated code
Dependency verificationPackage existence, known vulnerabilities, licenceBlock unknown or newly registered packages pending review
Secret scanningKeys and credentials in codeAssistants sometimes copy example credentials into code
Coverage on changed linesUntested new codeUse as a signal, not a target to game
Architecture rulesForbidden imports and layer violationsEncodes boundaries assistants may not know

Gates should run on every pull request and block merging when they fail.

For high-risk tiers, add dynamic testing in a staging environment and, where relevant, threat modelling for new data flows. Our guide to AI in software testing covers how AI can also help generate and maintain tests — with the same need for review.

Common failure patterns in generated code

Knowing what to look for makes review faster. These patterns appear repeatedly in AI-assisted pull requests:

PatternWhat it looks likeHow to catch it
———
Plausible but wrong API useCalls to functions or options that do not exist in your library version, or that behave differentlyType checks, tests, reading the library docs for unfamiliar calls
Invented dependenciesImports of packages that do not exist or are not the intended onesDependency verification gate; registry and publisher checks
Missing authorisationNew endpoint authenticates the user but does not check access to the specific recordTier 3 classification for data access; authorisation tests
Happy-path onlyNo handling for empty, null, oversized or malformed inputs; errors swallowedEdge-case checklist; property-based or boundary tests
Duplicated logicA new helper that re-implements an existing utility slightly differentlyReviewer familiarity; context files listing shared utilities
Inconsistent patternsA different state-management, error or logging approach from the rest of the codebaseConventions in context files; architecture lint rules
Tests that mirror the codeTests assert what the implementation does rather than what the requirement saysWrite or review acceptance criteria first; mutation testing on critical code
Outdated practicesDeprecated APIs, weak hashing, insecure defaults learned from old examplesStatic analysis rules; security checklist

Add the patterns you see most often to your context files and review checklist.

Worked example: reviewing a generated endpoint

A developer asks an assistant to add an endpoint that lets customers download past invoices as PDFs. The assistant produces a working endpoint, a PDF generator and two tests in a few minutes. Everything passes locally.

Applying the framework:

  1. Tier: the change exposes customer financial documents, so it is tier 3. A senior reviewer is assigned.
  2. Automated gates: tests, types and lint pass. The dependency gate flags a new PDF library the codebase does not use; the team already has an approved one. The developer switches to it.
  3. Authorisation review: the endpoint checks that the user is logged in, but loads the invoice by ID without checking that it belongs to the user’s account. Any logged-in customer could download any invoice by changing the number. The reviewer requires an ownership check and a test proving that another customer’s invoice returns 404.
  4. Edge cases: the code fails on invoices with credit notes and multiple currencies. The developer adds handling and tests using fixture data.
  5. Operational concerns: generating large PDFs synchronously could tie up servers. The team agrees to cache generated files and add a rate limit.
  6. Maintainability: the generated PDF layout code duplicates an existing template helper; the developer refactors to use it.

The final change took longer than the first draft — but far less time than building it from scratch, and without an access-control flaw that automated tests alone would have missed.

A policy for what tools may see

Teams also need clear rules about the information they share with AI tools:

  • Approved tools only, configured under business agreements that define data retention and training use.
  • No secrets in prompts or context files: API keys, passwords and production connection strings stay in secret managers.
  • No production personal data pasted into assistants for debugging; use synthetic or masked data.
  • Client confidentiality: for agencies and outsourced teams, confirm each client’s position on AI tools before use, and record it.
  • Licence awareness: check that generated code does not reproduce substantial third-party code with incompatible licences; some tools offer filters for this.

Using AI to help review

AI review tools can summarise changes, point out likely bugs and check for missing tests. They are useful as a first pass that makes human review faster. They are not a substitute: they share many of the blind spots of the tools that wrote the code, and they do not know your business intent. Treat their comments as suggestions for the human reviewer to accept or reject.

Metrics that show the real effect

Measuring AI-assisted development by lines of code or number of pull requests rewards the wrong things. Track delivery and quality together:

MetricWhat it tells you
——
Lead time for changesWhether work reaches production faster
Change failure rateShare of deployments causing incidents or rollbacks
Escaped defectsBugs found after release, by severity and component
Review time and review roundsWhether review has become a bottleneck or rubber stamp
Rework rateCode changed again within a few weeks of merging
Security findings per releaseWhether vulnerabilities are rising
Developer experienceShort surveys on confidence in the codebase and tooling

Compare teams or periods with and without heavy AI use, and look for trade-offs rather than a single headline.

If speed rises while change failure rate, escaped defects or rework also rise, the team is borrowing from the future.

When agents make multi-file changes

Coding agents increasingly plan and implement changes across many files, run tests and iterate. That raises the stakes for review:

  • Require a plan first. Ask the agent to describe the intended changes before writing code, and approve the plan for tier 2 and 3 work.
  • Constrain the workspace. Run agents in a sandbox with test and lint commands but no production credentials or deployment rights.
  • Review the whole diff, not the summary. Agent summaries can omit side effects such as changed configuration, deleted tests or loosened validation.
  • Watch for test tampering. An agent asked to make tests pass may change the tests. Flag any modification to existing tests for explicit reviewer attention.
  • Keep commits small and logical so changes can be reviewed and reverted independently.

Signs your process is not working

  • Pull requests are getting larger, and review comments are getting shorter.
  • Reviewers approve tier 3 changes in minutes.
  • Escaped defects or security findings rise while delivery speed rises.
  • The same bug pattern appears in several places, suggesting copied generated code.
  • Developers cannot explain how parts of the system they recently changed work.
  • Context files have not been updated in months despite architectural changes.

If you see these signs, slow down deliberately: tighten tiers, reduce change size, and run a short retrospective on recent incidents to update the checklist.

Rolling out a framework across a team

  1. Agree the policy: approved tools, data that may and may not be shared with them, ownership rules and review tiers.
  2. Write context files for each main repository and review them with senior engineers.
  3. Turn on the automated gates, starting with tests, type checks, secret scanning and dependency verification.
  4. Train reviewers on the checklist and on common failure patterns in generated code.
  5. Baseline the metrics for a month, then review them monthly and adjust the framework.
  6. Share examples of good and bad AI-assisted changes in team retrospectives.

Frequently asked questions

Should AI-generated code be labelled in pull requests?

It can help reviewers calibrate, but the review standard should depend on risk, not authorship. The author remains responsible either way.

Do AI tools make junior developers less capable?

They can if juniors accept code they do not understand. Require them to explain their changes, pair them with seniors on high-risk work and use the tools for learning as well as output.

How do we prevent hallucinated packages?

Verify every new dependency against the official registry and expected publisher, block unknown packages in CI and use lockfiles. Treat a new dependency as a design decision that needs review.

Can we let an agent merge its own changes?

Not for production code. Agents can open pull requests, run tests and respond to review comments; merging should require human approval and passing gates.

Is this framework only for AI-generated code?

No. Risk tiers, checklists and automated gates improve every review. AI tools simply increase the volume of code that needs them.

Sources and methodology

Facts in this article were checked against the sources below on 6 November 2026. Directory data (ratings, review counts, rate bands and team sizes) changes over time and is shown as published on the date accessed. Illustrative examples are labelled as such and are not quotes.

  1. Veracode (30 July 2025): AI-generated code poses major security risks in nearly half of all development tasks — accessed 6 November 2026. 80 tasks, more than 100 models; 45% of samples introduced security flaws; no security improvement in newer or larger models
  2. Spracklen et al.: We Have a Package for You! (USENIX Security 2025; arXiv 2406.10279) — accessed 6 November 2026. 576,000 code samples from 16 models; hallucinated packages at least 5.2% (commercial) and 21.7% (open-source); 205,474 unique hallucinated names
  3. OWASP: Top 10 for LLM Applications 2025 — accessed 6 November 2026. LLM05 Improper Output Handling and supply-chain risks

Using AI coding tools across your team?

Tell us about your stack, team and review process. We will help you set up context files, review tiers, CI gates and metrics so speed does not come at the cost of quality.