Package: pytest-kubernetes
pytest-kubernetespytest-kubernetes is a lightweight pytest plugin that makes managing (local) Kubernetes clusters a breeze. You can easily spin up a Kubernetes cluster with onepytest fixureand remove them again.
The fixture comes with some simple functions to interact with the cluster, for examplekubectl(...)that allows you to run typicalkubectlcommands against this cluster without worring
about thekubeconfigon the test machine.Features:Set up and tear down (local) Kubernetes clusters withminikube,k3dandkindConfigure the cluster to recreate for each test case (default), or keep it across multiple test casesAutomatic management of thekubeconfigSimple functions to run kubectl commands (withdictoutput), reading logs and load custom container imagesWait for certain conditions in the clusterPort forward Kubernetes-based services (using kubectl port-forward) easily during a test caseManagement utils for custom pytest-fixtures (for example pre-provisioned clusters)InstallationThis plugin can be installed from PyPI:pip install pytest-kubernetespoetry add -D pytest-kubernetesNote that this package provides entrypoint hooks to be automatically loaded with pytest.Requirementspytest-kubernetes expects the following components to be available on the test machine:kubectlminikube(optional for minikube-based clusters)k3d(optional for k3d-based clusters)kind(optional for kind-based clusters)Docker(optional for Docker-based Kubernetes clusters)Please make sure they are installed to run pytest-kubernetes properly.ReferenceFixturek8sThek8sfixture provides access to an automatically selected Kubernetes provider (depending on the availability on the host). The priority is: k3d, kind, minikube-docker and minikube-kvm2.The fixture passes a manager object of typeAClusterManager.It provides the following interface:kubectl(...): Execute kubectl command against this cluster (defaults todictas returning format)apply(...): Apply resources to this cluster, either from YAML file, or Python dictload_image(...): Load a container image into this clusterwait(...): Wait for a target and a conditionport_forwarding(...): Port forward a targetlogs(...): Get the logs of a podversion(): Get the Kubernetes version of this clustercreate(...): Create this cluster (pass special cluster arguments withoptions: List[str]to the CLI command)delete(): Delete this clusterreset(): Delete this cluster (if it exists) and create it againThe interface provides proper typing and should be easy to work with.Exampledeftest_a_feature_with_k3d(k8s:AClusterManager):k8s.create()k8s.apply({"apiVersion":"v1","kind":"ConfigMap","data":{"key":"value"},"metadata":{"name":"myconfigmap"},},)k8s.apply("./dependencies.yaml")k8s.load_image("my-container-image:latest")k8s.kubectl(["run","test","--image","my-container-image:latest","--restart=Never","--image-pull-policy=Never",])This cluster will be deleted once the test case is over.Please note that you need to set"--image-pull-policy=Never"for images that you loaded into the cluster via thek8s.load(name: str)function (see example above).Markspytest-kubernetes usespytest marksfor specifying the cluster configuration for a test caseCurrently the following settings are supported:provider(str): request a specific Kubernetes provider for the test casecluster_name(str): request a specific cluster namekeep(bool): keep the cluster across multiple test casesExample@pytest.mark.k8s(provider="minikube",cluster_name="test1",keep=True)deftest_a_feature_in_minikube(k8s:AClusterManager):...UtilsTo write custom Kubernetes-based fixtures in your project you can make use of the following util functions.select_provider_managerThis function returns a deriving class ofAClusterManagerthat is not created and wrapped in a fixture yet.select_provider_manager(name: Optional[str] = None) -> Type[AClusterManager]The returning object gets called with the init parameters ofAClusterManager, thecluster_name: str.Example@pytest.fixture(scope="session")defk8s_with_workload(request):cluster=select_provider_manager("k3d")("my-cluster")# if minikube should be used# cluster = select_provider_manager("minikube")("my-cluster")cluster.create()# init the cluster with a workloadcluster.apply("./fixtures/hello.yaml")cluster.wait("deployments/hello-nginxdemo","condition=Available=True")yieldclustercluster.delete()In this example, the cluster remains active for the entire session and is only deleted once pytest is done.Note thatyieldnotation that is prefered by pytest to express clean up tasks for this fixture.Special cluster optionsYou can pass more options usingkwargs['options']: List[str]to thecreate(options=...)function when creating the cluster like so:cluster=select_provider_manager("k3d")("my-cluster")# bind ports of this k3d clustercluster.create(options=["--agents","1","-p","8080:80@agent:0","-p","31820:31820/UDP@agent:0"])ExamplesPlease find more examples intests/vendor.pyin this repository. These test cases are written as users of pytest-kubernetes would write test cases in their projects.