Building and Testing Applications on GCP
Google Cloud Platform (GCP) is a powerful platform that brings the flexibility and reliability of Google’s infrastructure to your projects. As a leader in AI, machine learning, and networking, GCP has a suite of tools and services for developers to use for almost any circumstance. Before using them, it’s good to learn the ins and outs of GCP and the most effective patterns for software development. The Professional Cloud Developer exam, as well as the industry at large, has been transformed by Continuous Integration (CI) and Continuous Deployment (CD), which enable developers to deliver code safely and securely into production once properly setup. This course will cover the Google best practices for setting up a CI/CD pipeline on GCP.
For support, queries or feedback relating to this course, please contact us at firstname.lastname@example.org.
- Learn GCP core developer services
- Create a CI/CD pipeline with Google Cloud Build
- Test and deploy a containerized application
Developers who are studying for the Google Cloud Professional Cloud Developer Certification exam.
Unit testing is important in any development environment, especially when it comes to the cloud. If you're not running unit tests in your CI/CD pipeline, it's more likely that you might miss a defect that makes it to production. This is especially important for GCP Cloud Functions, where code is not compiled, just uploaded and run. There are three different types of tests you should be aware of:
- Unit tests, which are small tests that should run to test specific parts of your code. These can test edge cases and input validation. These do not test integration with external dependencies or components, instead having those mocked out for use during the test. They should run within a matter of milliseconds.
- Integration tests. These tests check the interaction between different parts of your code to make sure that the assumptions made while writing one class about resources in another are still valid. For example, lets say you had a cloud function that took data from Cloud Pub/Sub and wrote that data to Firestore. An integration test in this case would check if that function was using both services appropriately.
- System tests. This is where the application is deployed into a test environment and run. Once the environment is provisioned and code deployed, the functionality of the code can be validated.
Cloud build can incorporate unit tests and integration tests as part of the build step running on a separate builder, but to run system tests, you'll need to add a separate deployment into your configuration file.
Here are some best practices for testing:
- Unit test names should be descriptive. When reviewing the build output, finding out that the UnitTest010 test failed is not going to be as helpful as finding out the CannotDivideByZero test failed.
- Mocks in unit testings can also be set to fail, for example, a mock REST call that returns a 403 error. In cases like that, it's useful to know and test for what kind of exceptions your code will throw.
- Know the difference between unit tests and integration tests, especially if you're gonna take a certification exam.
- Use infrastructure as code to deploy environments for system tests. Using something like Terraform or Deployment Manager keeps costs low and makes sure there is as little configuration drift as possible.
- Integration tests don't just have to be for outside services, they can be from outside classes as well.
Now that we've gone over some of the basics of unit testing, let's look at how to run them as a part of Cloud Build. In this demo, we're going to go over how to run unit tests in Cloud Build, and coincidentally we're also going to cover how to start making custom builders and to add build triggers onto our commits, so that every time we commit code to a cloud source repository, we can then start running tests against it.
So that sounds like a lot to cover in one demo but it all makes sense. Let's start off here with cloudbuild.yaml which is, as we covered earlier, our build configuration file. And because all of our builders are docker containers, what I didn't mention earlier is that there's no Google-provided cloud builder for Python, so what I'm doing here is I'm running a Python 3.7 docker container in my cloud build script and then I'm passing it the code for my code source repository and some arguments to run, in this case it's going to install Flask and run test_app.py.
So now that we see this example of a custom builder, let's go ahead and set up a trigger, so that when we push to this repository it will build this code for us. Okay, I'm over here in Cloud Build and we see I have a few repositories. The first thing I want to do is create a trigger, and it'll ask me to select which repository I want to create this trigger for, I'm going to go ahead and pick this hello-cloudbuild-app and I'll give it a name, and here we can set some rules on this, I want it to run every time it gets pushed to master in this case. So, I have the option here to put some regex in for other branches, but that's fine for what we have now. Let's hide these filters here, and next it's going to ask do I want to specify a Docker file or a cloud build configuration to run this trigger? Well, I'm gonna go ahead and select cloudbuild.yaml, which is in the root of my source code repository, and let's go ahead and create that trigger, and we have the ability to run it from here, as well as manage it, but I want to push a new change up to that repository to show you that it works from there as well. Let's go over to Visual Studio Code.
Okay, I'm here in my cloud source repository, in Visual Studio Code, and what I'm gonna do, just for a demo in this case, is I've got my test_app.py here, I'm gonna go ahead and just add a new comment to make sure that we can push a change up to the repository, and let's go ahead and commit this change. All right, that's been pushed to our cloud source repository, let's go back to the GCP console.
All right, I'm back here in Cloud Build, and the first thing I want to do is actually go to history and this will show that we did have a build just now, let's go ahead and go into that build a little bit, you see it's run our Python test step here, and we have a log of what exactly it's done, if we go back up to the top, we can see the Git commit that triggered this as well and that it was triggered on a push to the master branch. So let's open that git commit, and we see it was a change to test_app.py and there we have it, that's it for this demo, thanks for watching.
Chris Blackden started his first IT job at the age of fifteen and has been doing it ever since. He’s held roles from Hardware Technician to Senior Software Engineer, and is currently working as a DevOps Engineer in a healthcare research organization. Some of his passions outside of work include cooking and eating spicy food, and old-school kung fu movies.