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.
On this page
- Where vibe coding is fine and where it is not
- Context engineering: better input, better code
- A risk-based review model
- The review checklist
- Automate the gates
- Common failure patterns in generated code
- Worked example: reviewing a generated endpoint
- A policy for what tools may see
- Using AI to help review
- Metrics that show the real effect
- When agents make multi-file changes
- Signs your process is not working
- Rolling out a framework across a team
- Frequently asked questions
- Sources and methodology
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
| Context | Acceptable approach | Why |
|---|---|---|
| — | — | — |
| Throwaway prototype or spike | Light review; discard afterwards | Learning is the goal; code will not ship |
| Internal script or tool with low risk | Normal review; basic tests | Limited blast radius |
| Product feature in a maintained codebase | Full review against conventions; tests required | Others will maintain and extend it |
| Security, payments, personal data, infrastructure | Senior review, security checks, threat consideration | Mistakes are costly and may be invisible |
| Regulated or safety-relevant systems | All of the above plus documented verification | Compliance 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.
| Tier | Typical changes | Review requirement |
|---|---|---|
| — | — | — |
| Tier 1: low | Copy changes, styling, test additions, internal tooling, isolated refactors with full test coverage | One reviewer; automated checks must pass |
| Tier 2: standard | New features and bug fixes in business logic | One reviewer familiar with the area; tests for new behaviour; manual check of edge cases |
| Tier 3: high | Authentication, authorisation, payments, personal data, cryptography, infrastructure, database migrations, public APIs | Senior 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
| Gate | What it checks | Notes for AI-generated code |
|---|---|---|
| — | — | — |
| Unit and integration tests | Behaviour and regressions | Require tests for new behaviour; check that tests fail without the change |
| Type checking and linting | Type errors, style, common bugs | Cheap and catches many generated inconsistencies |
| Static application security testing | Injection, unsafe functions, insecure patterns | Particularly important given security findings in generated code |
| Dependency verification | Package existence, known vulnerabilities, licence | Block unknown or newly registered packages pending review |
| Secret scanning | Keys and credentials in code | Assistants sometimes copy example credentials into code |
| Coverage on changed lines | Untested new code | Use as a signal, not a target to game |
| Architecture rules | Forbidden imports and layer violations | Encodes 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:
| Pattern | What it looks like | How to catch it |
|---|---|---|
| — | — | — |
| Plausible but wrong API use | Calls to functions or options that do not exist in your library version, or that behave differently | Type checks, tests, reading the library docs for unfamiliar calls |
| Invented dependencies | Imports of packages that do not exist or are not the intended ones | Dependency verification gate; registry and publisher checks |
| Missing authorisation | New endpoint authenticates the user but does not check access to the specific record | Tier 3 classification for data access; authorisation tests |
| Happy-path only | No handling for empty, null, oversized or malformed inputs; errors swallowed | Edge-case checklist; property-based or boundary tests |
| Duplicated logic | A new helper that re-implements an existing utility slightly differently | Reviewer familiarity; context files listing shared utilities |
| Inconsistent patterns | A different state-management, error or logging approach from the rest of the codebase | Conventions in context files; architecture lint rules |
| Tests that mirror the code | Tests assert what the implementation does rather than what the requirement says | Write or review acceptance criteria first; mutation testing on critical code |
| Outdated practices | Deprecated APIs, weak hashing, insecure defaults learned from old examples | Static 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:
- Tier: the change exposes customer financial documents, so it is tier 3. A senior reviewer is assigned.
- 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.
- 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.
- Edge cases: the code fails on invoices with credit notes and multiple currencies. The developer adds handling and tests using fixture data.
- Operational concerns: generating large PDFs synchronously could tie up servers. The team agrees to cache generated files and add a rate limit.
- 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:
| Metric | What it tells you |
|---|---|
| — | — |
| Lead time for changes | Whether work reaches production faster |
| Change failure rate | Share of deployments causing incidents or rollbacks |
| Escaped defects | Bugs found after release, by severity and component |
| Review time and review rounds | Whether review has become a bottleneck or rubber stamp |
| Rework rate | Code changed again within a few weeks of merging |
| Security findings per release | Whether vulnerabilities are rising |
| Developer experience | Short 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
- Agree the policy: approved tools, data that may and may not be shared with them, ownership rules and review tiers.
- Write context files for each main repository and review them with senior engineers.
- Turn on the automated gates, starting with tests, type checks, secret scanning and dependency verification.
- Train reviewers on the checklist and on common failure patterns in generated code.
- Baseline the metrics for a month, then review them monthly and adjust the framework.
- 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.
- 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
- 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
- OWASP: Top 10 for LLM Applications 2025 — accessed 6 November 2026. LLM05 Improper Output Handling and supply-chain risks
Related reading
Continue your research
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.
