meta_desc: "Infrastructure testing is core to cloud engineering; this article examines unit, property, and integration testing using infrastructure as code."
In the [previous article](/blog/infrastructure-testing-concepts/) we discussed how to apply software testing methodologies to cloud engineering. We also examined testing regimes starting from the testing pyramid to the trophy and honeycomb models of testing better suited to distributed and cloud architectures. These testing regimes include three types of tests suited for cloud architectures:
Cloud engineering testing differs from application testing because multiple dependencies between components can have high latency. Let's examine these dependencies using an [example application](https://github.com/pulumi/examples/tree/master/aws-ts-stackreference-architecture) composed of an application layer, a database layer, and a network layer. We can visualize these dependencies with Pulumi's resource graph.The graph is constructed from the [inputs](/docs/concepts/inputs-outputs/) needed to create a resource.
The resource graph for the application layer shows many dependencies. The application deploys containers in AWS Fargate, which are instantiated with an application service that requires a service definition with many inputs.

Unit tests are ideal for validating inputs and ensuring that cloud resources are created. Let's look at a simple example with just two resources, an EC2 instance running a web server and a SecurityGroup policy.

We can use [mocks](https://devopedia.org/mock-testing) to test if the webserver has a name tag. First, we'll create the mocks and import the infrastructure that uses the mocks.
The test has two assertions: one for tags on the server urn and another if the instance has a `Name` tag. When we call the test, we pass the server urn and tags. Note that we did not instantiate an EC2 instance and used a mock. This is why it can run unit tests frequently with quick results.
## Property tests
In addition to unit tests, we want to test the properties of a cloud resource. For example, we want to restrict access to a resource by creating a policy that limits ingress. For this use case, we need a property test to ensure the exact values required by a policy. The resource graph from our simple example shows that a `SecurityGroupRule sets ingress to the web server`. We can test if port 22 is open, which would enable logging into the server via ssh.
Because `web-secgrp` has port 22 open to all IP addresses, we can expect it to fail this test. You can find the complete example for the unit and property tests on [Pulumi's example Github repository](https://github.com/pulumi/examples/tree/master/testing-unit-py).
Integration testing requires deploying resources in either a test environment or an ephemeral environment. In this [integration testing example](https://github.com/pulumi/examples/tree/master/testing-integration-py), we'll deploy a single resource using Pulumi's [Automation API](/docs/using-pulumi/automation-api/). Spinning up [ephemeral environments](/docs/using-pulumi/testing/integration#ephemeral-environments) for integration testing is an excellent use for the Automation API, which provides a programmatic interface for building infrastructure without a CLI or web-based console.
The following code sets up the Pulumi [stack](/docs/concepts/) and S3 bucket with Automation API. It's interesting to note that the tests don't import the Pulumi AWS SDK and uses a combination of Python's built-in `unittest` framework and Amazon's [`boto3`](https://aws.amazon.com/sdk-for-python/) Python library. This illustrates the extensibility and flexibility of infrastructure as code by letting developers choose the tools and SDKs.
The `TestS3` class has a second `@classmethod` decorator for the tests; for example, the following code uploads a file and checks to see if the file is stored in the bucket.
When we run the test, it creates the stack and resource, runs the tests, and tears down the infrastructure. This process can be part of a CI/CD pipeline to run an automated integration test as part of the build process. The complete example for integration testing is available on [Github](https://github.com/pulumi/examples/tree/master/testing-integration-py).
Although distributed infrastructure presents some unique challenges because of its asynchronous nature, we can perform efficient and automated testing. Whether it is unit and property testing that uses mocks and stubs or integration testing that requires deployed resources, infrastructure as code lets you use familiar testing frameworks and SDKs. Moreover, Pulumi's Automation API makes it simple to create stacks and spin up ephemeral infrastructure for integration testing. Learn more about [infrastructure testing](/what-is/how-to-step-up-cloud-infrastructure-testing/) with [Pulumi's Testing User Guide](/docs/using-pulumi/testing/) and get hands-on with our [testing examples](https://github.com/pulumi/examples/#testing).