From 7bfbcaf1f7a6b4628ae6a7341aedd6155c184fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20M?= Date: Sun, 28 Jan 2024 11:56:58 +0000 Subject: [PATCH] src/goTest: fix multifile suite test fails to debug I have resumed the pull request golang/vscode-go#2415 and added the missing tests. Here is the original description: Collect a packages suites and maps their name with the caller function. This mapping is used to fix a bug where vscode-go was formatting wrong arguments for dlv (-test.run). Fixes golang/vscode-go#2414 Change-Id: Id6ac5d153fa1dbcdb7591b2bd0ee78bfa95686c6 GitHub-Last-Rev: 0fa9525dc1c5f0389775e59d83065e4d32558a08 GitHub-Pull-Request: golang/vscode-go#3128 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/555676 Reviewed-by: Than McIntosh TryBot-Result: kokoro Reviewed-by: Hyang-Ah Hana Kim Auto-Submit: Hyang-Ah Hana Kim Commit-Queue: Hyang-Ah Hana Kim --- extension/src/goTest.ts | 31 ++-- extension/src/goTest/run.ts | 12 +- extension/src/testUtils.ts | 145 ++++++++++++++++-- extension/test/gopls/codelens.test.ts | 140 ++++++++++++++++- extension/test/gopls/goTest.run.test.ts | 5 + extension/test/integration/test.test.ts | 13 ++ .../stretchrTestSuite/another_suite_test.go | 7 + .../test/testdata/stretchrTestSuite/go.mod | 7 +- 8 files changed, 325 insertions(+), 35 deletions(-) create mode 100644 extension/test/testdata/stretchrTestSuite/another_suite_test.go diff --git a/extension/src/goTest.ts b/extension/src/goTest.ts index 5d089bc02c..edc2460605 100644 --- a/extension/src/goTest.ts +++ b/extension/src/goTest.ts @@ -18,10 +18,12 @@ import { getBenchmarkFunctions, getTestFlags, getTestFunctionDebugArgs, - getTestFunctions, + getTestFunctionsAndTestSuite, getTestTags, goTest, - TestConfig + TestConfig, + SuiteToTestMap, + getTestFunctions } from './testUtils'; // lastTestConfig holds a reference to the last executed TestConfig which allows @@ -52,8 +54,11 @@ async function _testAtCursor( throw new NotFoundError('No tests found. Current file is not a test file.'); } - const getFunctions = cmd === 'benchmark' ? getBenchmarkFunctions : getTestFunctions; - const testFunctions = (await getFunctions(goCtx, editor.document)) ?? []; + const { testFunctions, suiteToTest } = await getTestFunctionsAndTestSuite( + cmd === 'benchmark', + goCtx, + editor.document + ); // We use functionName if it was provided as argument // Otherwise find any test function containing the cursor. const testFunctionName = @@ -67,9 +72,9 @@ async function _testAtCursor( await editor.document.save(); if (cmd === 'debug') { - return debugTestAtCursor(editor, testFunctionName, testFunctions, goConfig); + return debugTestAtCursor(editor, testFunctionName, testFunctions, suiteToTest, goConfig); } else if (cmd === 'benchmark' || cmd === 'test') { - return runTestAtCursor(editor, testFunctionName, testFunctions, goConfig, cmd, args); + return runTestAtCursor(editor, testFunctionName, testFunctions, suiteToTest, goConfig, cmd, args); } else { throw new Error(`Unsupported command: ${cmd}`); } @@ -92,7 +97,7 @@ async function _subTestAtCursor( } await editor.document.save(); - const testFunctions = (await getTestFunctions(goCtx, editor.document)) ?? []; + const { testFunctions, suiteToTest } = await getTestFunctionsAndTestSuite(false, goCtx, editor.document); // We use functionName if it was provided as argument // Otherwise find any test function containing the cursor. const currentTestFunctions = testFunctions.filter((func) => func.range.contains(editor.selection.start)); @@ -142,9 +147,9 @@ async function _subTestAtCursor( const escapedName = escapeSubTestName(testFunctionName, subTestName); if (cmd === 'debug') { - return debugTestAtCursor(editor, escapedName, testFunctions, goConfig); + return debugTestAtCursor(editor, escapedName, testFunctions, suiteToTest, goConfig); } else if (cmd === 'test') { - return runTestAtCursor(editor, escapedName, testFunctions, goConfig, cmd, args); + return runTestAtCursor(editor, escapedName, testFunctions, suiteToTest, goConfig, cmd, args); } else { throw new Error(`Unsupported command: ${cmd}`); } @@ -160,7 +165,7 @@ async function _subTestAtCursor( export function testAtCursor(cmd: TestAtCursorCmd): CommandFactory { return (ctx, goCtx) => (args: any) => { const goConfig = getGoConfig(); - _testAtCursor(goCtx, goConfig, cmd, args).catch((err) => { + return _testAtCursor(goCtx, goConfig, cmd, args).catch((err) => { if (err instanceof NotFoundError) { vscode.window.showInformationMessage(err.message); } else { @@ -202,13 +207,14 @@ async function runTestAtCursor( editor: vscode.TextEditor, testFunctionName: string, testFunctions: vscode.DocumentSymbol[], + suiteToTest: SuiteToTestMap, goConfig: vscode.WorkspaceConfiguration, cmd: TestAtCursorCmd, args: any ) { const testConfigFns = [testFunctionName]; if (cmd !== 'benchmark' && extractInstanceTestName(testFunctionName)) { - testConfigFns.push(...findAllTestSuiteRuns(editor.document, testFunctions).map((t) => t.name)); + testConfigFns.push(...findAllTestSuiteRuns(editor.document, testFunctions, suiteToTest).map((t) => t.name)); } const isMod = await isModSupported(editor.document.uri); @@ -259,11 +265,12 @@ export async function debugTestAtCursor( editorOrDocument: vscode.TextEditor | vscode.TextDocument, testFunctionName: string, testFunctions: vscode.DocumentSymbol[], + suiteToFunc: SuiteToTestMap, goConfig: vscode.WorkspaceConfiguration, sessionID?: string ) { const doc = 'document' in editorOrDocument ? editorOrDocument.document : editorOrDocument; - const args = getTestFunctionDebugArgs(doc, testFunctionName, testFunctions); + const args = getTestFunctionDebugArgs(doc, testFunctionName, testFunctions, suiteToFunc); const tags = getTestTags(goConfig); const buildFlags = tags ? ['-tags', tags] : []; const flagsFromConfig = getTestFlags(goConfig); diff --git a/extension/src/goTest/run.ts b/extension/src/goTest/run.ts index eb0f03e065..aff9fbef6c 100644 --- a/extension/src/goTest/run.ts +++ b/extension/src/goTest/run.ts @@ -21,7 +21,7 @@ import vscode = require('vscode'); import { outputChannel } from '../goStatus'; import { isModSupported } from '../goModules'; import { getGoConfig } from '../config'; -import { getBenchmarkFunctions, getTestFlags, getTestFunctions, goTest, GoTestOutput } from '../testUtils'; +import { getTestFlags, getTestFunctionsAndTestSuite, goTest, GoTestOutput } from '../testUtils'; import { GoTestResolver } from './resolve'; import { dispose, forEachAsync, GoTest, Workspace } from './utils'; import { GoTestProfiler, ProfilingOptions } from './profile'; @@ -161,8 +161,11 @@ export class GoTestRunner { await doc.save(); const goConfig = getGoConfig(test.uri); - const getFunctions = kind === 'benchmark' ? getBenchmarkFunctions : getTestFunctions; - const testFunctions = await getFunctions(this.goCtx, doc, token); + const { testFunctions, suiteToTest } = await getTestFunctionsAndTestSuite( + kind === 'benchmark', + this.goCtx, + doc + ); // TODO Can we get output from the debug session, in order to check for // run/pass/fail events? @@ -191,7 +194,8 @@ export class GoTestRunner { const run = this.ctrl.createTestRun(request, `Debug ${name}`); if (!testFunctions) return; - const started = await debugTestAtCursor(doc, escapeSubTestName(name), testFunctions, goConfig, id); + const started = await debugTestAtCursor(doc, escapeSubTestName(name), testFunctions, suiteToTest, goConfig, id); + if (!started) { subs.forEach((s) => s.dispose()); run.end(); diff --git a/extension/src/testUtils.ts b/extension/src/testUtils.ts index 0b72d9fbbd..4070f6e6d1 100644 --- a/extension/src/testUtils.ts +++ b/extension/src/testUtils.ts @@ -11,6 +11,7 @@ import cp = require('child_process'); import path = require('path'); import util = require('util'); import vscode = require('vscode'); +import { promises as fs } from 'fs'; import { applyCodeCoverageToAllEditors } from './goCover'; import { toolExecutionEnvironment } from './goEnv'; @@ -50,6 +51,7 @@ const testMethodRegex = /^\(([^)]+)\)\.(Test|Test\P{Ll}.*)$/u; const benchmarkRegex = /^Benchmark$|^Benchmark\P{Ll}.*/u; const fuzzFuncRegx = /^Fuzz$|^Fuzz\P{Ll}.*/u; const testMainRegex = /TestMain\(.*\*testing.M\)/; +const runTestSuiteRegex = /^\s*suite\.Run\(\w+,\s*(?:&?(?\w+)\{|new\((?\w+)\))/mu; /** * Input to goTest. @@ -153,27 +155,76 @@ export async function getTestFunctions( doc: vscode.TextDocument, token?: vscode.CancellationToken ): Promise { + const result = await getTestFunctionsAndTestifyHint(goCtx, doc, token); + return result.testFunctions; +} + +/** + * Returns all Go unit test functions in the given source file and an hint if testify is used. + * + * @param doc A Go source file + */ +export async function getTestFunctionsAndTestifyHint( + goCtx: GoExtensionContext, + doc: vscode.TextDocument, + token?: vscode.CancellationToken +): Promise<{ testFunctions?: vscode.DocumentSymbol[]; foundTestifyTestFunction?: boolean }> { const documentSymbolProvider = GoDocumentSymbolProvider(goCtx, true); const symbols = await documentSymbolProvider.provideDocumentSymbols(doc); if (!symbols || symbols.length === 0) { - return; + return {}; } const symbol = symbols[0]; if (!symbol) { - return; + return {}; } const children = symbol.children; - // With gopls dymbol provider symbols, the symbols have the imports of all + // With gopls symbol provider, the symbols have the imports of all // the package, so suite tests from all files will be found. const testify = importsTestify(symbols); - return children.filter( + + const allTestFunctions = children.filter( (sym) => - (sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) && + sym.kind === vscode.SymbolKind.Function && // Skip TestMain(*testing.M) - see https://github.com/golang/vscode-go/issues/482 !testMainRegex.test(doc.lineAt(sym.range.start.line).text) && - (testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name) || (testify && testMethodRegex.test(sym.name))) + (testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name)) ); + + const allTestMethods = testify + ? children.filter((sym) => sym.kind === vscode.SymbolKind.Method && testMethodRegex.test(sym.name)) + : []; + + return { + testFunctions: allTestFunctions.concat(allTestMethods), + foundTestifyTestFunction: allTestMethods.length > 0 + }; +} + +/** + * Returns all the Go test functions (or benchmark) from the given Go source file, and the associated test suites when testify is used. + * + * @param doc A Go source file + */ +export async function getTestFunctionsAndTestSuite( + isBenchmark: boolean, + goCtx: GoExtensionContext, + doc: vscode.TextDocument +): Promise<{ testFunctions: vscode.DocumentSymbol[]; suiteToTest: SuiteToTestMap }> { + if (isBenchmark) { + return { + testFunctions: (await getBenchmarkFunctions(goCtx, doc)) ?? [], + suiteToTest: {} + }; + } + + const { testFunctions, foundTestifyTestFunction } = await getTestFunctionsAndTestifyHint(goCtx, doc); + + return { + testFunctions: testFunctions ?? [], + suiteToTest: foundTestifyTestFunction ? await getSuiteToTestMap(goCtx, doc) : {} + }; } /** @@ -199,17 +250,16 @@ export function extractInstanceTestName(symbolName: string): string { export function getTestFunctionDebugArgs( document: vscode.TextDocument, testFunctionName: string, - testFunctions: vscode.DocumentSymbol[] + testFunctions: vscode.DocumentSymbol[], + suiteToFunc: SuiteToTestMap ): string[] { if (benchmarkRegex.test(testFunctionName)) { return ['-test.bench', '^' + testFunctionName + '$', '-test.run', 'a^']; } const instanceMethod = extractInstanceTestName(testFunctionName); if (instanceMethod) { - const testFns = findAllTestSuiteRuns(document, testFunctions); - const testSuiteRuns = ['-test.run', `^${testFns.map((t) => t.name).join('|')}$`]; - const testSuiteTests = ['-testify.m', `^${instanceMethod}$`]; - return [...testSuiteRuns, ...testSuiteTests]; + const testFns = findAllTestSuiteRuns(document, testFunctions, suiteToFunc); + return ['-test.run', `^${testFns.map((t) => t.name).join('|')}$/^${instanceMethod}$`]; } else { return ['-test.run', `^${testFunctionName}$`]; } @@ -222,12 +272,22 @@ export function getTestFunctionDebugArgs( */ export function findAllTestSuiteRuns( doc: vscode.TextDocument, - allTests: vscode.DocumentSymbol[] + allTests: vscode.DocumentSymbol[], + suiteToFunc: SuiteToTestMap ): vscode.DocumentSymbol[] { - // get non-instance test functions - const testFunctions = allTests?.filter((t) => !testMethodRegex.test(t.name)); - // filter further to ones containing suite.Run() - return testFunctions?.filter((t) => doc.getText(t.range).includes('suite.Run(')) ?? []; + const suites = allTests + // Find all tests with receivers. + ?.map((e) => e.name.match(testMethodRegex)) + .filter((e) => e?.length === 3) + // Take out receiever, strip leading *. + .map((e) => e && e[1].replace(/^\*/g, '')) + // Map receiver name to test that runs "suite.Run". + .map((e) => e && suiteToFunc[e]) + // Filter out empty results. + .filter((e): e is vscode.DocumentSymbol => !!e); + + // Dedup. + return [...new Set(suites)]; } /** @@ -254,6 +314,59 @@ export async function getBenchmarkFunctions( return children.filter((sym) => sym.kind === vscode.SymbolKind.Function && benchmarkRegex.test(sym.name)); } +export type SuiteToTestMap = Record; + +/** + * Returns a mapping between a package's function receivers to + * the test method that initiated them with "suite.Run". + * + * @param the URI of a Go source file. + * @return function symbols from all source files of the package, mapped by target suite names. + */ +export async function getSuiteToTestMap( + goCtx: GoExtensionContext, + doc: vscode.TextDocument, + token?: vscode.CancellationToken +) { + // Get all the package documents. + const packageDir = path.parse(doc.fileName).dir; + const packageContent = await fs.readdir(packageDir, { withFileTypes: true }); + const packageFilenames = packageContent + // Only go files. + .filter((dirent) => dirent.isFile()) + .map((dirent) => dirent.name) + .filter((name) => name.endsWith('.go')); + const packageDocs = await Promise.all( + packageFilenames.map((e) => path.join(packageDir, e)).map(vscode.workspace.openTextDocument) + ); + + const suiteToTest: SuiteToTestMap = {}; + for (const packageDoc of packageDocs) { + const funcs = await getTestFunctions(goCtx, packageDoc, token); + if (!funcs) { + continue; + } + + for (const func of funcs) { + const funcText = packageDoc.getText(func.range); + + // Matches run suites of the types: + // type1: suite.Run(t, MySuite{ + // type1: suite.Run(t, &MySuite{ + // type2: suite.Run(t, new(MySuite) + const matchRunSuite = funcText.match(runTestSuiteRegex); + if (!matchRunSuite) { + continue; + } + + const g = matchRunSuite.groups; + suiteToTest[g?.type1 || g?.type2 || ''] = func; + } + } + + return suiteToTest; +} + /** * go test -json output format. * which is a subset of https://golang.org/cmd/test2json/#hdr-Output_Format diff --git a/extension/test/gopls/codelens.test.ts b/extension/test/gopls/codelens.test.ts index 31c1fcdb3a..ac37516d9a 100644 --- a/extension/test/gopls/codelens.test.ts +++ b/extension/test/gopls/codelens.test.ts @@ -11,9 +11,10 @@ import sinon = require('sinon'); import vscode = require('vscode'); import { updateGoVarsFromConfig } from '../../src/goInstallTools'; import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens'; -import { subTestAtCursor } from '../../src/goTest'; +import { subTestAtCursor, testAtCursor } from '../../src/goTest'; import { MockExtensionContext } from '../mocks/MockContext'; import { Env } from './goplsTestEnv.utils'; +import * as testUtils from '../../src/testUtils'; suite('Code lenses for testing and benchmarking', function () { this.timeout(20000); @@ -200,4 +201,141 @@ suite('Code lenses for testing and benchmarking', function () { // Results should match `go test -list`. assert.deepStrictEqual(found, ['TestNotMain']); }); + + test('Debug - debugs a test with cursor on t.Run line', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(document); + editor.selection = new vscode.Selection(7, 4, 7, 4); + const result = await subTestAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestSample$/^sample_test_passing$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); +}); + +suite('Code lenses with stretchr/testify/suite', function () { + const ctx = MockExtensionContext.new(); + + const testdataDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata', 'stretchrTestSuite'); + const env = new Env(); + + this.afterEach(async function () { + // Note: this shouldn't use () => {...}. Arrow functions do not have 'this'. + // I don't know why but this.currentTest.state does not have the expected value when + // used with teardown. + env.flushTrace(this.currentTest?.state === 'failed'); + ctx.teardown(); + sinon.restore(); + }); + + suiteSetup(async () => { + await updateGoVarsFromConfig({}); + await env.startGopls(undefined, undefined, testdataDir); + }); + + suiteTeardown(async () => { + await env.teardown(); + }); + + test('Run test at cursor', async () => { + const goTestStub = sinon.stub(testUtils, 'goTest').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(vscode.Uri.file(path.join(testdataDir, 'suite_test.go'))); + editor.selection = new vscode.Selection(25, 4, 25, 4); + + const result = await testAtCursor('test')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(goTestStub.callCount, 1, 'expected one call to goTest'); + const gotConfig = goTestStub.getCall(0).args[0]; + assert.deepStrictEqual(gotConfig.functions, ['(*ExampleTestSuite).TestExample', 'TestExampleTestSuite']); + }); + + test('Run test at cursor in different file than test suite definition', async () => { + const goTestStub = sinon.stub(testUtils, 'goTest').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument( + vscode.Uri.file(path.join(testdataDir, 'another_suite_test.go')) + ); + editor.selection = new vscode.Selection(3, 4, 3, 4); + + const result = await testAtCursor('test')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(goTestStub.callCount, 1, 'expected one call to goTest'); + const gotConfig = goTestStub.getCall(0).args[0]; + assert.deepStrictEqual(gotConfig.functions, [ + '(*ExampleTestSuite).TestExampleInAnotherFile', + 'TestExampleTestSuite' + ]); + }); + + test('Debug test at cursor', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(vscode.Uri.file(path.join(testdataDir, 'suite_test.go'))); + editor.selection = new vscode.Selection(25, 4, 25, 4); + + const result = await testAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestExampleTestSuite$/^TestExample$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); + + test('Debug test at cursor in different file than test suite definition', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument( + vscode.Uri.file(path.join(testdataDir, 'another_suite_test.go')) + ); + editor.selection = new vscode.Selection(3, 4, 3, 4); + + const result = await testAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestExampleTestSuite$/^TestExampleInAnotherFile$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); }); diff --git a/extension/test/gopls/goTest.run.test.ts b/extension/test/gopls/goTest.run.test.ts index 112959a42d..d583dc99e9 100644 --- a/extension/test/gopls/goTest.run.test.ts +++ b/extension/test/gopls/goTest.run.test.ts @@ -8,12 +8,17 @@ import { GoTestExplorer } from '../../src/goTest/explore'; import { MockExtensionContext } from '../mocks/MockContext'; import { GoTest } from '../../src/goTest/utils'; import { Env } from './goplsTestEnv.utils'; +import { updateGoVarsFromConfig } from '../../src/goInstallTools'; suite('Go Test Runner', () => { const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata'); let testExplorer: GoTestExplorer; + suiteSetup(async () => { + await updateGoVarsFromConfig({}); + }); + suite('parseOutput', () => { const ctx = MockExtensionContext.new(); suiteSetup(async () => { diff --git a/extension/test/integration/test.test.ts b/extension/test/integration/test.test.ts index 1ca2431a47..500b176216 100644 --- a/extension/test/integration/test.test.ts +++ b/extension/test/integration/test.test.ts @@ -97,6 +97,19 @@ suite('Test Go Test Args', () => { flags: ['-run', 'TestC'] }); }); + test('use -testify.m for methods', () => { + runTest({ + expectedArgs: + 'test -timeout 30s -run ^TestExampleTestSuite$ -testify.m ^(TestExample|TestAnotherExample)$ ./...', + expectedOutArgs: + 'test -timeout 30s -run ^TestExampleTestSuite$ -testify.m ^(TestExample|TestAnotherExample)$ ./...', + functions: [ + '(*ExampleTestSuite).TestExample', + '(*ExampleTestSuite).TestAnotherExample', + 'TestExampleTestSuite' + ] + }); + }); }); suite('Test Go Test', function () { diff --git a/extension/test/testdata/stretchrTestSuite/another_suite_test.go b/extension/test/testdata/stretchrTestSuite/another_suite_test.go new file mode 100644 index 0000000000..1af57e7d34 --- /dev/null +++ b/extension/test/testdata/stretchrTestSuite/another_suite_test.go @@ -0,0 +1,7 @@ +package main_test + +func (suite *ExampleTestSuite) TestExampleInAnotherFile() { + if suite.VariableThatShouldStartAtFive != 5 { + suite.T().Fatalf("%d != %d", 5, suite.VariableThatShouldStartAtFive) + } +} diff --git a/extension/test/testdata/stretchrTestSuite/go.mod b/extension/test/testdata/stretchrTestSuite/go.mod index 272ea9c8a5..7703985823 100644 --- a/extension/test/testdata/stretchrTestSuite/go.mod +++ b/extension/test/testdata/stretchrTestSuite/go.mod @@ -1,10 +1,13 @@ module example/a -go 1.16 +go 1.21 + +require github.com/stretchr/testify v1.7.0 require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.1.0 // indirect - github.com/stretchr/testify v1.7.0 + github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect )