001/**
002 * Powerunit - A JDK1.8 test framework
003 * Copyright (C) 2014 Mathieu Boretti.
004 *
005 * This file is part of Powerunit
006 *
007 * Powerunit is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation, either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * Powerunit is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
019 */
020package ch.powerunit;
021
022import java.lang.annotation.Documented;
023import java.lang.annotation.ElementType;
024import java.lang.annotation.Retention;
025import java.lang.annotation.RetentionPolicy;
026import java.lang.annotation.Target;
027
028/**
029 * Mark a method as being a test method.
030 * <p>
031 * This method must be public, non static, 0-arg, void return.
032 *
033 * @author borettim
034 *
035 */
036@Documented
037@Retention(RetentionPolicy.RUNTIME)
038@Target(ElementType.METHOD)
039public @interface Test {
040        /**
041         * Define an alternative name for the test.
042         * <p>
043         * If not used, the test name will be based on the method name. In case of
044         * parameterized test, the name will be formatted in the same way that the
045         * {@link Parameters @Parameters} annotation will be.
046         * 
047         * @return the name
048         * @see Parameters#value() For the exact syntax of the name model.
049         * @see java.text.MessageFormat#format(String, Object...) The formatter used
050         *      for parameterized test. For version before 0.4.0.
051         * @see java.lang.String#format(String, Object...) The formatter used for
052         *      parameterized test, since version 0.4.0.
053         */
054        String name() default "";
055
056        /**
057         * Define if the test must fail at the first assertion/failure in error
058         * (default) or only at the end (and accumulate all expected error).
059         * <p>
060         * The goal is here to change the fail assertion and failure work ; When set
061         * to <code>false</code>. Assertion/failure will not stop the test, but
062         * return false. It is up to the test itself to define what to be done based
063         * on this return value (continue, return, etc). At the end of the test, if
064         * any failure happened, a general failure will be produced, with detail
065         * regarding all failures. <br>
066         * For example, a test may look like :
067         * 
068         * <pre>
069         * public class LaterFailureTest implements TestSuite {
070         *      &#064;Test(fastFail = false)
071         *      public void test() {
072         *              assertThat(true).is(false);
073         *              assertWhen((p) -&gt; {
074         *              }).throwException(any(Throwable.class));
075         *              fail(&quot;demo&quot;);
076         *      }
077         * }
078         * </pre>
079         * 
080         * And the result like:
081         * 
082         * <pre>
083         * Multiple failures : 
084         *      Error : expecting &lt;false&gt; but was &lt;true&gt;
085         *      Error : An exception was expected, but none was thrown
086         *      Error : demo
087         * 
088         * Original Stack Traces
089         *      expecting &lt;false&gt; but was &lt;true&gt;
090         *              ch.powerunit.impl.AssertThatObjectImpl.is(AssertThatObjectImpl.java:63)
091         *              ...
092         *      An exception was expected, but none was thrown
093         *              ch.powerunit.impl.AssertThatExceptionImpl.throwException(AssertThatExceptionImpl.java:64)
094         *              ...
095         *      demo
096         *              ch.powerunit.Assert.fail(Assert.java:578)
097         *              ...
098         * 
099         * ch.powerunit.impl.TestContextImpl.fail(TestContextImpl.java:115)
100         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl.lambda$null$104(DefaultPowerUnitRunnerImpl.java:505)
101         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl$$Lambda$38/665188480.run(Unknown Source)
102         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl.lambda$runOne$73(DefaultPowerUnitRunnerImpl.java:226)
103         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl$$Lambda$42/520022247.accept(Unknown Source)
104         * java.util.HashMap$EntrySet.forEach(HashMap.java:1035)
105         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl.runOne(DefaultPowerUnitRunnerImpl.java:210)
106         * ch.powerunit.impl.DefaultPowerUnitRunnerImpl.run(DefaultPowerUnitRunnerImpl.java:144)
107         * ch.powerunit.PowerUnitMainRunner.main(PowerUnitMainRunner.java:82)
108         * ch.powerunit.suite.Suites.main(Suites.java:73)
109         * </pre>
110         * 
111         * <br>
112         * This function will only function in the following case :
113         * <ul>
114         * <li>The assertion method is used from the same thread that the test
115         * itself (it is the standard case).</li>
116         * <li>The assertion method is used directement from the object test, and
117         * this class implements {@link TestSuite}.</li>
118         * </ul>
119         * 
120         * <h3>Examples</h3>
121         * <h4>Using two threads without fastFail</h4>
122         * Let's assume the following test class :
123         * 
124         * <pre>
125         * import ch.powerunit.Rule;
126         * import ch.powerunit.Test;
127         * import ch.powerunit.TestRule;
128         * import ch.powerunit.TestSuite;
129         * 
130         * public class MyBean4Test implements TestSuite {
131         *      &#064;Rule
132         *      public final TestRule rule = before(this::prepare);
133         * 
134         *      private MyBean bean;
135         * 
136         *      private void prepare() {
137         *              bean = new MyBean();
138         *      }
139         * 
140         *      &#064;Test()
141         *      public void testSimple() throws Exception {
142         *              Thread t = new Thread(() -&gt; {
143         *                      bean.setField1(&quot;y&quot;);
144         *                      assertThat(bean.getField1()).is(&quot;x&quot;);
145         *              });
146         *              t.start();
147         *              t.join();
148         *      }
149         * }
150         * </pre>
151         * 
152         * <b>This test will not fail!</b>. Why ? because simply the assertion
153         * failure happend in another thread, so this thread receive an assertion
154         * failure, not the once supporting the test.
155         * 
156         * <h4>Using two threads inside the same class, with fastFail</h4>
157         * Let's assume the following test class
158         * 
159         * <pre>
160         * import ch.powerunit.Rule;
161         * import ch.powerunit.Test;
162         * import ch.powerunit.TestRule;
163         * import ch.powerunit.TestSuite;
164         * 
165         * public class MyBean3Test implements TestSuite {
166         *      &#064;Rule
167         *      public final TestRule rule = before(this::prepare);
168         * 
169         *      private MyBean bean;
170         * 
171         *      private void prepare() {
172         *              bean = new MyBean();
173         *      }
174         * 
175         *      &#064;Test(fastFail = false)
176         *      public void testSimple() throws Exception {
177         *              Thread t = new Thread(() -&gt; {
178         *                      bean.setField1(&quot;y&quot;);
179         *                      assertThat(bean.getField1()).is(&quot;x&quot;);
180         *              });
181         *              t.start();
182         *              t.join();
183         *      }
184         * }
185         * </pre>
186         * 
187         * <b>This test will fail!</b>. Why ? because the fastFail mode will make
188         * the <code>assertThat</code> method only register the failure, and produce
189         * an error in the test thread. the link between the two threads is found
190         * because the <code>assertThat</code> method used is the one from the test
191         * class itself.
192         * 
193         * @return true by default.
194         * @since 0.4.0
195         */
196        boolean fastFail() default true;
197}