End-to-end (E2E) testing checks whether a complete application workflow produces the expected result through the same entry point a user or client uses. For an AWS application, that can mean sending a request to a deployed API, passing through configured services, and verifying the resulting response and stored record.
A passing E2E test is evidence for that workflow in that test environment. It does not replace unit tests, focused integration tests, load tests, or security testing. The practices below help make AWS end-to-end tests useful, repeatable, and safe to run.
1. Test the deployed workflow in the cloud
Choose a user-visible behavior and exercise it through the deployed application's normal interface: for example, submit an order through an API and verify its response and resulting state. A cloud test can cover service configuration, IAM permissions, networking, event delivery, and the managed services that a local process cannot fully reproduce. AWS recommends cloud-based tests for serverless applications because they exercise the deployed code and services together.
Deploy the test version into a dedicated account or an isolated stack in a non-production account. Keep its architecture close enough to production to cover the settings that matter, while using synthetic test data and test-only identities. Never point an automated test at production data or let it modify production resources.
Give each test run a unique name or identifier and use it in stack names, test records, and logs. This makes overlapping runs easier to isolate and clean up. If an endpoint accepts work asynchronously, an accepted response only proves that the request was accepted; verify the later business outcome as well.
For an API-backed order flow, a practical check might:
Create a unique test run ID and submit an order through the deployed API as a test user.
Assert the documented success response and capture the returned order ID.
Poll the read endpoint for that order until it reaches the expected state or a deadline expires.
Verify the run ID identifies exactly one expected order, then remove its test data during cleanup.
See the AWS Lambda testing guide for examples of cloud tests that validate deployed service interactions and configuration.
2. Keep application code easy to test
Separate business decisions from code that adapts an AWS event, calls an SDK, or formats an HTTP response. A thin handler can validate and translate its input, call application logic, then format the result. This lets unit tests cover many business cases without deploying AWS resources, while a smaller set of cloud tests checks the adapters and service wiring.
Keep the E2E test itself readable: arrange unique input data, call the real test endpoint, and assert the externally visible result. Prefer checks on stable behavior—such as a response schema and a persisted business outcome—over assertions about internal implementation details that may change during a refactor.
3. Automate the test pipeline and make it fail clearly
Run the fast checks first, then deploy or update the isolated test environment and run the E2E suite against its outputs. Make a failed required test fail the CI job so it cannot be mistaken for a successful build. Keep the deployment identifier, test report, and useful logs with the run so a developer can reproduce the problem.
Use the same provisioning and test commands in local development and CI where practical, with configuration that selects the test account, region, and unique stack name. Limit parallelism when tests share a resource; otherwise, give each run separate resources and data. AWS CodeBuild can publish reports from common test-framework formats, which makes failures and trends available after a build.
Do not treat “the pipeline ran” as proof that the test reached the application. Check that the environment deployment succeeded, the test cases actually executed, and their results reached the CI system.
4. Use each test level for its own question
Test type
What it checks
Typical environment
Unit
A small block of code in isolation, such as a pricing rule
Usually local; dependencies are often replaced with test doubles
Integration
Two or more components working together, such as a function writing to a test table
Local or cloud, depending on which real integrations matter
End to end
A complete application workflow through its external interface to its expected outcome
Usually a deployed, isolated AWS environment when validating AWS service behavior
Keep many fast, focused unit tests, add integration tests at important service boundaries, and reserve E2E tests for a small set of critical user journeys. The exact balance depends on the application; the point is to catch most logic defects close to their source and use E2E tests to check that the deployed pieces work together.
An E2E test does not have to imitate every internal call or cover every input combination. That makes the suite slower and can make failures harder to diagnose without adding useful evidence.
5. Use mocks and emulators for fast feedback
Mocks and service emulators are useful when checking business logic, error handling, and event parsing without waiting for a cloud deployment. They let a test control a dependency's response, but they cannot prove that AWS accepted the deployed configuration or that a real service will invoke the function with the same permissions and behavior.
The AWS SAM CLI can run Lambda functions and an API locally. Those checks are valuable during development, but local invocation is not proof that the deployed AWS workflow works. A local function may still call real AWS resources if it has working credentials, so configure test endpoints and credentials carefully; a local run can still incur charges or change cloud data.
Use local tests to shorten the feedback loop, then keep cloud integration or E2E checks for the behaviors that depend on actual AWS service configuration. AWS documents both local testing with SAM and its separate cloud-testing guidance.
6. Exercise service integrations and event flows
Test the application path across real AWS boundaries when service configuration is part of the behavior. For example, a test that passes an SQS-shaped JSON event directly to a Lambda handler checks handler logic; it does not prove that the deployed queue, event source mapping, and execution role invoke that function successfully. AWS calls out this difference in its serverless testing guidance.
For asynchronous workflows, assert the eventual business result instead of expecting every side effect to be visible immediately. Poll the test resource for the expected state using a bounded deadline and a short interval that can grow between attempts; fail with the run ID and observed state when the deadline expires. Avoid a single fixed sleep, which can be too short in a slow run and waste time in a fast one.
Account for delivery retries and duplicate events in both the application and test data. For example, Lambda event source mappings process SQS messages at least once, so a test should verify the intended result without assuming exactly one invocation. Use a unique event identifier, make operations safe to repeat, and check the configured failure path when it is part of the workflow. See AWS documentation on Lambda with SQS and asynchronous Lambda retries.
7. Choose tools for the layer being tested
Use infrastructure as code to provision a repeatable cloud test environment. AWS SAM, AWS CDK, or CloudFormation can define the application resources; the important part is that the test deploys the configuration you intend to check. CloudFormation stacks provide a way to manage a set of resources together, but a stack deployment does not itself prove the workflow works.
Use sam local invoke or sam local start-api for local function and API feedback. Use a CI runner such as AWS CodeBuild or your existing CI service to run the commands that deploy the test stack and execute the cloud suite. If you use CodeBuild, its test reporting can preserve case-level results. Select the tools to match the part of the system under test; no local tool removes the need to verify AWS-specific behavior in AWS.
8. Keep load and cost testing separate
Functional E2E checks ask whether a user journey produces the right outcome. They do not establish how the workload behaves under high concurrency, sustained traffic, or traffic spikes. Design load tests separately with explicit traffic patterns, performance targets, a controlled environment, and synthetic or sanitized data. An E2E suite can still catch a basic response-time regression, but it is not a substitute for a load test.
Resources used by cloud test environments can incur charges, even for short runs. Choose resource sizes and run frequency deliberately, add account-level spending alerts or other guardrails where appropriate, and avoid provisioning production-scale capacity for every pull request unless the test requires it. AWS's load-testing guidance treats scale testing as a workload-level exercise with planned traffic and performance measures.
9. Test authorization with realistic test identities
When access control affects the user journey, run the workflow with a non-production identity that follows the same authentication path as the application. Check both expected access and expected denial—for example, that an authenticated user can read their own test record and cannot read another test user's record. Verify the deployed role and resource policies that the workflow depends on.
Give the test runner and application roles only the permissions their jobs require. Use temporary credentials or the CI platform's role integration where available, and keep production credentials and real customer data out of test jobs. These E2E assertions help confirm authorization behavior; they do not replace broader security testing such as policy review, dependency scanning, or penetration testing. See the AWS IAM security best practices.
10. Make runs observable and clean up resources
Give each run a correlation ID and include it in test records and application logs where possible. On failure, retain the test name, request or event identifier, test stack name, response, and relevant logs. Amazon CloudWatch provides logs and metrics for AWS resources and applications; CloudWatch and X-Ray tracing can help follow a request across services when the application is instrumented.
Delete resources created solely for a test after the run, including on failure. If you provision with CloudFormation, delete the test stack and confirm cleanup completed. Review deletion policies and separately managed resources: CloudFormation can retain resources configured to survive stack deletion, and resources accrue charges while they exist. Keep a cleanup process for abandoned stacks as a fallback for interrupted CI jobs.
Review recurring failures and flaky tests. Fix the underlying timing, data-isolation, or environment problem, and distinguish a retry from a clean first-pass success in CI results. The goal is to keep the suite small enough to run consistently and clear enough that a failure points to a behavior someone can investigate.
Conclusion
A dependable AWS E2E suite checks a few important user journeys against an isolated deployed environment, with unique data, realistic permissions, and observable outcomes. Use unit and integration tests for faster, narrower feedback; use mocks and SAM local for local development; use cloud E2E tests to verify the services and configuration that only exist in AWS.
FAQs
What is end-to-end testing in AWS?
It verifies an application behavior across the full deployed workflow, from an external entry point through the AWS components involved to the expected response or persisted result. The exact path depends on the application; a serverless order API and an asynchronous image-processing workflow need different checks.
Does local SAM testing replace cloud end-to-end testing?
No. SAM local helps test function and API behavior during development. It does not by itself verify deployed service wiring, IAM permissions, or cloud configuration. Use a deployed test environment when those behaviors are part of the claim.
How many end-to-end tests should an AWS app have?
There is no fixed number or ratio. Cover the critical user journeys and high-risk cross-service behavior, then use unit and integration tests for the broader set of logic and edge cases. This keeps end-to-end feedback focused and easier to diagnose.