trait Retries extends AnyRef
Provides methods that can be used in withFixture implementations to retry tests in various scenarios.
Trait Retries is intended to help you deal with “flickers”—tests that usually pass, but
occasionally fail. The best way to deal with such tests is to fix them so they always pass. Sometimes, however, this is
not practical. In such cases, flickers can waste your time by forcing you to investigate test failures that turn
out to be flickers. Or worse, like the boy who cried wolf, the flickers may train you an your colleagues to not pay attention
to failures such that you don't notice real problems, at least not in a timely manner.
Trait Retries offers methods that will retry a failed and/or canceled test once, on the same thread,
with or without a delay. These methods take a block that results in Outcome,
and are intended to be used in withFixture methods. You should be very selective about which tests you
retry, retrying those for which you have good evidence to conclude they are flickers. Thus it is recommended you
only retry tests that are tagged with Retryable, and only tag tests as such once they have flickered
consistently for a while, and only after you invested a reasonable effort into fixing them properly.
Here's an example showing how you might use Retries:
package org.scalatest.examples.tagobjects.retryable
import org.scalatest._ import tagobjects.Retryable
class SetSpec extends FlatSpec with Retries {
override def withFixture(test: NoArgTest) = { if (isRetryable(test)) withRetry { super.withFixture(test) } else super.withFixture(test) }
"An empty Set" should "have size 0" taggedAs(Retryable) in { assert(Set.empty.size === 0) } }
- Source
- Retries.scala
- Alphabetic
- By Inheritance
- Retries
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
def
isRetryable(testData: TestData): Boolean
Indicates whether the test described by the given
TestDataincludes the tagorg.scalatest.tags.Retryable.Indicates whether the test described by the given
TestDataincludes the tagorg.scalatest.tags.Retryable.This method provides an easy way to selectively retry just tests that are flickering. You can annotated such problematic tests with
Retryable, and just retry those. Here's what it might look like:override def withFixture(test: NoArgTest) = { if (isRetryable(test)) withRetry { super.withFixture(test) } else super.withFixture(test) }
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
def
withRetry(delay: Span)(blk: ⇒ Outcome): Outcome
Retries the given block with a given delay if the
Outcomeof executing the block is eitherFailedorCanceled.Retries the given block with a given delay if the
Outcomeof executing the block is eitherFailedorCanceled.The behavior of this method is defined in the table below. The first two rows show the main "retry" behavior: if executing the block initially fails, and on retry it succeeds, the result is
Canceled. The purpose of this is to deal with "flickering" tests by downgrading a failure that succeeds on retry to a cancelation. Or, if executing the block initially results inCanceled, and on retry it succeeds, the result isSucceeded. The purpose of this is to deal with tests that intermittently cancel by ignoring a cancelation that succeeds on retry.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, after sleeping the given delay.First OutcomeRetry OutcomeResult FailedSucceededCanceled(theSucceededandFailedare discarded; the exception from theFailedis the cause of the exception in theCanceled)CanceledSucceededSucceeded(theCanceledis discarded)Succeeded— Succeeded(no retry)Pending— Pending(no retry)FailedFailedthe first Failed(the secondFailedis discarded)FailedPendingthe Failed(thePendingis discarded)FailedCanceledthe Failed(theCanceledis discarded)CanceledCanceledthe first Canceled(the secondCanceledis discarded)CanceledPendingthe Canceled(thePendingis discarded)CanceledFailedthe Failed(theCanceledis discarded)- delay
the amount of time to sleep before retrying
- blk
the block to execute and potentially retry
-
def
withRetry(blk: ⇒ Outcome): Outcome
Retries the given block immediately (with no delay) if the
Outcomeof executing the block is eitherFailedorCanceled.Retries the given block immediately (with no delay) if the
Outcomeof executing the block is eitherFailedorCanceled.The behavior of this method is defined in the table below. The first two rows show the main "retry" behavior: if executing the block initially fails, and on retry it succeeds, the result is
Canceled. The purpose of this is to deal with "flickering" tests by downgrading a failure that succeeds on retry to a cancelation. Or, if executing the block initially results inCanceled, and on retry it succeeds, the result isSucceeded. The purpose of this is to deal with tests that intermittently cancel by ignoring a cancelation that succeeds on retry.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, with no delay.First OutcomeRetry OutcomeResult FailedSucceededCanceled(theSucceededandFailedare discarded; the exception from theFailedis the cause of the exception in theCanceled)CanceledSucceededSucceeded(theCanceledis discarded)Succeeded— Succeeded(no retry)Pending— Pending(no retry)FailedFailedthe first Failed(the secondFailedis discarded)FailedPendingthe Failed(thePendingis discarded)FailedCanceledthe Failed(theCanceledis discarded)CanceledCanceledthe first Canceled(the secondCanceledis discarded)CanceledPendingthe Canceled(thePendingis discarded)CanceledFailedthe Failed(theCanceledis discarded)- blk
the block to execute and potentially retry
-
def
withRetryOnCancel(delay: Span)(blk: ⇒ Outcome): Outcome
Retries the given block after the given delay if the
Outcomeof executing the block isCanceled.Retries the given block after the given delay if the
Outcomeof executing the block isCanceled.The behavior of this method is defined in the table below. The first row shows the main "retry" behavior: if executing the block initially results in
Canceled, and on retry it succeeds, the result isSucceeded. The purpose of this is to deal with tests that intermittently cancel by ignoring a cancelation that succeeds on retry.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, after the given delay.First OutcomeRetry OutcomeResult CanceledSucceededthe Succeeded(theCanceledis discarded)Succeeded— Succeeded(no retry)Pending— Pending(no retry)Failed— Failed(no retry)CanceledCanceledthe first Canceled(the secondCanceledis discarded)CanceledPendingthe Canceled(thePendingis discarded)CanceledFailedthe Failed(theCanceledis discarded)- delay
the amount of time to sleep before retrying
- blk
the block to execute and potentially retry
-
def
withRetryOnCancel(blk: ⇒ Outcome): Outcome
Retries the given block immediately (with no delay) if the
Outcomeof executing the block isCanceled.Retries the given block immediately (with no delay) if the
Outcomeof executing the block isCanceled.The behavior of this method is defined in the table below. The first row shows the main "retry" behavior: if executing the block initially results in
Canceled, and on retry it succeeds, the result isSucceeded. The purpose of this is to deal with tests that intermittently cancel by ignoring a cancelation that succeeds on retry.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, with no delay.First OutcomeRetry OutcomeResult CanceledSucceededthe Succeeded(theCanceledis discarded)Succeeded— Succeeded(no retry)Pending— Pending(no retry)Failed— Failed(no retry)CanceledCanceledthe first Canceled(the secondCanceledis discarded)CanceledPendingthe Canceled(thePendingis discarded)CanceledFailedthe Failed(theCanceledis discarded)- blk
the block to execute and potentially retry
-
def
withRetryOnFailure(delay: Span)(blk: ⇒ Outcome): Outcome
Retries the given block immediately with the given delay if the
Outcomeof executing the block isFailed.Retries the given block immediately with the given delay if the
Outcomeof executing the block isFailed.The behavior of this method is defined in the table below. The first row shows the main "retry" behavior: if executing the block initially fails, and on retry it succeeds, the result is
Canceled. The purpose of this is to deal with "flickering" tests by downgrading a failure that succeeds on retry to a cancelation.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, after the given delay.First OutcomeRetry OutcomeResult FailedSucceededCanceled(theSucceededandFailedare discarded; the exception from theFailedis the cause of the exception in theCanceled)Succeeded— Succeeded(no retry)Pending— Pending(no retry)Canceled— the Canceled(no retry)FailedFailedthe first Failed(the secondFailedis discarded)FailedPendingthe Failed(thePendingis discarded)FailedCanceledthe Failed(theCanceledis discarded)- delay
the amount of time to sleep before retrying
- blk
the block to execute and potentially retry
-
def
withRetryOnFailure(blk: ⇒ Outcome): Outcome
Retries the given block immediately (with no delay) if the
Outcomeof executing the block isFailed.Retries the given block immediately (with no delay) if the
Outcomeof executing the block isFailed.The behavior of this method is defined in the table below. The first row shows the main "retry" behavior: if executing the block initially fails, and on retry it succeeds, the result is
Canceled. The purpose of this is to deal with "flickering" tests by downgrading a failure that succeeds on retry to a cancelation.In the table below, if the “Retry
Outcome” has just a dash, the block is not retried. Otherwise, the block is retried on the same thread, with no delay.First OutcomeRetry OutcomeResult FailedSucceededCanceled(theSucceededandFailedare discarded; the exception from theFailedis the cause of the exception in theCanceled)Succeeded— Succeeded(no retry)Pending— Pending(no retry)Canceled— the Canceled(no retry)FailedFailedthe first Failed(the secondFailedis discarded)FailedPendingthe Failed(thePendingis discarded)FailedCanceledthe Failed(theCanceledis discarded)- blk
the block to execute and potentially retry