<p>I was reading something that made me question if I'm implementing testing in my pipeline correctly.</p>
<p>I currently have it setup like the following:</p>
<ul>
<li>Local feature branch for a microservice pushed to remote</li>
<li>PR request to merge feature request into <code>testing</code> branch for microservice</li>
<li>Accepted and merged</li>
<li>Triggers CI/CD pipeline:
<ul>
<li>First, a Linux VM is created</li>
<li>The microservice is deployed to the VM</li>
<li>The tests are run for the microservice</li>
<li>If all testing passes, it builds the Docker image and pushes it to the container registry</li>
<li>The deployment stage then pulls the image and deploys to the Kubernetes cluster</li>
</ul>
</li>
</ul>
<p>My questions are the following:</p>
<ul>
<li>The dev should be testing locally, but should testing automatically happen when the PR is submitted?</li>
<li>Should I be building the Docker image first, creating a running container of the image and testing that (that is after all what is getting deployed)?</li>
</ul>
<p>In other words, is the flow:</p>
<ol>
<li>Build app -&gt; test -&gt; if passes, build image -&gt; deploy</li>
<li>Build image -&gt; test -&gt; if passes, deploy</li>
<li>Build app -&gt; run certain tests -&gt; if passes, build image -&gt; run more tests -&gt; deploy</li>
</ol>
<p>Thanks for clarifying.</p>

<p>There are a couple of things I'd rearrange here.</p>
<p>As @DanielMann notes in a comment, your service should have a substantial set of unit tests.  These don't require running in a container and don't have dependencies on any external resources; you might be able to use mock implementations of service clients, or alternate implementations like SQLite as an in-process database.  Once your CI system sees a commit, before it builds an image, it should run these unit tests.</p>
<p>You should then run as much of the test sequence as you can against the pull request.  (If the integration tests fail <em>after</em> you've merged to the main branch, your build is broken, and that can be problematic if you need an emergency fix.)  Especially you can build a Docker image from the PR branch.  Depending on how your system is set up you may be able to test that directly; either with an alternate plain-Docker environment, or in a dedicated Kubernetes namespace, or using a local Kubernetes environment like minikube or kind.</p>
<p>Absolutely test the same Docker image you will be running in production.</p>
<p>In summary, I'd rearrange your workflow as:</p>
<ol>
<li>Local feature branch for a microservice pushed to remote</li>
<li>PR request to merge feature request into <code>testing</code> branch for microservice
<ol>
<li>Triggers CI pipeline:</li>
<li>Run unit tests (without Docker)</li>
<li>Builds a Docker image (and optionally pushes to a registry)</li>
<li>Deploy to some test setup and run integration tests (with Docker)</li>
</ol>
</li>
<li>Accepted and merged
<ol>
<li>Triggers CI/CD pipeline:</li>
<li>Runs unit tests (without Docker)</li>
<li>Builds a Docker image and pushes it</li>
<li>Deploy to the production Kubernetes environment</li>
</ol>
</li>
</ol>
