diff --git a/src/test/java/io/bitsquare/util/Repeat.java b/src/test/java/io/bitsquare/util/Repeat.java
new file mode 100644
index 0000000000..d67c8be70b
--- /dev/null
+++ b/src/test/java/io/bitsquare/util/Repeat.java
@@ -0,0 +1,38 @@
+/*
+ * This file is part of Bitsquare.
+ *
+ * Bitsquare is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bitsquare is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bitsquare. If not, see .
+ */
+
+package io.bitsquare.util;
+
+import java.lang.annotation.ElementType;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Method-level annotation to be used in connection with {@link RepeatRule} to cause a
+ * given {@link org.junit.Test} method to be repeated a specified number of times.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Repeat {
+
+ /**
+ * Specifies the number of times to repeat the annotated {@link org.junit.Test}.
+ */
+ int value();
+}
\ No newline at end of file
diff --git a/src/test/java/io/bitsquare/util/RepeatRule.java b/src/test/java/io/bitsquare/util/RepeatRule.java
new file mode 100644
index 0000000000..6505952950
--- /dev/null
+++ b/src/test/java/io/bitsquare/util/RepeatRule.java
@@ -0,0 +1,57 @@
+/*
+ * This file is part of Bitsquare.
+ *
+ * Bitsquare is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bitsquare is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bitsquare. If not, see .
+ */
+
+package io.bitsquare.util;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * @see {@link Repeat}
+ */
+public class RepeatRule implements TestRule {
+
+ private static class RepeatStatement extends Statement {
+
+ private final int times;
+ private final Statement statement;
+
+ private RepeatStatement(int times, Statement statement) {
+ this.times = times;
+ this.statement = statement;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ for (int i = 0; i < times; i++) {
+ statement.evaluate();
+ }
+ }
+ }
+
+ @Override
+ public Statement apply(Statement statement, Description description) {
+ Statement result = statement;
+ Repeat repeat = description.getAnnotation(Repeat.class);
+ if (repeat != null) {
+ int times = repeat.value();
+ result = new RepeatStatement(times, statement);
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/io/bitsquare/util/RepeatRuleTests.java b/src/test/java/io/bitsquare/util/RepeatRuleTests.java
new file mode 100644
index 0000000000..f9278d3c32
--- /dev/null
+++ b/src/test/java/io/bitsquare/util/RepeatRuleTests.java
@@ -0,0 +1,68 @@
+/*
+ * This file is part of Bitsquare.
+ *
+ * Bitsquare is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bitsquare is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bitsquare. If not, see .
+ */
+
+package io.bitsquare.util;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.*;
+
+public class RepeatRuleTests {
+
+ private static final int EXPECTED_COUNT = 10;
+ private static int ACTUAL_BEFORE_COUNT;
+ private static int ACTUAL_TEST_COUNT;
+ private static int ACTUAL_AFTER_COUNT;
+
+ public @Rule RepeatRule repeatRule = new RepeatRule();
+
+ @BeforeClass
+ public static void beforeTests() {
+ ACTUAL_BEFORE_COUNT = 0;
+ ACTUAL_TEST_COUNT = 0;
+ ACTUAL_AFTER_COUNT = 0;
+ }
+
+ @Before
+ public void setUp() {
+ ACTUAL_BEFORE_COUNT++;
+ }
+
+ @Test
+ @Repeat(EXPECTED_COUNT)
+ public void shouldBeRepeated() {
+ ACTUAL_TEST_COUNT++;
+ }
+
+ @After
+ public void tearDown() {
+ ACTUAL_AFTER_COUNT++;
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ assertThat(ACTUAL_BEFORE_COUNT, equalTo(EXPECTED_COUNT));
+ assertThat(ACTUAL_TEST_COUNT, equalTo(EXPECTED_COUNT));
+ assertThat(ACTUAL_AFTER_COUNT, equalTo(EXPECTED_COUNT));
+ }
+}