Introduction to Testing in Go (Golang)
Writing unit tests and integration tests is one of the most-neglected aspects of software development. All too often, a developer will find him or herself say "but it works on my computer!" when a project is presumed finished, only to discover that once taken out of the development environment, things don't work as expected. Well written unit tests and integration tests help to solve this problem, and in fact almost without exception will reduce overall development time, rather than adding to it.
More
In addition, well-tested code almost always requires less maintenance, and the end product will have less down time.
This course is focused on writing unit and integration tests in Go, a modern, type safe, compiled, and extremely fast programming language. It it is ideally suited for building safe, scalable, incredibly fast web applications, and it has powerful testing tools built right in.
In this course, we will build four simple applications, and thoroughly test them:
A command line application (CLI) that tries to determine if a user-entered number is prime or not;
A simple web application that allows a user to log in and upload a profile picture;
A simple REST API built on the same code base as the web application which allows users to authenticate using JWT tokens and perform operations against a Postgres database. We'll go through the entire authentication process, including using refresh tokens, and thoroughly test all aspects of the code.
A simple Single Page Web Application (SPA), written in Vanilla JavaScript, that demonstrates how to use JWT and Refresh Tokens with a SPA, and how to test that functionality.
For each of these projects, we will learn how to write unit tests for all functionality. We will learn how to test (among other things):
Application routes
Application handlers
How to test multiple scenarios by writing and using table tests
Database operations (using the Repository pattern)
Application middleware
User authentication (with sessions)
User authentication (with JWT tokens)
JWT token generation and validation
Refresh token generation and validation
Testing user input
Writing to the terminal
Adding cookies to a request
Reading cookies from a response
By the end of this course, you will have a solid understanding of how to write effective tests, and how to write testable code.
Watch Online Introduction to Testing in Go (Golang)
# | Title | Duration |
---|---|---|
1 | Introduction | 05:34 |
2 | About me | 01:02 |
3 | Asking for help | 01:15 |
4 | Mistakes: we all make them. | 01:07 |
5 | What we'll cover in this section | 00:30 |
6 | Installing Go | 01:28 |
7 | Installing an IDE | 01:30 |
8 | Installing Docker | 00:52 |
9 | What we'll cover in this section | 01:04 |
10 | Creating a simple command line application | 06:21 |
11 | Writing a test for the isPrime() function | 07:58 |
12 | Improving our test with table tests | 07:21 |
13 | Checking test coverage | 02:30 |
14 | Completing our table tests | 02:49 |
15 | Improving our program to allow for user entered information | 11:26 |
16 | Writing a test for the prompt() function | 07:10 |
17 | Writing a test for the intro() function | 02:30 |
18 | Testing user input - writing a test for the checkNumbers() function | 13:36 |
19 | Updating readUserInput to make it testable, and then testing it | 05:58 |
20 | What we'll cover in this section | 00:45 |
21 | Running a single test | 01:38 |
22 | Running groups of tests (test suites) | 02:00 |
23 | What we'll cover in this section | 00:43 |
24 | Creating a simple web app | 10:16 |
25 | Setting up a route and handler for the home page | 12:00 |
26 | Testing our application routes | 11:29 |
27 | Testing Handlers: the Home handler | 10:01 |
28 | Setting up some simple middleware | 12:23 |
29 | Trying out our new addIPToContext middleware | 02:46 |
30 | Testing our middleware | 12:12 |
31 | Testing ipFromContext | 04:30 |
32 | Creating a login form | 02:57 |
33 | Setting up a route and stub handler for the login form | 04:44 |
34 | What we'll cover in this section | 00:35 |
35 | Setting up validation logic | 09:33 |
36 | Testing validation logic | 08:25 |
37 | Completing the tests for our validation logic | 05:19 |
38 | Trying out validation with our login form | 03:27 |
39 | What we'll cover in this section | 00:56 |
40 | Setting up a test enviroment with testing.M | 04:29 |
41 | Simplifying our templates using a layout | 04:26 |
42 | Installing a sessions package | 02:02 |
43 | Adding session to App config, and creating a SessionManager | 04:11 |
44 | Trying out our sessions | 07:39 |
45 | Updating our tests | 11:48 |
46 | Improving our test for the Home handler | 06:19 |
47 | Testing the render function with a bad template | 07:37 |
48 | What we'll cover in this section | 01:14 |
49 | Installing postgres with Docker | 06:06 |
50 | Setting up a database connection | 10:27 |
51 | Adding the data package for models and db package for database access | 04:03 |
52 | Making sure our web app can connect to our database | 03:35 |
53 | Closing our database pool gracefully, and resetting template path in tests | 01:58 |
54 | Creating a stub profile page | 08:29 |
55 | Adding messages to our template data and template files | 06:54 |
56 | Adding true authenication to the Login handler | 05:33 |
57 | Testing the Login handler | 19:18 |
58 | Adding Auth middleware | 04:25 |
59 | Testing Auth middleware | 06:54 |
60 | Updating routes & end-to-end tests | 09:29 |
61 | Problems with our Login handler test | 01:57 |
62 | What we'll cover in this section | 02:13 |
63 | Defining an interface type for our repository | 03:28 |
64 | Moving our database functions into a repository | 05:02 |
65 | Updating application config to use the database repository | 02:21 |
66 | Creating a testdb repository | 05:50 |
67 | Updating setup_test.go to use the test repository | 01:59 |
68 | Updating our tests to use the testdb repository | 04:33 |
69 | What we'll cover in this section | 01:23 |
70 | Getting started with testing our database | 08:06 |
71 | Getting our tests to spin up a docker image with Postgres | 11:04 |
72 | Populating our test database with empty tables | 08:55 |
73 | Testing InsertUser | 06:22 |
74 | Testing AllUsers | 04:10 |
75 | Testing GetUser and GetUserByEmail | 05:12 |
76 | Testing UpdateUser | 04:22 |
77 | Testing DeleteUser | 02:34 |
78 | Testing ResetUserPassword | 04:14 |
79 | Testing InsertUserImage | 06:36 |
80 | Using build tags to separate our integration tests | 02:56 |
81 | What we'll cover in this section | 00:57 |
82 | Adding a form to the Profile page | 05:44 |
83 | Adding the UserImage type to the User type | 05:42 |
84 | Updating the profile.page.gohtml file to look for a profile image | 06:53 |
85 | Writing a stub handler and a function to process profile image uploads | 14:29 |
86 | Implementing the UploadProfilePic handler | 04:51 |
87 | Trying things out | 04:29 |
88 | Testing image uploads | 15:22 |
89 | Testing our upload handler, with an alternative approach | 09:52 |
90 | What we'll cover in this section | 01:30 |
91 | Setting up an api with our existing code base | 09:55 |
92 | Adding stub handlers (endpoints) for our API | 05:49 |
93 | Trying out our REST API to make sure things work | 05:23 |
94 | Getting started with JWT Authentication | 19:04 |
95 | Generating token pairs | 10:39 |
96 | Implementing the authenticate handler | 04:50 |
97 | Trying out the authentication handler | 04:53 |
98 | Testing our authentication handler | 10:51 |
99 | Setting up a simple program to generate tokens for testing | 02:39 |
100 | Testing generating and validating tokens | 15:38 |
101 | Setting up our application middleware | 06:40 |
102 | Testing our CORS middleware | 07:04 |
103 | Testing our authRequired middleware | 08:18 |
104 | Add middleware to routes | 02:16 |
105 | Testing API routes | 03:56 |
106 | Implementing the handler to refresh tokens | 09:41 |
107 | Testing refreshing tokens | 13:13 |
108 | Completing the handlers that interact with the User type | 07:22 |
109 | Testing the handlers that interact with the User type | 11:56 |
110 | Finishing up testing handlers that interact with the data.User type | 08:55 |
111 | What we'll cover in this section | 01:21 |
112 | Serving HTML for our SPA | 05:18 |
113 | Authenticating users with our SPA | 16:16 |
114 | Setting a refresh token cookie when authenticating | 08:40 |
115 | Allowing users to refresh tokens using a cookie | 06:24 |
116 | Automatically refreshing tokens while the user is logged in | 05:54 |
117 | Getting a user from our simple SPA with the "Get User" button | 04:37 |
118 | Logging web users out | 06:01 |
119 | Testing refreshing tokens for Single Page Apps | 08:59 |
120 | Testing logging users out of our SPA | 06:33 |