Testing, Stubbing, & Automating Go Training

This coursed was designed to take a student from their first day of testing in Go all the way through creating tests for asynchronous (concurrent) code, testing web API's, and understanding how to properly architect IO patterns for better testing. It will also show students how to configure, isolate, and performance tune their tests. Finally, it will cover several popular Go tools and packages, as well as show how to automate testing and testing workflows.

Length

2 days. Each day is 4 hours long including a 15 minute break.

Class Size

10 - 25 students. Need a larger or smaller class, just contact us for a custom quote.

Target Audience

  • You have been doing daily Go development for 1-3 months.
  • You want to learn more advanced Go testing patterns, such as asynchronous testing, mocking, stubbing, etc.
  • You want to learn how to create faster and more effective tests in Go.

Prerequisites

  • Familiarity and comfort navigating and basic file manipulation at the command line.
  • Familiarity and comfort with a modern code editor, including creating and modifying files and projects.
  • You have 1 to 3 months of daily Go experience.
  • You have at least 6 months of experience with other modern development languages such as Java, C#, Swift, JavaScript, Python, Rust, etc.
  • Familiarity with basic programming concepts and structures such as variables, loops, conditionals, etc.
  • Computers should be capable of modern software development, such as access to install and run binaries, install a code editor, etc. Full instructions referenced here: preparing your environment for Go development. It may be necessary for them to have root/admin access to their computer.

Recommended Preparation

  • Install and configure an editor for Go.
  • Have a functioning Go environment installed with Go 1.13 or later.
  • Sign up for a Github account if you don't already have one.

Suggested Followup Learning

Expected Outcomes

  • Students will understand how to create tests for asynchronous (concurrent) code.
  • Students will be able to stub out Go structures for better unit testing.
  • Students will understand the Go test ecosystem, as well as how to configure and run their Go tests efficiently.
  • Students will learn how to create unit tests and integration tests for web API's.

Course Details

Day One

Welcome

This module covers general information about your instructor and course materials.

Testing Basics

Testing in Go is easy, and simple to use. There is a strong emphasis on testing in Go. The compiler will catch a lot of bugs for you, but it can not ensure your business logic is sound or bug-free.

While the testing package isn't large, there are some features that are not properly understood. In this chapter we will cover the following concepts:

  • *testing.T
  • Error vs. Fatal
  • Failure Messages
  • Helpers
  • Testing Packages

Table Driven Testing

Table driven tests can be used to cover a lot of ground quickly while re-using common setup and comparison code. Table driven testing is not unique to Go, however, it is very powerful. In this module we will cover the different ways to create, run, and isolate table driven tests.

Running Tests

Understanding the different options to run tests can greatly reduce the feedback cycle during development. In this chapter, we will cover:

  • Running Specific Tests
  • Verbose Output
  • Failing Fast
  • Parallel Options
  • Short Testing
  • Timing Out Tests
  • Race Conditions

Break

Tea/Coffee Break.

Code Coverage

Code coverage is a great tool to show what part of your code is being tested. It will help identify areas that need more testing, as well as assist in making sure your tests actually test the part of the code you think it does.

Example Tests

No project is complete without great documentation. Example tests are a great way to not only document your code, but ensure that the examples you use always work as they are actually a test in addition to the documentation.

Stubbing & Mocking Tests

It's easy to decouple packages in Go using interfaces. Because of this, testing can also be much easier. However, you typically want to stub out your interfaces in tests so that unit testing is much easier. This chapter will cover how to write a stub for a service to enable easy and precise testing.

Day Two

Testing Net/HTTP

In the standard library there are two mechanisms for us to use to test web applications.

  • Unit Style Testing
  • Integration Style Testing

These are not their "official" names, but we believe they do a good job of describing the styles of testing. In this module, we will cover both styles of testing and how to use them.

Testing Asynchronous Tasks

Many times you may be testing parts of your code that have service dependency that run for an unknown amount of time.

Examples of these may be task queues, distributed system calls, etc.

Because you don't know how long they may take to execute, testing them can present some challenges.

In this module we will learn how to set up tests both effectively and efficiently for testing async processes.

Note: This module assumes the audience is familiar with concepts such as

  • httptest package
  • concurrency primitives such as channels and goroutines

Break

Tea/Coffee Break.

Testing With IO

Many times the software we design relies on reading and writing data, either to disk, network connections, etc. This chapter will show you how to properly architect your software so that it is easily testable without the need to create temporary files as well as show how to use the io interfaces in your tests.

Testing Tooling

There are many tools to assist with testing. This chapter will cover the following topics:

  • Comparing complex structures with go-cmp
  • How to use the testing/quick package
  • Fuzzing your API

Workflow Automation

Workflow automation can significantly improve developer productivity. This chapter will show how to implement some very simple, lightweight automation to automatically run tests and coverage.

Prerequisites

Interfaces

Interfaces in Go provide a way to specify the behavior of an object: If something can do this, then it can be used here. This chapter will take a look at how to use interfaces to abstract that behavior. Concepts such as the Empty Interface, satisfying multiple interfaces, and asserting for behavior will be covered. Additionally, this chapter will cover the difference between value and pointer receivers and how they affect the ability to satisfy an interface.

Embedding And Composition

Go does not provide the typical type-driven notion of subclassing. However, it does have the ability to “borrow” pieces of an implementation by embedding types within a struct or interface. This chapter will cover how promotion from embedding works as well how collision and overriding are handled. We will also walk through how to embed types to be able to satisfy a specific interface.

Errors

Error handling in Go can feel a bit tedious at first. However, this chapter will cover the benefits of how Go's error model results in more reliable code. This chapter will also cover how to handle basic errors and return errors as an interface that satisfies the error type. Concepts such as custom error types, panics, recovering from panics, and sentinel errors are also covered.

Introduction To Go Web Development

This chapter will cover some basic concepts of web development in Go. We'll cover how to create handlers, set up routing, and launch a basic web server.

Routing And Muxing

Routing in Go requires the use of a "muxer". In this module, we'll explore how to properly set up a muxer to route traffic properly in your web application.

HTTP Handlers

Understanding how Go web applications work means understanding the HTTP.Handler interface. This module will cover how Handler, HandlerFunc and ServeHTTP all work together to create the basic building blocks of a Go web service. We will also cover how to create and implement middleware, such as a basic logger and authentication.

Subscribe to our newsletter