The testing package has many logging functions that are used for logging only when errors are encountered. It would be beneficial to be able to easily redirect output to this. I can't see a simple way to do this currently besides creating an io.Writer that outputs to testing.Logf.
Hi @drewwells, I've you tried somehow to set the logger.Out field to os.Stdout instead of os.Stderr ? I wonder if the test environment doesn't do something Stdout in order to only have its output upon test failure.
@drewwells it's slightly tricky since you need to get access to the *testing.T instance of each test, and it is hardcoded to look back a certain number of stack frames for the calling location.
In one of our projects at work we have this:
package serenity
import (
"io"
"os"
"testing"
"github.com/sirupsen/logrus"
)
// LogCapturer reroutes testing.T log output
type LogCapturer interface {
Release()
}
type logCapturer struct {
*testing.T
origOut io.Writer
}
func (tl logCapturer) Write(p []byte) (n int, err error) {
tl.Logf((string)(p))
return len(p), nil
}
func (tl logCapturer) Release() {
logrus.SetOutput(tl.origOut)
}
// CaptureLog redirects logrus output to testing.Log
func CaptureLog(t *testing.T) LogCapturer {
lc := logCapturer{T: t, origOut: logrus.StandardLogger().Out}
if !testing.Verbose() {
logrus.SetOutput(lc)
}
return &lc
}
But it does mean in every test you need to do:
```golang
func TestFoo(t *testing.T) {
defer serenity.CaptureLog(t).Release()
…
}
We can use logrus.SetOutput(ioutil.Discard) to disable output.
import (
"io/ioutil"
"testing"
"github.com/sirupsen/logrus"
)
func TestFoo(t *testing.T) {
logrus.Info("Logrus in Testing")
}
func TestMain(m *testing.M) {
logrus.SetOutput(ioutil.Discard)
os.Exit(m.Run())
}
Note: we need to call m.Run() to execute the test after defining the TestMain.
Most helpful comment
@drewwells it's slightly tricky since you need to get access to the
*testing.Tinstance of each test, and it is hardcoded to look back a certain number of stack frames for the calling location.In one of our projects at work we have this:
But it does mean in every test you need to do:
```golang
func TestFoo(t *testing.T) {
defer serenity.CaptureLog(t).Release()
…
}