design/one-pager-e2e-tests.md
Crossplane relies heavily on unit tests to ensure quality, but these alone are not enough to ensure Crossplane functions correctly as a whole.
Thus far we have relied on an honor system of folks running manual black-box tests to increase the likelihood that their changes work in real-world conditions. These tests:
kind on the author's laptop.Over the years this has lead to several (probably many) issues in released versions of Crossplane that would likely have been caught by E2E tests. Some examples include:
We've made several attempts to add integration and E2E tests to Crossplane in the past, but none have flourished. Typically we've aligned on a pattern, implemented the first test or two, then never touched them again. I believe this is largely because we've relied on CNCF interns to kick-off the testing effort. The testing frameworks we've put into place are actually promising - it's just hard to ensure contributors keep using them once your internship ends.
Examples include:
integration_tests.sh is our most long-lived attempt at black-box testing. It
runs as part of every continuous integration (CI) job (i.e. on every PR) and
simply ensures Crossplane starts without crashing.
crossplane/test does run on a regular schedule, using a mix of tests defined
under test/e2e in c/c, and tests defined in its own repository. It covers:
Because it's run in a separate repository and isn't connected to PRs or releases it's unclear whether anyone notices if/when tests break. It's also easy to forget to update the tests when adding new functionality.
The goal of this proposal is to:
In this context we consider "Crossplane" to include only the functionality defined in the crossplane/crossplane repo, e.g. the package manager, composition engine, etc. Testing that any specific extension such as a provider or function works as expected is out of scope.
Our "black box" is the artifacts produced from this repository - the Crossplane
containers and Helm chart. Testing their integration with the Kubernetes API
server is unavoidable, but it is not our goal to test that the API server
itself, or any particular client thereof, functions correctly. (Consider that
clients like kubectl don't interact directly with Crossplane, they simply
write state to the API server that Crossplane reads).
To achieve our goals, I propose:
It will eventually become expensive and slow to run all E2E tests on every PR, but we can face that problem when we come to it. We could add a GitHub action to trigger specific tests on-command, or run them periodically (e.g. nightly).
I propose the PR template be updated as follows:
### Description of your changes
<!--
Briefly describe what this pull request does, and how it is covered by tests.
Be proactive - direct your reviewers' attention to anything that needs special
consideration.
You MUST either [x] check or ~strikethrough~ every item in the checklist below.
We love pull requests that fix an open issue. If yours does, use the below line
to indicate which issue it fixes, for example "Fixes #500".
-->
Fixes #
I have:
- [ ] Read and followed Crossplane's [contribution process].
- [ ] Added or updated unit **and** E2E tests for my change.
- [ ] Run `make reviewable` to ensure this PR is ready for review.
- [ ] Added `backport release-x.y` labels to auto-backport this PR if necessary.
[contribution process]: https://git.io/fj2m9
Note that:
Contemporary E2E tests are either shell scripts or Go-heavy tests written using
the stdlib testing library and client-go. I propose that in order to make it
more likely for contributors to add or update E2E tests we attempt to reduce the
burden of doing so by:
The overall goal being that eventually most tests will involve only adding or updating YAML manifests, with a little Go plumbing to use existing functions to check that Crossplane works correctly when they are applied.
To this end I propose that we:
features.Func implementations) in a
separate package from the test step definitions.I believe e2e-framework is the best choice for us because it:
testing package.https://github.com/crossplane/crossplane/pull/4101 explored several other potential E2E testing frameworks, including Godog (i.e. Cucumber), Terratest, and kuttl. See that proposal for details.