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));
+    }
+}