Golang Testing - flowup/knowledge GitHub Wiki

Tools used

  • Testify - testing and mocking framework
  • Goconvey - automatic test runner with UI

Concepts

🖼️ These concepts are all working with the Testify framework.

We will define a simple fibonacci function for the purpose of direct testing and table testing.

func Fib(n int) int {...}

Direct testing

Direct testing relays on the ability of code to be directly executed and asserted. These are the most simple tests, however, they are not as flexible as Table tests.

🤖 Use direct testing when there is no way of generalization of the given problem

func TestFib(t *testing.T) {
  // let's assert that third number of fibonacci sequence is 3
  assert.Equal(t, 2, Fib(3))
}

Table tests

Table tests are used whenever a generalization of inputs and outputs is available. E.g. Fibonacci sequence is well known and can be calculated. However, to test that it calculates the results correctly, we need to create a lookup table with known results.

func TestFib(t *testing.T) {
  candidates := map[int]int{
    1: 1,
    2: 1,
    3: 2,
    4: 3,
    5: 5,
  }

  for seq, res := range candidates {
    assert.Equal(t, res, Fib(seq))
  }
}

Any cases which caused bugs can be rapidly tested thanks to the table tests. All it involves is adding a new pair to the table.

Test Suites

Testing with mocks

Testing with mocks and HTTP testing require more advanced scenario, e.g. User registration process. We will cover this scenario with our Auth service.

// MailService is a service that is able to send mails to users
type MailService interface {
  Send(to string, text string)
}

type AuthService struct {
  mails MailService
}

// Register registers given user to the database and sends him
// confirmation email via s.mails.Send()
func (s *AuthService) Register(user User) {...}

🤖 This code is missing implementations, as the tester should always be able to determine what is the function doing at the first place

HTTP tests

⚠️ **GitHub.com Fallback** ⚠️