I Want to Test Local Plural Packages on Go
Tags: webdev, go, testing, programming
Published: 2022-06-22 07:08:58

I faced the problem that it is difficult to test local plural packages on Go. For example, I want to test all packages (`calculate` and `outLog`) under `src` directory, as shown below.

```
./src
  |- calculate/
    |- calculate.go
    |- calculate_test.go
    |- go.mod
  |- outLog/
    |- outLog.go
    |- outLog_test.go
    |- go.mod
main.go
go.mod
```

You can test all packages using the below command if you do not make `go.mod` in `calculate` and `outLog` (it means that if you do not initialize `calculate` and `outLog` as a module).
However, you cannot use these packages on `main.go` if you do not initialize them as a module, so you should initialize them.

This article's goal is that I know how to test local plural packages after initializing them as packages(modules) on Go.
I could not find good TIPS in Google, so I took a trial-and-error. I want to share them.

On the other hand, Go has `interface`, so I guess that we can use [DI(Dependency Injection) on Go](https://blog.drewolson.org/dependency-injection-in-go). My guess is that it is better to test each local package after dividing dependencies among all packages(Single responsibility principle?), but I'm a beginner at using Go, so it is difficult for me to use DI for now. I shared this article topic as interim progress to DI.

## Initialize Each Local Package (Module)
Before testing, I initialize each package using the following command.

```shell
go mod init [any name of your package you decided]
go mod tidy
```

After that, I make a path to each package. I run the following command on the directory, which has `main.go`.

```shell
go mod edit -replace [any name of your package you decided]=[relative path to each module]
go mod tidy
```

In this article, I named `playground/calculate` and `playground/outLog` to each package, so `main.go` has the following source code.

```go
package main

import (
	"fmt"
	"playground/calculate"
	outlog "playground/outLog"
)

func main() {
	ol := outlog.OutLog{To_console: true, To_file: false}
	ol.Error("Success to output an Error🎉")
	res := calculate.Calculate(3)
	fmt.Printf("The result of calculation：%d", res)
}
```

# How to Test All Packages?
## Test Files on the Directory, Which Has `main.go`
I'm sure that I can test all packages if I make a test file on the directory, which has `main.go` as shown below.

```go
package main

import (
	"playground/calculate"
	outlog "playground/outLog"
	"testing"
)

func TestCal(t *testing.T) {
	result := calculate.Calculate(2)
	if result != 2*2 {
		t.Fatal("Not match the result of calculation.")
	}
}

func TestConsole(t *testing.T) {
	outLog := outlog.OutLog{To_console: true, To_file: false}
	rec, err := outLog.Error("Please find me!!🐬")
	if rec == "" || err != nil {
		t.Fatal("The failed to output an error.")
	}
}
```
After that, I run the following command on the directory, which has `main.go`.

```shell
go test -v ./...
```

However, I do not want to test in this way because I have to make a lot of test files on the directory which has `main.go`.

## Test All Packages using `go test -v [package name]`
This is a better solution, I think, but this command will be long if I use a log to packages.
In this article, `go.mod` of `main.go` is the following.

```mod
module playground/main

go 1.18

replace playground/outLog => ./src/outLog

replace playground/calculate => ./src/calculate

require (
	playground/calculate v0.0.0-00010101000000-000000000000
	playground/outLog v0.0.0-00010101000000-000000000000
)
```

I run the following command on the directory, which has `main.go` if I want to test `playground/calculate` and `playground/outLog`.

```shell
go test -v playground/calculate playground/outLog
```
After that command runs, I get the following result.

```shell
=== RUN   TestCal
--- PASS: TestCal (0.00s)
PASS
ok  	playground/calculate	(cached)
=== RUN   TestConsole
2022/06/17 15:55:19 [2022-06-17T15:55:19+09:00][Error] - Please find me!!🐬
--- PASS: TestConsole (0.00s)
PASS
ok  	playground/outLog	(cached)
```

In this way, the directory has `main.go` does not need to have too many test files. It is a good point.

# Conclusion
I do not have the best idea to resolve this problem. If you have any good ideas to resolve it, I would greatly appreciate it if you could let me know your idea.

---
This original article is the following that is written by me. This is a translation of a portion of this original article from Japanese to English.

{% embed https://zenn.dev/akira_kashihara/articles/190c544cc5eb4e %}