forked from junit-team/junit4
/
faq.fml
1729 lines (1685 loc) · 59.8 KB
/
faq.fml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<faqs title="Frequently Asked Questions" xmlns="http://maven.apache.org/FML/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/FML/1.0 http://maven.apache.org/xsd/fml-1.0.xsd">
<part id="faqinfo">
<title>About this frequently asked questions list</title>
<faq id="faqinfo_1">
<question>Who is responsible for this FAQ?</question>
<answer>
<p>The current version of this FAQ is maintained
by <a href="mailto:mike@clarkware.com">Mike Clark</a>.</p>
<p>Most of the wisdom contained in this FAQ comes from the
collective insights and hard-won experiences of the many good
folks who participate on the JUnit mailing list and the JUnit
community at large.</p>
<p>If you see your genius represented anywhere in this FAQ without
due credit to you, please send me an email and I'll make things
right.</p>
</answer>
</faq>
<faq id="faqinfo_2">
<question>How can I contribute to this FAQ?</question>
<answer>
<p>Your contributions to this FAQ are greatly appreciated! The
JUnit community thanks you in advance.</p>
<p>To contribute to this FAQ, simply write a JUnit-related question
and answer, then send the unformatted text
to
<a href="mailto:mike@clarkware.com">
Mike Clark</a>.
Corrections to this FAQ are always appreciated, as well.</p>
<p>No reasonable contribution will be denied. Your name will
always appear along with any contribution you make.</p>
</answer>
</faq>
<faq id="faqinfo_3">
<question>Where do I get the latest version of this
FAQ?</question>
<answer>
<p>The latest copy of this FAQ is available
at
<a href="https://junit.org/junit4/faq.html">
https://junit.org/junit4/faq.html</a>.</p>
<p>The JUnit distribution also includes this FAQ in
the
<code>
doc</code>directory.</p>
</answer>
</faq>
</part>
<part id="overview">
<title>Overview</title>
<faq id="overview_1"><question>What is JUnit?</question>
<answer><p>
JUnit is a simple, open source framework to write and run
repeatable tests. It is an instance of the xUnit architecture
for unit testing frameworks. JUnit features include:
</p>
<ul>
<li>Assertions for testing expected results</li>
<li>Test fixtures for sharing common test data</li>
<li>Test runners for running tests</li>
</ul>
<p>
JUnit was originally written by Erich Gamma and Kent Beck.
</p>
</answer>
</faq>
<faq id="overview_2"><question>Where is the JUnit home page?</question>
<answer>
<p>
The official JUnit home page is <a
href="http://junit.org">http://junit.org</a>.
</p>
</answer>
</faq>
<faq id="overview_3"><question>Where are the JUnit mailing lists and
forums?</question>
<answer>
<p>
There are 3 mailing lists dedicated to everything JUnit:
</p>
<ul>
<li>
<a href="http://groups.yahoo.com/group/junit/">JUnit user
list</a>. (Search it for answers to frequently asked
questions not included here.)
</li>
<li>
<a
href="http://lists.sourceforge.net/lists/listinfo/junit-announce">JUnit
announcements</a>
</li>
<li>
<a
href="http://lists.sourceforge.net/lists/listinfo/junit-devel">JUnit
developer list</a>
</li>
</ul>
</answer>
</faq>
<faq id="overview_4"><question>Where is the JUnit
documentation?</question>
<answer>
<p>
The following documents are included in the JUnit distribution
in the <code>doc</code> directory:
</p>
<ul>
<li>
<a
href="http://junit.sourceforge.net/doc/testinfected/testing.htm">JUnit
Test Infected: Programmers Love Writing Tests</a>
</li>
<li>
<a
href="http://junit.sourceforge.net/doc/cookbook/cookbook.htm">JUnit
Cookbook</a>
</li>
<li>
<a
href="http://junit.sourceforge.net/doc/cookstour/cookstour.htm">JUnit
- A Cook's Tour</a>
</li>
<li>
<a href="http://junit.sourceforge.net/doc/faq/faq.htm">JUnit
FAQ</a>
</li>
</ul>
</answer>
</faq>
<faq id="overview_7"><question>How is JUnit licensed?</question>
<answer>
<p>
JUnit is <a href="http://www.opensource.org/">Open Source
Software</a>, released
under the <a
href="http://opensource.org/licenses/eclipse-1.0.html">
Eclipse Public License Version 1.0</a> and hosted
on <a
href="http://sourceforge.net/projects/junit/">SourceForge</a>.
</p>
</answer>
</faq>
<faq id="overview_8"><question>What awards has JUnit won?</question>
<answer>
<ul>
<li>
<p> <a
href="http://www.javaworld.com/javaworld/jw-03-2002/jw-0326-awards.html">2002
JavaWorld Editors' Choice Awards (ECA)</a>
</p>
<p>
Best Java Performance Monitoring/Testing Tool
</p>
</li>
<li>
<p>
<a
href="http://www.javaworld.com/javaworld/jw-06-2001/j1-01-awards.html">2001
JavaWorld Editors' Choice Awards (ECA)</a>
</p>
<p>
Best Java Performance Monitoring/Testing Tool
</p>
</li>
</ul>
</answer>
</faq>
</part>
<part id="started">
<title>Getting Started</title>
<faq id="started_1">
<question>Where do I download JUnit?</question>
<answer><p>
The latest version of JUnit is available
on <a
href="http://sourceforge.net/project/showfiles.php?group_id=15278">SourceForge</a>.
</p></answer>
</faq>
<faq id="started_2">
<question>How do I install JUnit?</question>
<answer><ol>
<li>
<p>
First, <a
href="http://sourceforge.net/project/showfiles.php?group_id=15278">download</a>
the
latest version of JUnit, referred to below
as <code>junit.zip</code>.
</p>
</li>
<li>
<p>
Then install JUnit on your platform of choice:
</p>
<p>
<u>Windows</u>
</p>
<p>
To install JUnit on Windows, follow these steps:
</p>
<ol>
<li>
<p>
Unzip the <code>junit.zip</code> distribution file to
a directory referred to as <code>%JUNIT_HOME%</code>.
</p>
</li>
<li>Add JUnit to the classpath:
<p>
<code>set CLASSPATH=%CLASSPATH%;%JUNIT_HOME%\junit.jar</code>
</p>
</li>
</ol>
<p>
<u>Unix (bash)</u>
</p>
<p>
To install JUnit on Unix, follow these steps:
</p>
<ol>
<li>
<p>
Unzip the <code>junit.zip</code> distribution file to
a directory referred to as <code>$JUNIT_HOME</code>.
</p>
</li>
<li>
<p>
Add JUnit to the classpath:
</p>
<p>
<code>export CLASSPATH=$CLASSPATH:$JUNIT_HOME/junit.jar</code>
</p>
</li>
</ol>
</li>
<li>
<p>
<i>(Optional)</i> Unzip
the <code>$JUNIT_HOME/src.jar</code> file.
</p>
</li>
<li>
<p>
Test the installation by running the sample tests
distributed with JUnit. Note that the sample tests are
located in the installation directory directly, not
the <code>junit.jar</code> file. Therefore, make sure that
the JUnit installation directory is on your CLASSPATH. Then
simply type:
</p>
<pre>java org.junit.runner.JUnitCore org.junit.tests.AllTests</pre>
<p>
All the tests should pass with an "OK" message.
</p>
<p>
<i>
If the tests don't pass, verify
that <code>junit.jar</code> is in the CLASSPATH.
</i>
</p>
</li>
<li>
<p>
Finally, <a href="#overview_4">read</a> the documentation.
</p>
</li>
</ol></answer>
</faq>
<faq id="started_3">
<question>How do I uninstall JUnit?</question>
<answer><ol>
<li>
<p>
Delete the directory structure where you unzipped the JUnit
distribution.
</p>
</li>
<li>
<p>
Remove <code>junit.jar</code> from the CLASSPATH.
</p>
</li>
</ol>
<p>
JUnit does not modify the registry so simply removing all the
files will fully uninstall it.
</p></answer>
</faq>
<faq id="started_4">
<question>How do I ask questions?</question>
<answer><p>
Questions that are not answered in
the <a
href="http://junit.sourceforge.net/doc/faq/faq.htm">FAQ</a> or
in the <a href="#overview_4">documentation</a> should be posted
to
the <a
href="http://www.jguru.com/forums/home.jsp?topic=JUnit">jGuru
discussion forum</a> or the <a
href="http://groups.yahoo.com/group/junit/">JUnit user mailing
list</a>.
</p>
<p>
Please stick to technical issues on the discussion forum and
mailing lists. Keep in mind that these are public, so
do <b>not</b> include any confidential information in your
questions!
</p>
<p>
You should also
read <a
href="http://www.catb.org/~esr/faqs/smart-questions.html">"How
to ask questions the smart way"</a> by Eric Raymond before
participating in the discussion forum and mailing lists.
</p>
<p>
<i>
NOTE: <br/> Please do NOT submit bugs, patches, or feature
requests to the discussion forum or mailing lists. <br/>
Refer instead to <a href="#started_5">"How do I submit bugs,
patches, or feature requests?"</a>.
</i>
</p></answer>
</faq>
<faq id="started_5">
<question>How do I submit bugs, patches, or
feature requests?</question>
<answer> <p>
JUnit celebrates programmers testing their own software. In this
spirit, bugs, patches, and feature requests that include JUnit
tests have a better chance of being addressed than those
without.
</p>
<p>
JUnit is hosted
on <a
href="https://github.com/junit-team/junit4">GitHub</a>.
Please use the tools provided by GitHub for your
submissions.
</p>
</answer>
</faq>
</part>
<part id="tests">
<title>Writing Tests</title>
<faq id="#tests_1"><question>How do I write and run a simple test?</question><answer> <ol>
<li>
<p>
Create a class:
</p>
<pre class="prettyprint linenums">package junitfaq;
import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;
public class SimpleTest {</pre>
</li>
<li>
<p>
Write a test method (annotated with <code>@Test</code>) that
asserts expected results on the object under test:
</p>
<pre class="prettyprint linenums"> @Test
public void testEmptyCollection() {
Collection collection = new ArrayList();
assertTrue(collection.isEmpty());
}</pre>
</li>
<li>
<p>
If you are running your JUnit 4 tests with a JUnit 3.x runner,
write a <code>suite()</code> method that uses the
<code>JUnit4TestAdapter</code> class to create a suite
containing all of your test methods:
</p>
<pre class="prettyprint linenums"> public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(SimpleTest.class);
}</pre>
</li>
<li>
<p>
Although writing a <code>main()</code> method to run the
test is much less important with the advent of IDE runners,
it's still possible:
</p>
<pre class="prettyprint linenums"> public static void main(String args[]) {
org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");
}
}</pre>
</li>
<li>
<p>
Run the test:
</p>
<ul>
<li>
<p>
To run the test from the console, type:
</p>
<pre>java org.junit.runner.JUnitCore junitfaq.SimpleTest</pre>
</li>
<li>
<p>
To run the test with the test runner used
in <code>main()</code>, type:
</p>
<pre>java junitfaq.SimpleTest</pre>
</li>
</ul>
<p>
The passing test results in the following textual output:
</p>
<pre>.
Time: 0
OK (1 tests)</pre>
</li>
</ol>
</answer></faq>
<faq id="#tests_2"><question>How do I use a test fixture?</question><answer><p>
<i>(Submitted by: Jeff Nielsen)</i>
</p>
<p>
A test fixture is useful if you have two or more tests for a
common set of objects. Using a test fixture avoids duplicating
the code necessary to initialize (and cleanup) the common
objects.
</p>
<p>
Tests can use the objects (variables) in a test fixture, with
each test invoking different methods on objects in the fixture
and asserting different expected results. Each test runs in its
own test fixture to isolate tests from the changes made by other
tests. That is, <em>tests don't share the state of objects in
the test fixture</em>. Because the tests are isolated, they can
be run in any order.
</p>
<p>
To create a test fixture, declare instance variables for the
common objects. Initialize these objects in a <code>public
void</code> method annotated with <code>@Before</code>. The
JUnit framework automatically invokes any <code>@Before</code>
methods before each test is run.
</p>
<p>
The following example shows a test fixture with a common
<code>Collection</code> object.
</p>
<pre class="prettyprint linenums">package junitfaq;
import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;
public class SimpleTest {
private Collection<Object> collection;
@Before
public void setUp() {
collection = new ArrayList<Object>();
}
@Test
public void testEmptyCollection() {
assertTrue(collection.isEmpty());
}
@Test
public void testOneItemCollection() {
collection.add("itemA");
assertEquals(1, collection.size());
}
}</pre>
<p>
Given this test, the methods might execute in the following
order:
</p>
<pre class="prettyprint linenums">setUp()
testEmptyCollection()
setUp()
testOneItemCollection()</pre>
<p>
The ordering of test-method invocations is not guaranteed, so
<code>testOneItemCollection()</code> might be executed before
<code>testEmptyCollection()</code>. But it doesn't matter,
because each method gets its own instance of the
<code>collection</code>.
</p>
<p>
Although JUnit provides a new instance of the fixture objects
for each test method, if you allocate any <em>external</em>
resources in a <code>@Before</code> method, you should release
them after the test runs by annotating a method with
<code>@After</code>. The JUnit framework automatically invokes
any <code>@After</code> methods after each test is run. For
example:
</p>
<pre class="prettyprint linenums">package junitfaq;
import org.junit.*;
import static org.junit.Assert.*;
import java.io.*;
public class OutputTest {
private File output;
@Before
public void createOutputFile() {
output = new File(...);
}
@After
public void deleteOutputFile() {
output.delete();
}
@Test
public void testSomethingWithFile() {
...
}
}</pre>
<p>
With this test, the methods will execute in the following order:
</p>
<pre class="prettyprint linenums">
createOutputFile()
testSomethingWithFile()
deleteOutputFile()</pre></answer></faq>
<faq id="#tests_4"><question>How do I test a method that doesn't
return anything?</question><answer><p>
<i>(Submitted by: Dave Astels)</i>
</p>
<p>
Often if a method doesn't return a value, it will have some side
effect. Actually, if it doesn't return a value AND doesn't have
a side effect, it isn't doing anything.
</p>
<p>
There may be a way to verify that the side effect actually
occurred as expected. For example, consider
the <code>add()</code> method in the Collection classes. There
are ways of verifying that the side effect happened (i.e. the
object was added). You can check the size and assert that it is
what is expected:
</p>
<pre class="prettyprint linenums">
@Test
public void testCollectionAdd() {
Collection collection = new ArrayList();
assertEquals(0, collection.size());
collection.add("itemA");
assertEquals(1, collection.size());
collection.add("itemB");
assertEquals(2, collection.size());
}</pre>
<p>
Another approach is to make use of <a
href="http://www.mockobjects.com">MockObjects</a>.
</p>
<p>
A related issue is to design for testing. For example, if you
have a method that is meant to output to a file, don't pass in a
filename, or even a <code>FileWriter</code>. Instead, pass in
a <code>Writer</code>. That way you can pass in
a <code>StringWriter</code> to capture the output for testing
purposes. Then you can add a method
(e.g. <code>writeToFileNamed(String filename)</code>) to
encapsulate the <code>FileWriter</code> creation.
</p></answer></faq>
<faq id="#tests_5"><question>Under what conditions should I test get()
and set() methods?</question><answer><p>
Unit tests are intended to alleviate fear that something might
break. If you think a <code>get()</code> or <code>set()</code>
method could reasonably break, or has in fact contributed to a
defect, then by all means write a test.
</p>
<p>
In short, test until you're confident. What you choose to test
is subjective, based on your experiences and confidence level.
Remember to be practical and maximize your testing investment.
</p>
<p>
Refer also to <a href="#best_3">"How simple is 'too simple to
break'?"</a>.
</p></answer></faq>
<faq id="#tests_6"><question>Under what conditions should I not test
get() and set() methods?</question><answer><p>
<i>(Submitted by: J. B. Rainsberger)</i>
</p>
<p>
Most of the time, get/set methods just can't break, and if they
can't break, then why test them? While it is usually better to
test more, there is a definite curve of diminishing returns on
test effort versus "code coverage". Remember the maxim: "Test
until fear turns to boredom."
</p>
<p>
Assume that the <code>getX()</code> method only does "return x;"
and that the <code>setX()</code> method only does "this.x =
x;". If you write this test:
</p>
<pre class="prettyprint linenums">@Test
public void testGetSetX() {
setX(23);
assertEquals(23, getX());
}</pre>
<p>
then you are testing the equivalent of the following:
</p>
<pre class="prettyprint linenums">
@Test
public void testGetSetX() {
x = 23;
assertEquals(23, x);
}</pre>
<p>
or, if you prefer,
</p>
<pre class="prettyprint linenums">@Test
public void testGetSetX() {
assertEquals(23, 23);
}</pre>
<p>
At this point, you are testing the Java compiler, or possibly
the interpreter, and not your component or application. There is
generally no need for you to do Java's testing for them.
</p>
<p>
If you are concerned about whether a property has already been
set at the point you wish to call <code>getX()</code>, then you
want to test the constructor, and not the <code>getX()</code>
method. This kind of test is especially useful if you have
multiple constructors:
</p>
<pre class="prettyprint linenums">@Test
public void testCreate() {
assertEquals(23, new MyClass(23).getX());
}</pre>
</answer></faq>
<faq id="#tests_7"><question>How do I write a test that passes when an
expected exception is thrown?</question><answer><p>
Add the optional <code>expected</code> attribute to
the <code>@Test</code> annotation. The following is an example
test that passes when the
expected <code>IndexOutOfBoundsException</code> is raised:
</p>
<pre class="prettyprint linenums">@Test(expected=IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}</pre>
</answer></faq>
<faq id="#tests_8"><question>How do I write a test that fails when an
unexpected exception is thrown?</question><answer><p>
Declare the exception in the <code>throws</code> clause of the
test method and don't catch the exception within the test
method. Uncaught exceptions will cause the test to fail with an
error.
</p>
<p>
The following is an example test that fails when
the <code>IndexOutOfBoundsException</code> is raised:
</p>
<pre class="prettyprint linenums">@Test
public void testIndexOutOfBoundsExceptionNotRaised()
throws IndexOutOfBoundsException {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}</pre></answer></faq>
<faq id="#tests_10"><question>How do I test protected methods?</question><answer><p>
Place your tests in the same package as the classes under test.
</p>
<p>
Refer to <a href="#organize_1">"Where should I put my test
files?"</a> for examples of how to organize tests for protected
method access.
</p></answer></faq>
<faq id="#tests_11"><question>How do I test private methods?</question><answer><p>
Testing private methods may be an indication that those methods
should be moved into another class to promote reusability.
</p>
<p>
But if you must...
</p>
<p>
If you are using JDK 1.3 or higher, you can use reflection to
subvert the access control mechanism with the aid of
the <a
href="http://sourceforge.net/projects/privaccessor/">PrivilegedAccessor</a>.
For details on how to use it,
read <a
href="http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.html">this
article</a>.
</p>
<p>
If you are using JDK 1.6 or higher and you annotate your tests with @Test,
you can use <a href="http://dp4j.com">Dp4j</a> to inject reflection in your
test methods. For details on how to use it, see <a href="http://dp4j.com/testscript">
this test script</a>.
</p></answer></faq>
<faq id="#tests_12"><question>Why does JUnit only report the first
failure in a single test?</question><answer><p>
<i>(Submitted by: J. B. Rainsberger)</i>
</p>
<p>
Reporting multiple failures in a single test is generally a sign
that the test does too much, compared to what a unit test ought
to do. Usually this means either that the test is really a
functional/acceptance/customer test or, if it is a unit test,
then it is too big a unit test.
</p>
<p>
JUnit is designed to work best with a number of small tests. It
executes each test within a separate instance of the test
class. It reports failure on each test. Shared setup code is
most natural when sharing between tests. This is a design
decision that permeates JUnit, and when you decide to report
multiple failures per test, you begin to fight against
JUnit. This is not recommended.
</p>
<p>
Long tests are a design smell and indicate the likelihood of a
design problem. Kent Beck is fond of saying in this case that
"there is an opportunity to learn something about your design."
We would like to see a pattern language develop around these
problems, but it has not yet been written down.
</p>
<p>
Finally, note that a single test with multiple assertions is
isomorphic to a test case with multiple tests:
</p>
<p>
One test method, three assertions:
</p>
<pre class="prettyprint linenums">public class MyTestCase {
@Test
public void testSomething() {
// Set up for the test, manipulating local variables
assertTrue(condition1);
assertTrue(condition2);
assertTrue(condition3);
}
}</pre>
<p>
Three test methods, one assertion each:
</p>
<pre class="prettyprint linenums">
public class MyTestCase {
// Local variables become instance variables
@Before
public void setUp() {
// Set up for the test, manipulating instance variables
}
@Test
public void testCondition1() {
assertTrue(condition1);
}
@Test
public void testCondition2() {
assertTrue(condition2);
}
@Test
public void testCondition3() {
assertTrue(condition3);
}
}</pre>
<p>
The resulting tests use JUnit's natural execution and reporting
mechanism and, failure in one test does not affect the execution
of the other tests. You generally want exactly one test to fail
for any given bug, if you can manage it.
</p></answer></faq>
<faq id="#tests_13"><question>In Java 1.4, 'assert' is a
keyword. Won't this conflict with JUnit's assert()
method?</question><answer><p>
JUnit 3.7 deprecated <code>assert()</code> and replaced it
with <code>assertTrue()</code>, which works exactly the same
way.
</p>
<p>
JUnit 4 is compatible with the <code>assert</code> keyword. If
you run with the <code>-ea</code> JVM switch, assertions that
fail will be reported by JUnit.
</p></answer></faq>
<faq id="#tests_14"><question>How do I test things that must be run in
a J2EE container (e.g. servlets, EJBs)?</question><answer><p>
Refactoring J2EE components to delegate functionality to other
objects that don't have to be run in a J2EE container will
improve the design and testability of the software.
</p>
<p>
<a href="http://jakarta.apache.org/cactus/index.html">Cactus</a>
is an open source JUnit extension that can be used to test J2EE
components in their natural environment.
</p></answer></faq>
<faq id="#tests_15"><question>Do I need to write a test class for
every class I need to test?</question><answer><p>
<i>(Submitted by: J. B. Rainsberger)</i>
</p>
<p>
No. It is a convention to start with one test
class per class under test, but it is not necessary.
</p>
<p>
Test classes only provide a way to organize tests, nothing more.
Generally you will start with one test class per class under
test, but then you may find that a small group of tests belong
together with their own common test fixture.[1] In this case,
you may move those tests to a new test class. This is a simple
object-oriented refactoring: separating responsibilities of an
object that does too much.
</p>
<p>
Another point to consider is that the <code>TestSuite</code> is
the smallest execution unit in JUnit: you cannot execute
anything smaller than a TestSuite at one time without changing
source code. In this case, you probably do not want to put tests
in the same test class unless they somehow "belong together".
If you have two groups of tests that you think you'd like to
execute separately from one another, it is wise to place them in
separate test classes.
</p>
<p>
<i>
[1] A test fixture is a common set of test data and
collaborating objects shared by many tests. Generally they are
implemented as instance variables in the test class.
</i>
</p></answer></faq>
<faq id="#tests_16"><question>Is there a basic template I can use to
create a test?</question><answer><p>
<i>(Submitted by: Eric Armstrong)</i>
</p>
<p>
The following templates are a good starting point. Copy/paste
and edit these templates to suit your coding style.
</p>
<p>
SampleTest is a basic test template:
</p>
<pre class="prettyprint linenums">import org.junit.*;
import static org.junit.Assert.*;
public class SampleTest {
private java.util.List emptyList;
/**
* Sets up the test fixture.
* (Called before every test case method.)
*/
@Before
public void setUp() {
emptyList = new java.util.ArrayList();
}
/**
* Tears down the test fixture.
* (Called after every test case method.)
*/
@After
public void tearDown() {
emptyList = null;
}
@Test
public void testSomeBehavior() {
assertEquals("Empty list should have 0 elements", 0, emptyList.size());
}
@Test(expected=IndexOutOfBoundsException.class)
public void testForException() {
Object o = emptyList.get(0);
}
}</pre></answer></faq>
<faq id="#tests_17"><question>How do I write a test for an abstract
class?</question><answer><p>
Refer to <a
href="http://c2.com/cgi/wiki?AbstractTestCases">http://c2.com/cgi/wiki?AbstractTestCases</a>.
</p></answer></faq>
<faq id="#tests_18"><question>When are tests garbage collected?</question><answer><p>
<i>(Submitted by: Timothy Wall and Kent Beck)</i>
</p>
<p>
By design, the tree of Test instances is built in one pass, then
the tests are executed in a second pass. The test runner holds
strong references to all Test instances for the duration of the
test execution. This means that for a very long test run with
many Test instances, none of the tests may be garbage collected
until the end of the entire test run.
</p>
<p>
Therefore, if you allocate external or limited resources in a
test, you are responsible for freeing those resources.
Explicitly setting an object to <code>null</code> in
the <code>tearDown()</code> method, for example, allows it to be
garbage collected before the end of the entire test run.
</p></answer></faq>
</part>
<part id="organize">
<title>Organizing Tests</title>
<faq id="organize_1">
<question>Where should I put my test files?</question>
<answer><p>
You can place your tests in the same package and directory as
the classes under test.
</p>
<p>
For example:
</p>
<pre>src
com
xyz
SomeClass.java
SomeClassTest.java</pre>
<p>
While adequate for small projects, many developers feel that
this approach clutters the source directory, and makes it hard
to package up client deliverables without also including
unwanted test code, or writing unnecessarily complex packaging
tasks.
</p>
<p>
An arguably better way is to place the tests in a separate
parallel directory structure with package alignment.
</p>
<p>
For example:
</p>
<pre>src
com
xyz
SomeClass.java
test
com
xyz
SomeClassTest.java</pre>
<p>
These approaches allow the tests to access to all the public and
package visible methods of the classes under test.
</p>
<p>
Some developers have argued in favor of putting the tests in a
sub-package of the classes under test (e.g. com.xyz.test). The
author of this FAQ sees no clear advantage to adopting this
approach and believes that said developers also put their curly
braces on the wrong line. :-)
</p></answer>
</faq>
<faq id="organize_3">
<question>How can I run setUp() and tearDown()
code once for all of my tests?</question>
<answer><p>
The desire to do this is usually a symptom of excessive coupling
in your design. If two or more tests must share the same test
fixture state, then the tests may be trying to tell you that the
classes under test have some undesirable dependencies.
</p>
<p>
Refactoring the design to further decouple the classes under
test and eliminate code duplication is usually a better
investment than setting up a shared test fixture.
</p>
<p>
But if you must...
</p>
<p>
You can add a <code>@BeforeClass</code> annotation to a method
to be run before all the tests in a class, and
a <code>@AfterClass</code> annotation to a method to be run
after all the tests in a class. Here's an example:
</p>
<pre class="prettyprint linenums">package junitfaq;
import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;
public class SimpleTest {
private Collection collection;
@BeforeClass
public static void oneTimeSetUp() {