Let’s build tags in go!!

Introduction

In Go, a build tag is an identifier added to a piece of code that determines when the file should be included in a package during the build process.

Why Go build tags?

Go does not have a preprocessor, a macro system, or a #define declaration to control the inclusion of platform-specific code. So to fulfill the conditional compilation build tags are introduced in Golang.

Build tag basics

Build tags are implemented as comments and can appear in any source file( not just go files), but it must appear on the top of the file in the case of GoLang. 

Note:  To differentiate between the package and build tags, there must be a blank line.

Rules for adding multiple tags

(1) ‘OR’ Rule

The tags separated by space will be interpreted as OR logic. This means that the package will be included if either of the tags is present when the build command is executed.

// +build tag1 tag2

(2) ‘AND’ Rule

Comma-separated tags will be interpreted as AND logic. This means that the package will be included only if all the mentioned tags are present when the build command is executed. 

// +build tag1,tag2

(3) ‘NOT’ Rule

Inverted tags will be interpreted as NOT logic. This means that the package will be included only if the mentioned tag is not present when the build command is executed.

// +build !tag2

5. Hands on

Let’s consider an example where we are working with different operating systems. Some functionalities are not there in the Linux operating system so we wrote a piece of code that will include the package according to our requirements only if the operating system is Linux else the package will be excluded from the build. At this time the real-time application of conditional compilation comes into the picture.

//go build linux
// +build linux
 
package systemd
 
import "fmt"
 
func systemD() {
   fmt.Println("Hello from linux operating system")
}

In the above example, we have added Linux build constraints. When we perform the go build operation, either we have to explicitly pass build tags to include the package or the default operating system should be Linux else it will be excluded.

6. Separate test cases in golang using build tags

As a go developer, we run go test ./… and our whole test cases will be executed present inside the root package.
The point is that we can not distinguish between the unit test and integration test, here is where Build tags become useful. You can provide build tags for test files. The tags can then be passed to the go test command.

go test -tags=integration/unit

I have two following files in my test directory. One is integration_test.go and another is unit_test.go.

(1) Integration Test 

When the chosen keyword is an integration test, I just need to add a comment on the top of my file // +build integration and run the command go test ./… -tags=integration to execute it. 

//go:build integration
// +build integration

package go_test

import (
	"fmt"
	"testing"
)

func TestIntegration(t *testing.T) {
	fmt.Println("testing:", t.Name())
}

Output

mohit.dehuliya_js@SW-LP09437 go-tags % go test -tags=integration       

testing:  TestIntegration

PASS

ok      github/mdehuliya        1.861s

(2) Unit test:

When the chosen keyword is integration test, I just need to add a comment on the top of my file // +build unit and run the command go test ./… -tags=unit to execute it.

//go:build unit
// +build unit

package go_test

import (
	"fmt"
	"testing"
)

func TestUnit(t *testing.T) {
	fmt.Println("testing:", t.Name())
}

Output

mohit.dehuliya_js@SW-LP09437 go-tags % go test -tags=unit       
testing: TestUnit
PASS
ok      github/mdehuliya        1.861s

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.