diff --git a/__tests__/__outputs__/golang-json.md b/__tests__/__outputs__/golang-json.md
new file mode 100644
index 0000000..aaa36ea
--- /dev/null
+++ b/__tests__/__outputs__/golang-json.md
@@ -0,0 +1,33 @@
+
+|Report|Passed|Failed|Skipped|Time|
+|:---|---:|---:|---:|---:|
+|fixtures/golang-json.json|3 ✅|5 ❌|1 ⚪|4s|
+## ❌ fixtures/golang-json.json
+**9** tests were completed in **4s** with **3** passed, **5** failed and **1** skipped.
+|Test suite|Passed|Failed|Skipped|Time|
+|:---|---:|---:|---:|---:|
+|[_/home/james_t/git/test-reporter/reports/go](#user-content-r0s0)|3 ✅|5 ❌|1 ⚪|4s|
+### ❌ _/home/james_t/git/test-reporter/reports/go
+```
+✅ TestPassing
+❌ TestFailing
+ calculator_test.go:19: expected 1+1 = 3, got 2
+
+❌ TestPanicInsideFunction
+ calculator_test.go:71: caught panic: runtime error: integer divide by zero
+
+❌ TestPanicInsideTest
+ calculator_test.go:71: caught panic: bad stuff
+
+⚪ TestSkipped
+ calculator_test.go:45: skipping test
+
+❌ TestCases
+
+TestCases
+ ✅ 1_+_2_=_3
+ ✅ 4_+_7_=_11
+ ❌ 2_+_3_=_4
+ calculator_test.go:62: expected 2 + 3 = 4, got 5
+
+```
\ No newline at end of file
diff --git a/__tests__/__snapshots__/golang-json.test.ts.snap b/__tests__/__snapshots__/golang-json.test.ts.snap
new file mode 100644
index 0000000..f2e4b04
--- /dev/null
+++ b/__tests__/__snapshots__/golang-json.test.ts.snap
@@ -0,0 +1,108 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`golang-json tests report from ./reports/dotnet test results matches snapshot 1`] = `
+TestRunResult {
+ "path": "fixtures/golang-json.json",
+ "suites": [
+ TestSuiteResult {
+ "groups": [
+ TestGroupResult {
+ "name": null,
+ "tests": [
+ TestCaseResult {
+ "error": undefined,
+ "name": "TestPassing",
+ "result": "success",
+ "time": 90,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "calculator_test.go:19: expected 1+1 = 3, got 2
+",
+ "message": "calculator_test.go:19: expected 1+1 = 3, got 2
+",
+ },
+ "name": "TestFailing",
+ "result": "failed",
+ "time": 760,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "calculator_test.go:71: caught panic: runtime error: integer divide by zero
+",
+ "message": "calculator_test.go:71: caught panic: runtime error: integer divide by zero
+",
+ },
+ "name": "TestPanicInsideFunction",
+ "result": "failed",
+ "time": 0,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "calculator_test.go:71: caught panic: bad stuff
+",
+ "message": "calculator_test.go:71: caught panic: bad stuff
+",
+ },
+ "name": "TestPanicInsideTest",
+ "result": "failed",
+ "time": 0,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "calculator_test.go:45: skipping test
+",
+ "message": "calculator_test.go:45: skipping test
+",
+ },
+ "name": "TestSkipped",
+ "result": "skipped",
+ "time": 110,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "",
+ "message": "",
+ },
+ "name": "TestCases",
+ "result": "failed",
+ "time": 1620,
+ },
+ ],
+ },
+ TestGroupResult {
+ "name": "TestCases",
+ "tests": [
+ TestCaseResult {
+ "error": undefined,
+ "name": "1_+_2_=_3",
+ "result": "success",
+ "time": 540,
+ },
+ TestCaseResult {
+ "error": undefined,
+ "name": "4_+_7_=_11",
+ "result": "success",
+ "time": 540,
+ },
+ TestCaseResult {
+ "error": {
+ "details": "calculator_test.go:62: expected 2 + 3 = 4, got 5
+",
+ "message": "calculator_test.go:62: expected 2 + 3 = 4, got 5
+",
+ },
+ "name": "2_+_3_=_4",
+ "result": "failed",
+ "time": 530,
+ },
+ ],
+ },
+ ],
+ "name": "_/home/james_t/git/test-reporter/reports/go",
+ "totalTime": undefined,
+ },
+ ],
+ "totalTime": undefined,
+}
+`;
diff --git a/__tests__/fixtures/golang-json.json b/__tests__/fixtures/golang-json.json
new file mode 100644
index 0000000..c18d7ef
--- /dev/null
+++ b/__tests__/fixtures/golang-json.json
@@ -0,0 +1,46 @@
+{"Time":"2025-04-21T14:45:43.899731191-05:00","Action":"start","Package":"_/home/james_t/git/test-reporter/reports/go"}
+{"Time":"2025-04-21T14:45:43.907303273-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPassing"}
+{"Time":"2025-04-21T14:45:43.907333465-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPassing","Output":"=== RUN TestPassing\n"}
+{"Time":"2025-04-21T14:45:43.998551886-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPassing","Output":" calculator_test.go:11: pass!\n"}
+{"Time":"2025-04-21T14:45:43.998572844-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPassing","Output":"--- PASS: TestPassing (0.09s)\n"}
+{"Time":"2025-04-21T14:45:43.998576971-05:00","Action":"pass","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPassing","Elapsed":0.09}
+{"Time":"2025-04-21T14:45:43.998580617-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestFailing"}
+{"Time":"2025-04-21T14:45:43.998582298-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestFailing","Output":"=== RUN TestFailing\n"}
+{"Time":"2025-04-21T14:45:44.763532195-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestFailing","Output":" calculator_test.go:19: expected 1+1 = 3, got 2\n"}
+{"Time":"2025-04-21T14:45:44.763556975-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestFailing","Output":"--- FAIL: TestFailing (0.76s)\n"}
+{"Time":"2025-04-21T14:45:44.763560434-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestFailing","Elapsed":0.76}
+{"Time":"2025-04-21T14:45:44.763564534-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideFunction"}
+{"Time":"2025-04-21T14:45:44.763566339-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideFunction","Output":"=== RUN TestPanicInsideFunction\n"}
+{"Time":"2025-04-21T14:45:44.763568422-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideFunction","Output":" calculator_test.go:71: caught panic: runtime error: integer divide by zero\n"}
+{"Time":"2025-04-21T14:45:44.763571047-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideFunction","Output":"--- FAIL: TestPanicInsideFunction (0.00s)\n"}
+{"Time":"2025-04-21T14:45:44.763575434-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideFunction","Elapsed":0}
+{"Time":"2025-04-21T14:45:44.763577511-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideTest"}
+{"Time":"2025-04-21T14:45:44.763579734-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideTest","Output":"=== RUN TestPanicInsideTest\n"}
+{"Time":"2025-04-21T14:45:44.763584346-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideTest","Output":" calculator_test.go:71: caught panic: bad stuff\n"}
+{"Time":"2025-04-21T14:45:44.763592493-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideTest","Output":"--- FAIL: TestPanicInsideTest (0.00s)\n"}
+{"Time":"2025-04-21T14:45:44.763595682-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestPanicInsideTest","Elapsed":0}
+{"Time":"2025-04-21T14:45:44.763598032-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestSkipped"}
+{"Time":"2025-04-21T14:45:44.763600787-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestSkipped","Output":"=== RUN TestSkipped\n"}
+{"Time":"2025-04-21T14:45:44.875085305-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestSkipped","Output":" calculator_test.go:45: skipping test\n"}
+{"Time":"2025-04-21T14:45:44.875128112-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestSkipped","Output":"--- SKIP: TestSkipped (0.11s)\n"}
+{"Time":"2025-04-21T14:45:44.875136234-05:00","Action":"skip","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestSkipped","Elapsed":0.11}
+{"Time":"2025-04-21T14:45:44.87514445-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases"}
+{"Time":"2025-04-21T14:45:44.87514908-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases","Output":"=== RUN TestCases\n"}
+{"Time":"2025-04-21T14:45:44.875158116-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/1_+_2_=_3"}
+{"Time":"2025-04-21T14:45:44.875163067-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/1_+_2_=_3","Output":"=== RUN TestCases/1_+_2_=_3\n"}
+{"Time":"2025-04-21T14:45:45.413895814-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/4_+_7_=_11"}
+{"Time":"2025-04-21T14:45:45.413916191-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/4_+_7_=_11","Output":"=== RUN TestCases/4_+_7_=_11\n"}
+{"Time":"2025-04-21T14:45:45.957801848-05:00","Action":"run","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/2_+_3_=_4"}
+{"Time":"2025-04-21T14:45:45.957836789-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/2_+_3_=_4","Output":"=== RUN TestCases/2_+_3_=_4\n"}
+{"Time":"2025-04-21T14:45:46.492673381-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/2_+_3_=_4","Output":" calculator_test.go:62: expected 2 + 3 = 4, got 5\n"}
+{"Time":"2025-04-21T14:45:46.492759645-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases","Output":"--- FAIL: TestCases (1.62s)\n"}
+{"Time":"2025-04-21T14:45:46.492779916-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/1_+_2_=_3","Output":" --- PASS: TestCases/1_+_2_=_3 (0.54s)\n"}
+{"Time":"2025-04-21T14:45:46.492787539-05:00","Action":"pass","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/1_+_2_=_3","Elapsed":0.54}
+{"Time":"2025-04-21T14:45:46.492795891-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/4_+_7_=_11","Output":" --- PASS: TestCases/4_+_7_=_11 (0.54s)\n"}
+{"Time":"2025-04-21T14:45:46.492801851-05:00","Action":"pass","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/4_+_7_=_11","Elapsed":0.54}
+{"Time":"2025-04-21T14:45:46.492806634-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/2_+_3_=_4","Output":" --- FAIL: TestCases/2_+_3_=_4 (0.53s)\n"}
+{"Time":"2025-04-21T14:45:46.492811453-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases/2_+_3_=_4","Elapsed":0.53}
+{"Time":"2025-04-21T14:45:46.49281562-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Test":"TestCases","Elapsed":1.62}
+{"Time":"2025-04-21T14:45:46.492821605-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Output":"FAIL\n"}
+{"Time":"2025-04-21T14:45:46.493310745-05:00","Action":"output","Package":"_/home/james_t/git/test-reporter/reports/go","Output":"FAIL\t_/home/james_t/git/test-reporter/reports/go\t2.593s\n"}
+{"Time":"2025-04-21T14:45:46.493343801-05:00","Action":"fail","Package":"_/home/james_t/git/test-reporter/reports/go","Elapsed":2.594}
diff --git a/__tests__/golang-json.test.ts b/__tests__/golang-json.test.ts
new file mode 100644
index 0000000..37d45b3
--- /dev/null
+++ b/__tests__/golang-json.test.ts
@@ -0,0 +1,29 @@
+import * as fs from 'fs'
+import * as path from 'path'
+
+import { GolangJsonParser } from '../src/parsers/golang-json/golang-json-parser'
+import { ParseOptions } from '../src/test-parser'
+import { getReport } from '../src/report/get-report'
+import { normalizeFilePath } from '../src/utils/path-utils'
+
+describe('golang-json tests', () => {
+ it('report from ./reports/dotnet test results matches snapshot', async () => {
+ const fixturePath = path.join(__dirname, 'fixtures', 'golang-json.json')
+ const outputPath = path.join(__dirname, '__outputs__', 'golang-json.md')
+ const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
+ const fileContent = fs.readFileSync(fixturePath, { encoding: 'utf8' })
+
+ const opts: ParseOptions = {
+ parseErrors: true,
+ trackedFiles: ['calculator.go', 'calculator_test.go']
+ }
+
+ const parser = new GolangJsonParser(opts)
+ const result = await parser.parse(filePath, fileContent)
+ expect(result).toMatchSnapshot()
+
+ const report = getReport([result])
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true })
+ fs.writeFileSync(outputPath, report)
+ })
+})
diff --git a/package.json b/package.json
index 96a951e..6c8cdc0 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,8 @@
"dart-fixture": "cd \"reports/dart\" && dart test --file-reporter=\"json:../../__tests__/fixtures/dart-json.json\"",
"dotnet-fixture": "dotnet test reports/dotnet/DotnetTests.XUnitTests --logger \"trx;LogFileName=../../../../__tests__/fixtures/dotnet-trx.trx\"",
"dotnet-nunit-fixture": "nunit.exe reports/dotnet/DotnetTests.NUnitV3Tests/bin/Debug/netcoreapp3.1/DotnetTests.NUnitV3Tests.dll --result=__tests__/fixtures/dotnet-nunit.xml",
+ "dotnet-nunit-legacy-fixture": "nunit-console.exe reports/dotnet-nunit-legacy/NUnitLegacy.sln --result=__tests__/fixtures/dotnet-nunit-legacy.xml",
+ "golang-json-fixture": "go test -v -json -timeout 5s ./reports/go | tee __tests__/fixtures/golang-json.json",
"jest-fixture": "cd \"reports/jest\" && npm test",
"mocha-fixture": "cd \"reports/mocha\" && npm test"
},
diff --git a/reports/go/calculator.go b/reports/go/calculator.go
new file mode 100644
index 0000000..c863ae0
--- /dev/null
+++ b/reports/go/calculator.go
@@ -0,0 +1,20 @@
+package main
+
+import "errors"
+
+func CalculatorSum(a, b int) int {
+ return a + b
+}
+
+func CalculatorDivide(a, b int) int {
+ return a / b
+}
+
+var ErrDivideByZero = errors.New("divide by zero")
+
+func CalculatorSafeDivide(a, b int) (int, error) {
+ if b == 0 {
+ return 0, ErrDivideByZero
+ }
+ return a / b, nil
+}
diff --git a/reports/go/calculator_test.go b/reports/go/calculator_test.go
new file mode 100644
index 0000000..c0649fb
--- /dev/null
+++ b/reports/go/calculator_test.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestPassing(t *testing.T) {
+ randomSleep()
+ t.Log("pass!")
+}
+
+func TestFailing(t *testing.T) {
+ randomSleep()
+ expected := 3
+ actual := CalculatorSum(1, 1)
+ if actual != expected {
+ t.Fatalf("expected 1+1 = %d, got %d", expected, actual)
+ }
+}
+
+func TestPanicInsideFunction(t *testing.T) {
+ defer catchPanics(t)
+
+ expected := 0
+ actual := CalculatorDivide(1, 0)
+ if actual != expected {
+ t.Fatalf("expected 1/1 = %d, got %d", expected, actual)
+ }
+}
+
+func TestPanicInsideTest(t *testing.T) {
+ defer catchPanics(t)
+ panic("bad stuff")
+}
+
+// Timeouts cause the entire test process to end - so we can't get good output for these
+// func TestTimeout(t *testing.T) {
+// time.Sleep(time.Second * 5)
+// }
+
+func TestSkipped(t *testing.T) {
+ randomSleep()
+ t.Skipf("skipping test")
+}
+
+func TestCases(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ a, b, c int
+ }{
+ {"1 + 2 = 3", 1, 2, 3},
+ {"4 + 7 = 11", 4, 7, 11},
+ {"2 + 3 = 4", 2, 3, 4},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ randomSleep()
+
+ c := CalculatorSum(tc.a, tc.b)
+ if c != tc.c {
+ t.Fatalf("expected %s, got %d", tc.name, c)
+ }
+ })
+ }
+}
+
+func catchPanics(t *testing.T) {
+ err := recover()
+ if err != nil {
+ t.Fatalf("caught panic: %v", err)
+ }
+}
+
+func randomSleep() {
+ time.Sleep(time.Duration(rand.Int63n(int64(time.Second))))
+}
diff --git a/reports/go/go.mod b/reports/go/go.mod
new file mode 100644
index 0000000..4b3a577
--- /dev/null
+++ b/reports/go/go.mod
@@ -0,0 +1,3 @@
+module test_reporter_example
+
+go 1.24.2
diff --git a/src/parsers/golang-json/golang-json-parser.ts b/src/parsers/golang-json/golang-json-parser.ts
new file mode 100644
index 0000000..b79e1f9
--- /dev/null
+++ b/src/parsers/golang-json/golang-json-parser.ts
@@ -0,0 +1,114 @@
+import { ParseOptions, TestParser } from '../../test-parser'
+
+import { GoTestEvent } from './golang-json-types'
+import { getExceptionSource } from '../../utils/node-utils'
+import { getBasePath, normalizeFilePath } from '../../utils/path-utils'
+
+import {
+ TestExecutionResult,
+ TestRunResult,
+ TestSuiteResult,
+ TestGroupResult,
+ TestCaseResult,
+ TestCaseError
+} from '../../test-results'
+
+export class GolangJsonParser implements TestParser {
+ assumedWorkDir: string | undefined
+
+ constructor(readonly options: ParseOptions) { }
+
+ async parse(path: string, content: string): Promise {
+ const events = await this.getGolangTestEvents(path, content)
+ return this.getTestRunResult(path, events)
+ }
+
+ private async getGolangTestEvents(path: string, content: string): Promise {
+ return content.trim().split('\n').map((line, index) => {
+ try {
+ return JSON.parse(line) as GoTestEvent
+ } catch (e) {
+ throw new Error(`Invalid JSON at ${path} line ${index + 1}\n\n${e}`)
+ }
+ })
+ }
+
+ private getTestRunResult(path: string, events: GoTestEvent[]): TestRunResult {
+ const eventGroups = new Map()
+ for (const event of events) {
+ if (!event.Test) {
+ continue
+ }
+ const k = `${event.Package}/${event.Test}`
+ let g = eventGroups.get(k)
+ if (!g) {
+ g = []
+ eventGroups.set(k, g)
+ }
+ g.push(event)
+ }
+
+ const suites: TestSuiteResult[] = []
+
+ for (const eventGroup of eventGroups.values()) {
+ const event = eventGroup[0]
+
+ let suite = suites.find(s => s.name === event.Package)
+ if (!suite) {
+ suite = new TestSuiteResult(event.Package, [])
+ suites.push(suite)
+ }
+
+ if (!event.Test) {
+ continue
+ }
+
+ let groupName: string | null
+ let testName: string
+ [groupName, testName] = event.Test.split('/', 2)
+ if (!testName) {
+ testName = groupName
+ groupName = null
+ }
+
+ let group = suite.groups.find(g => g.name === groupName)
+ if (!group) {
+ group = new TestGroupResult(groupName, [])
+ suite.groups.push(group)
+ }
+
+ const lastEvent = eventGroup.at(-1)!
+
+ const result: TestExecutionResult = lastEvent.Action === 'pass' ? 'success'
+ : lastEvent.Action === 'skip' ? 'skipped'
+ : 'failed'
+ if (lastEvent.Elapsed === undefined) {
+ throw new Error('missing elapsed on final test event')
+ }
+ const time: number = lastEvent.Elapsed * 1000
+
+ let error: TestCaseError | undefined = undefined
+ if (result !== 'success') {
+ const outputEvents = eventGroup
+ .filter(e => e.Action === 'output')
+ .map(e => e.Output ?? '')
+ // Go output prepends indentation to help group tests - remove it
+ .map(o => o.replace(/^ /, ''))
+
+ // First and last lines will be generic "test started" and "test finished" lines - remove them
+ outputEvents.splice(0, 1)
+ outputEvents.splice(-1, 1)
+
+ const details = outputEvents.join('')
+ error = {
+ message: details,
+ details: details
+ }
+ }
+
+ group.tests.push(new TestCaseResult(testName, result, time, error))
+ }
+
+ return new TestRunResult(path, suites)
+ }
+}
diff --git a/src/parsers/golang-json/golang-json-types.ts b/src/parsers/golang-json/golang-json-types.ts
new file mode 100644
index 0000000..f27fa86
--- /dev/null
+++ b/src/parsers/golang-json/golang-json-types.ts
@@ -0,0 +1,19 @@
+export type GoTestAction = 'start'
+ | 'run'
+ | 'pause'
+ | 'cont'
+ | 'pass'
+ | 'bench'
+ | 'fail'
+ | 'output'
+ | 'skip'
+
+export type GoTestEvent = {
+ Time: string
+ Action: GoTestAction
+ Package: string
+ Test?: string
+ Elapsed?: number
+ Output?: string
+ FailedBuild?: string
+}