From a high-level view, you typically have separate steps in CodePipeline for test and deployment on each environment. A common flow would look like this:
- Code is checked in
- Pipeline is triggered
- Code is built and tested (e.g. unit tests)
- Artifacts are deployed to testing environment
- Application is tested (e.g. integration tests, smoke tests, etc)
- Artifacts are deployed to prod environment
- Application is tested
Ideally stages are also separated through different AWS accounts, like one account for dev (potentially including the Pipeline itself), one for testing, and one for prod. See the image below and related blog post for illustration and more information.

While that works well for the common trunk-based development model, it sounds as if you may want to run the Pipeline on separate branches instead.
For that, you can implement a mechanism that will create a new Pipeline using a CloudFormation template, whenever a new branch is created. The high-level idea is shown in the diagram below. This blog post provides the full details on how to implement the approach.
