@@ -87,8 +87,8 @@ void defineReflectiveTests(Type type) {
8787 {
8888 var isSolo = _hasAnnotationInstance (classMirror, soloTest);
8989 var className = MirrorSystem .getName (classMirror.simpleName);
90- group = _Group (isSolo, _combineNames (_currentSuiteName, className),
91- classMirror.testLocation );
90+ group = _Group (
91+ isSolo, _combineNames (_currentSuiteName, className), classMirror);
9292 _currentGroups.add (group);
9393 }
9494
@@ -154,12 +154,16 @@ void _addTestsIfTopLevelSuite() {
154154 if (allGroups || group.isSolo) {
155155 for (var test in group.tests) {
156156 if (allTests || test.isSolo) {
157- test_package.test (test.name, test.function,
157+ test_package.test (test.name, () async {
158+ await group.ensureSetUpClass ();
159+ test.function ();
160+ },
158161 timeout: test.timeout,
159162 skip: test.isSkipped,
160163 location: test.location);
161164 }
162165 }
166+ test_package.tearDownAll (() => group.tearDownClass ());
163167 }
164168 }
165169 }
@@ -210,14 +214,14 @@ bool _hasSkippedTestAnnotation(MethodMirror method) =>
210214 _hasAnnotationInstance (method, skippedTest);
211215
212216Future <Object ?> _invokeSymbolIfExists (
213- InstanceMirror instanceMirror , Symbol symbol) {
217+ ObjectMirror objectMirror , Symbol symbol) {
214218 Object ? invocationResult;
215219 InstanceMirror ? closure;
216220 try {
217- closure = instanceMirror .getField (symbol);
221+ closure = objectMirror .getField (symbol);
218222 // ignore: avoid_catching_errors
219223 } on NoSuchMethodError {
220- // ignore
224+ // ignore: empty_catches
221225 }
222226
223227 if (closure is ClosureMirror ) {
@@ -307,10 +311,13 @@ class _AssertFailingTest {
307311class _Group {
308312 final bool isSolo;
309313 final String name;
310- final test_package.TestLocation ? location;
311314 final List <_Test > tests = < _Test > [];
312315
313- _Group (this .isSolo, this .name, this .location);
316+ /// For static group-wide operations eg `setUpClass` and `tearDownClass` .
317+ final ClassMirror _classMirror;
318+ Future <Object ?>? _setUpCompletion;
319+
320+ _Group (this .isSolo, this .name, this ._classMirror);
314321
315322 bool get hasSoloTest => tests.any ((test) => test.isSolo);
316323
@@ -327,6 +334,16 @@ class _Group {
327334 tests.add (_Test (isSolo, fullName, function, timeout? ._timeout,
328335 memberMirror.testLocation));
329336 }
337+
338+ /// Runs group-wide setup if it has not been started yet,
339+ /// ensuring it only runs once for a group. Set up runs and
340+ /// completes before any test of the group runs
341+ Future <Object ?> ensureSetUpClass () =>
342+ _setUpCompletion ?? = _invokeSymbolIfExists (_classMirror, #setUpClass);
343+
344+ /// Runs group-wide tear down after all tests of the group have
345+ /// run
346+ void tearDownClass () => _invokeSymbolIfExists (_classMirror, #tearDownClass);
330347}
331348
332349/// A marker annotation used to instruct dart2js to keep reflection information
0 commit comments