I try to understand how testing fits into continuous integration and continuous delivery practices.
This article about CI states that automated tools are used to assert the new code’s correctness before integration.
Before new code is merged it must pass the CI test assertion suite which will prevent any new regressions.
But how can we build and test a new version of software without integrating all changes?
On the other hand, this page says that CI is a process that occurs prior to a build in which code is tested. And there is also a picture showing tests after version control. So, it looks like changes are first integrated in the version control, then software is built and tested.
Are tests in CI performed before or after integration of changes? And what happens if these tests fail? Will changes be rolled back then?
Another thing I find unclear is that testing is a part of both CI and CD phases. How does testing in CI differ from testing in CD?
CI is essentially a process to build each software component. Testing in CI = unit tests + any tests related to specific component being built in isolation from other components. In example, in your CI step you can run compiled jar against mock db and run some tests on that.
CI tests are performed after integration of changes but only on a single component being built. Usual flow - you do a Git commit, that triggers CI, tests would cover the code including that Git commit.
If CI tests fail, you should get notified and the build should not be promoted to CD step. In other words, the CICD pipeline aborts. Changes won't be rollbacked though - instead developers would need to decide what to do.
Testing in CD = integration testing, where software stack is deployed to some non-prod environment and being tested there. Such tests can be automated or manual. Note, that here you can implement auto-rollback to previous version of the stack.
I.e. see sample here of how we do automated CD testing - https://worklifenotes.com/2021/02/03/automated-tests-ci-cd-workflow-with-reliza-hub/