@@ -97,7 +97,63 @@ public void ApplyToContext(TestExecutionContext context)
9797 /// <param name="command">the test command</param>
9898 /// <returns>the wrapped test command</returns>
9999 public TestCommand Wrap ( TestCommand command )
100- => new UnobservedTaskExceptionCommand ( command ) ;
100+ {
101+ if ( Environment . GetEnvironmentVariable ( "CI" ) != null )
102+ {
103+ command = new RetryCommand ( command , 3 ) ;
104+ }
105+ return new UnobservedTaskExceptionCommand ( command ) ;
106+ }
107+
108+ // RetryAttribute.RetryCommand only retries AssertionException but we want to retry all exceptions. See
109+ // https://github.com/nunit/nunit/issues/1388#issuecomment-2574970271
110+ internal class RetryCommand ( TestCommand innerCommand , int retryCount ) : DelegatingTestCommand ( innerCommand )
111+ {
112+ private readonly int _retryCount = retryCount ;
113+
114+ public override TestResult Execute ( TestExecutionContext context )
115+ {
116+ int tryCount = 0 ;
117+ bool isPassed = false ;
118+
119+ while ( tryCount < _retryCount )
120+ {
121+ try
122+ {
123+ innerCommand . Execute ( context ) ;
124+ if ( context . CurrentResult . ResultState == ResultState . Success )
125+ {
126+ isPassed = true ;
127+ break ;
128+ }
129+ }
130+ catch ( Exception )
131+ {
132+ // Ignore the exception
133+ }
134+
135+ tryCount ++ ;
136+ if ( tryCount < _retryCount )
137+ {
138+ // Reset only if there will be another retry
139+ context . CurrentResult = context . CurrentTest . MakeTestResult ( ) ;
140+ }
141+
142+ }
143+
144+ LogFinalOutcome ( context . CurrentResult , tryCount == 0 , isPassed ) ;
145+
146+ return context . CurrentResult ;
147+ }
148+
149+ private void LogFinalOutcome ( TestResult result , bool firstAttempt , bool isPassed )
150+ {
151+ if ( ! firstAttempt )
152+ {
153+ Console . Error . WriteLine ( $ "WARNING: Test { result . FullName } needed { _retryCount } retries and { ( isPassed ? "passed" : "failed" ) } ") ;
154+ }
155+ }
156+ }
101157
102158 /// <summary>
103159 /// Helper to detect UnobservedTaskExceptions
0 commit comments