
Learn to write testable Go code with testing tools, covering unit and integration tests across four projects, including a prime CLI, a secure web app, and a JWT-auth REST API.
Meet a veteran software professional and educator with 25 years in the industry, teaching since 1991, and a PhD in English literature, computer science, and education.
Look online for go testing solutions, compare your code to the lecture's source when needed, and use the Q&A section with a code sample or git repository link for help.
Explore how mistakes fuel learning in software development as the instructor openly identifies and fixes errors in real time, illustrating the ongoing nature of debugging in an intermediate course.
Set up your Go development environment by installing the latest Go version, explore Visual Studio Code, and install Docker to run a Postgres database, using any editor you prefer.
Install go by visiting go.dev, choosing the correct OS package, and following the platform-specific installation steps. Verify the setup by running go version in the terminal.
Install and configure an integrated development environment to simplify Go development. Download Visual Studio Code, install the official Go extension, and enable Go template syntax highlighting.
Install docker to run all microservices locally and support future service discovery, with free, easy installation from course resources for Mac, Windows, or Linux.
Learn to write unit tests in Go with a simple command line program that checks if a number is prime, and explore test coverage and user input testing.
Create a command line Go application that determines if a number is prime. Implement an isPrime function with a for loop and modulus checks, handle edge cases, and print results.
Write your first go test beside main file. Name it main_test.go, use a test function with t *testing.T to verify isPrime for zero and prime numbers, then run go test.
Improve our test with table-driven go tests by creating a prime test table, iterating over cases, and validating both results and messages, then explore coverage with go test.
Learn to measure Go code coverage by running go test -cover, generating a coverage profile, and viewing the html report to refine table tests for the is prime function.
Update table tests for the is prime function by adding cases for zero, one, and negative numbers, verify with go test and 100% coverage, and plan user input testing.
Enhance a Go program to accept user input, test numbers for primality, and coordinate a background goroutine with a quit channel.
Demonstrates testing the go prompt function by redirecting and capturing stdout with a pipe, validating the output, and increasing test coverage using go test -cover.
Learn to test the Go intro function by capturing stdout, verifying a substring with strings.Contains, and expanding to table tests for input like entering a number.
Learn to test the Go check numbers function by simulating input with a prefilled reader and a table-driven approach, covering empty input, primes, non-primes, negative numbers, and quit.
Refactor readUserInput to accept an io.Reader instead of using os.Stdin, enabling testable input via a bytes.Buffer. Test the goroutine-driven read path for 100% coverage of readUserInput.
Learn the syntax for running an individual test and for running groups of tests, or a test suite, in Go.
Learn to run a single test in Go by using go test -run <test_name> with -v for verbose output, instead of executing the entire test suite.
Learn how to group tests into suites in Go by naming tests with a common prefix, use go test -run to execute specific groups, and enable verbose output for clarity.
Learn to start testing web applications in Go by building a simple web app, a server, a handler with a route, and testing a context-adding middleware.
Create a Go web app to test handlers, routes, and a database by scaffolding an app with chi router and recover middleware, then start a server for route testing.
Create a home page route and handler in Go, render a Go template from disk, and serve the page via http on port 8080.
Learn to test Go web routes by validating registered paths with a table-driven approach, and fix template imports while wiring static assets with a file server and strip prefix.
Write unit tests for the home handler using a built-in http test server to verify expected status codes for the root and a not-found route.
Develop a Go middleware that recovers from panics, computes a more accurate client IP (considering x-forwarded headers), and stores it in the request context for handlers.
Learn how to wire a Go middleware that adds the visitor IP to the context, retrieve it in handlers via IP from context, and display it on the home page.
Write and test a Go middleware that adds IP information to the request context. Use a unit test with multiple scenarios, a dummy handler, and verify context values and coverage.
Write a focused unit test for the ipFromContext function in middleware using a background context and a context user key. Verify the function returns the expected IP from context.
Create a simple login form on the homepage using bootstrap, with email and password inputs and an action route for /login, and plan a stub handler with validation for tests.
Create a post route for /login and a stub Go handler that parses form data, retrieves email and password, and prints them for verification, laying groundwork for validation and tests.
Implement simple validation logic in a Go web app and test it, highlighting that validation is critical for any application. We'll cover a few validators and verify them through tests.
Learn to build practical form validation in Go by defining a custom errors type for fields, validating required fields, and using a simple check and valid method on URL values.
Learn to test Go form validation by writing unit tests for forms.go, checking has fields, required fields, and form validity using URL values and posted data.
Finish testing the validation logic in Go by validating the check and get functions, using a form with a password field, and achieving full test coverage.
Learn to add validation to a Go login form, enforce required email and password fields, test validation with updated routes and tests, and prepare for session handling.
Explore adding session support to a server-rendered Go web app and learn to write code and tests using sessions to persist information between requests, with tests mirroring the app.
Learn to bootstrap a Go test environment with testing.M and a test main, enabling pre-test setup and consistent application state across handlers, middleware, and roots tests.
Define a base layout in the templates folder and a content block in Go HTML templates, pass data with dot, render multiple templates, then run Go test.
Install a sessions package to persist data across requests on a stateless web server, using a cookie store to maintain login state; use version two for compatibility.
create a sessions.go file in the main package, implement get session to return a new CES session manager with a 24 hour lifetime, cookie persistence, sameSite, secure, and load-and-save middleware.
Implement and test session support in the Go web app by storing a value in the session, rendering it on the home page, and preparing tests for sessions.
Update tests by configuring session data in the test environment and attaching session context through helper functions. Verify the home page output via http handlers.
Improve testing of the home handler by converting to a table-driven test using sessions, validating render output, and examining test coverage for Go handlers.
Test the render function with a deliberately bad template in Go by configuring a test data templates path and creating a faulty page template; expect an error and validate behavior.
Learn to test post requests for a login form by building authentication, connecting a Go web app to a Postgres database via Docker, and implementing authentication middleware and tests.
Install Postgres with Docker to support testing the login post handler, set up Docker Compose for Postgres 14.5, and use Beekeeper Studio to inspect the users table.
Learn how to set up a Postgres database connection in Go using the pgx driver with the standard library database/sql, including DSN configuration, open db, and ping verification.
Learn to define models and the db access layer in Go, implementing CRUD operations for users and images, with bcrypt password checks and database queries via a Postgres connection.
Demonstrates connecting the web app to the database by using a db wrapper, querying users by email, and validating the setup via Docker and login.
Close database connections gracefully by deferring the SQL DB close in main to prevent pool exhaustion. Reset the template path after tests to its original value to avoid issues.
learn to implement a login handler in go: validate form data, manage sessions, flash errors, prevent session fixation, and redirect to a stub user profile page.
Pull error and flash messages from the session into template data and render them as bootstrap alerts in the base layout.
Add an authenticate function in the login handler to verify password hash against the data user password, store the user in the session, and redirect on error with gob registration.
Learn to test the Go login handler with table tests, validating form data, simulating database lookups, and verifying redirects to /user/profile on successful login.
Add an authentication middleware to protect the /user/profile route in the Go application by checking the session for a user and redirecting unauthenticated requests to the login screen.
Learn to test go http middleware authentication by writing unit tests with the http test package, simulating sessions, and verifying 200 status for authenticated access and 307 redirect for unauthenticated access.
Update routes and end-to-end tests by adding expected url and first status code for routes like /user/login and /user/profile. Use a custom http client to capture the first redirect status.
Fix the route labeling to 'user profile' and enable tests to run without a database by introducing the repository pattern and a test database repository.
Explore the repository pattern to decouple tests from a database, enabling isolated unit tests with no external dependencies. Build two repositories: Postgres-connected and in-memory.
Define an interface type for the database repository in Go, set up a repository package, and list user-related operations to prepare for Postgres implementation.
Implement a Postgres DB repository by creating a db repo folder, defining the Postgres DB repo type, and implementing the connection method and user-related repository functions for the repository pattern.
Update the application to use the database repository by replacing the direct postgres connection with a repository db repo, and wire the login handler to use it.
Create a test db repository in the db repo package, implement all repository functions by adapting the Postgres db repo, adjust receivers and imports, and return simple values for tests.
Update the setup to use the test database repository, remove db connection, replace app db with a reference to test db repo, and run the tests.
Update tests to use the testdb repository and adjust get user by email to return a user when the email is admin@example.com.
Spin up a temporary Postgres Docker image to run integration tests that exercise database interactions, using empty tables matching production, and separate integration from unit tests with Go build tags.
Perform integration tests for the database layer by spinning up a Docker test Postgres instance that mirrors schema and tests the db repo users and images tables with go test.
Connect to Docker and start a Postgres image with user, password, and database; wait for readiness, create empty users and users_image tables, run tests, and purge to reset state.
Learn how to populate a Postgres test database with empty tables inside a docker setup, read sql fixtures, handle errors, and verify the database with a ping test.
Write and run a unit test for insert user in a Go Postgres repo using dockerized Postgres and a test repository to verify id and error handling.
Practice testing in Go by inserting users, validating that all_users returns correct counts (one, then two), and verifying alphabetical sorting by last name.
Test get user by ID and get user by email in the Postgres db repo. Validate correct id and email, and handle non-existent users.
Showcases Go testing for update user: fetch a user by ID, modify first name and email, call update user, re-fetch, and verify changes with error checks.
Learn to test deleting a user in Go by writing an integration test for delete user, verifying the user is removed via a get user call, and running Go test.
Develop a Go test for the reset password function, verifying hash generation, password update, error handling, and password verification via user.password_matches.
Test the insert user image function in Go with docker-based Postgres integration tests, validating the user ID foreign key, column naming, and separating integration from unit tests.
Learn how to separate integration tests from unit tests in Go using build tags, run integration tests with -tags=integration, avoid common tag syntax mistakes, and speed up test runs.
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. 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.
Please note that this course requires you to download Docker Desktop from Docker. If you are a Udemy Business user, please check with your employer before downloading software.