|
|
@@ -74,72 +74,104 @@ running the task you asked it to: executing the tests against the solution.
|
|
74
|
74
|
```
|
|
75
|
75
|
:test
|
|
76
|
76
|
|
|
|
77
|
+HelloWorldTest > helloSampleName FAILED
|
|
|
78
|
+ java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
|
|
|
79
|
+ at HelloWorld.hello(HelloWorld.java:3)
|
|
|
80
|
+ at HelloWorldTest.helloSampleName(HelloWorldTest.java:22)
|
|
|
81
|
+
|
|
77
|
82
|
HelloWorldTest > helloNoName FAILED
|
|
78
|
|
- java.lang.AssertionError: expected:<Hello, World!> but was:<null>
|
|
79
|
|
- at org.junit.Assert.fail(Assert.java:93)
|
|
80
|
|
- at org.junit.Assert.failNotEquals(Assert.java:647)
|
|
81
|
|
- at org.junit.Assert.assertEquals(Assert.java:128)
|
|
82
|
|
- at org.junit.Assert.assertEquals(Assert.java:147)
|
|
83
|
|
- at HelloWorldTest.helloNoName(HelloWorldTest.java:10)
|
|
|
83
|
+ java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
|
|
|
84
|
+ at HelloWorld.hello(HelloWorld.java:3)
|
|
|
85
|
+ at HelloWorldTest.helloNoName(HelloWorldTest.java:11)
|
|
84
|
86
|
|
|
85
|
|
-HelloWorldTest > helloSampleName SKIPPED
|
|
|
87
|
+HelloWorldTest > emptyStringIsComparedByValue FAILED
|
|
|
88
|
+ java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
|
|
|
89
|
+ at HelloWorld.hello(HelloWorld.java:3)
|
|
|
90
|
+ at HelloWorldTest.emptyStringIsComparedByValue(HelloWorldTest.java:17)
|
|
86
|
91
|
|
|
87
|
|
-HelloWorldTest > helloAnotherSampleName SKIPPED
|
|
|
92
|
+HelloWorldTest > helloAnotherSampleName FAILED
|
|
|
93
|
+ java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
|
|
|
94
|
+ at HelloWorld.hello(HelloWorld.java:3)
|
|
|
95
|
+ at HelloWorldTest.helloAnotherSampleName(HelloWorldTest.java:27)
|
|
88
|
96
|
|
|
89
|
|
-3 tests completed, 1 failed, 2 skipped
|
|
|
97
|
+4 tests completed, 4 failed
|
|
90
|
98
|
:test FAILED
|
|
91
|
99
|
|
|
92
|
100
|
FAILURE: Build failed with an exception.
|
|
93
|
101
|
|
|
94
|
102
|
* What went wrong:
|
|
95
|
103
|
Execution failed for task ':test'.
|
|
96
|
|
-> There were failing tests. See the report at: file:///Users/jtigger/projects/exercism/java/build/exercism/java/hello-world/build/reports/tests/index.html
|
|
|
104
|
+> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
|
|
97
|
105
|
|
|
98
|
106
|
* Try:
|
|
99
|
107
|
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
|
|
100
|
108
|
|
|
101
|
109
|
BUILD FAILED
|
|
102
|
110
|
|
|
103
|
|
-Total time: 6.716 secs
|
|
|
111
|
+Total time: 12.361 secs
|
|
104
|
112
|
```
|
|
105
|
113
|
|
|
106
|
114
|
Seeing the word "fail" TEN TIMES might give you the impression you've done
|
|
107
|
115
|
something horribly wrong. You haven't. It's a whole lot of noise over
|
|
108
|
|
-a single test not passing.
|
|
|
116
|
+a few tests not passing.
|
|
109
|
117
|
|
|
110
|
118
|
Let's focus in on the important bits:
|
|
111
|
119
|
|
|
112
|
120
|
```
|
|
113
|
|
-HelloWorldTest > helloNoName FAILED
|
|
114
|
|
- java.lang.AssertionError: expected:<Hello, World!> but was:<null>
|
|
|
121
|
+HelloWorldTest > helloSampleName FAILED
|
|
|
122
|
+ java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
|
|
115
|
123
|
```
|
|
116
|
124
|
|
|
117
|
125
|
...is read: "Within the test class named `HelloWorldTest`, the test method
|
|
118
|
|
-`helloNoName` did not pass because the solution did not satisfy an
|
|
119
|
|
-assertion. Apparently, we expected to see the string 'Hello, World!' but
|
|
120
|
|
-the value `null` was returned instead.
|
|
|
126
|
+`helloSampleName` did not pass because an `UnsupportedOperationException` was thrown with the message
|
|
|
127
|
+`Delete this statement and write your own implementation.`."
|
|
121
|
128
|
|
|
122
|
|
-The last line of the stack trace tells us exactly where this unsatisfied
|
|
123
|
|
-assertion lives:
|
|
|
129
|
+The next line of the stack trace tells us where the exception was thrown:
|
|
124
|
130
|
|
|
125
|
131
|
```
|
|
126
|
|
- at HelloWorldTest.helloNoName(HelloWorldTest.java:10)
|
|
|
132
|
+ at HelloWorld.hello(HelloWorld.java:3)
|
|
127
|
133
|
```
|
|
128
|
134
|
|
|
|
135
|
+Looks like it was on line 3 in the HelloWorld file.
|
|
|
136
|
+
|
|
|
137
|
+We should remove this line from our `HelloWorld.java` file.
|
|
|
138
|
+
|
|
|
139
|
+In your favorite text editor, open `src/main/java/HelloWorld.java`.
|
|
|
140
|
+
|
|
|
141
|
+Delete the contents of that line and replace it with the following:
|
|
|
142
|
+```java
|
|
|
143
|
+return null;
|
|
|
144
|
+```
|
|
|
145
|
+Now you can run `gradle test` again.
|
|
|
146
|
+
|
|
|
147
|
+You should see a new error this time, don't worry though, you're making progress.
|
|
|
148
|
+
|
|
|
149
|
+```
|
|
|
150
|
+HelloWorldTest > helloNoName FAILED
|
|
|
151
|
+ java.lang.AssertionError: expected:<Hello, World!> but was:<null>
|
|
|
152
|
+```
|
|
|
153
|
+...is read: "Within the test class named HelloWorldTest,
|
|
|
154
|
+the test method helloNoName did not pass because the solution did not satisfy an assertion.
|
|
|
155
|
+Apparently, we expected to see the string 'Hello, World!' but the value null was returned instead.
|
|
|
156
|
+
|
|
|
157
|
+The last line of the stack trace tells us exactly where this unsatisfied assertion lives:
|
|
|
158
|
+
|
|
|
159
|
+```
|
|
|
160
|
+ at HelloWorldTest.helloNoName(HelloWorldTest.java:10)
|
|
|
161
|
+```
|
|
129
|
162
|
Looks like the crime was discovered on line 10 in the test file.
|
|
130
|
163
|
|
|
131
|
164
|
Knowing these two facts,
|
|
132
|
165
|
|
|
133
|
|
-1. the return value was not what was expected, and
|
|
134
|
|
-2. the failure was on line 10 of the test,
|
|
135
|
|
-
|
|
136
|
|
-we can turn this failure into success.
|
|
|
166
|
+1. The return value was not what was expected, and
|
|
|
167
|
+2. The failure was on line 10 of the test,
|
|
137
|
168
|
|
|
|
169
|
+We can turn this failure into success.
|
|
138
|
170
|
|
|
139
|
171
|
|
|
140
|
|
-## Fixing the first failing test
|
|
|
172
|
+## Fixing the first test
|
|
141
|
173
|
|
|
142
|
|
-In your favorite text editor, open `src/test/java/HelloWorldTest.java`
|
|
|
174
|
+Open `src/test/java/HelloWorldTest.java`
|
|
143
|
175
|
and go to line 10.
|
|
144
|
176
|
|
|
145
|
177
|
```java
|
|
|
@@ -182,88 +214,50 @@ $ gradle test
|
|
182
|
214
|
:testClasses
|
|
183
|
215
|
:test
|
|
184
|
216
|
|
|
185
|
|
-HelloWorldTest > helloAnotherSampleName SKIPPED
|
|
|
217
|
+HelloWorldTest > helloSampleName FAILED
|
|
|
218
|
+ org.junit.ComparisonFailure: expected:<Hello, [Alice]!> but was:<Hello, [World]!>
|
|
|
219
|
+ at org.junit.Assert.assertEquals(Assert.java:115)
|
|
|
220
|
+ at org.junit.Assert.assertEquals(Assert.java:144)
|
|
|
221
|
+ at HelloWorldTest.helloSampleName(HelloWorldTest.java:22)
|
|
186
|
222
|
|
|
187
|
223
|
HelloWorldTest > helloNoName PASSED
|
|
188
|
224
|
|
|
189
|
|
-HelloWorldTest > helloSampleName SKIPPED
|
|
190
|
|
-
|
|
191
|
|
-BUILD SUCCESSFUL
|
|
|
225
|
+HelloWorldTest > emptyStringIsComparedByValue PASSED
|
|
192
|
226
|
|
|
193
|
|
-Total time: 4.523 secs
|
|
194
|
|
-```
|
|
195
|
|
-
|
|
196
|
|
-"BUILD SUCCESSFUL"! Woohoo! :) You can see that `helloNoName()` test is
|
|
197
|
|
-now passing.
|
|
|
227
|
+HelloWorldTest > helloAnotherSampleName FAILED
|
|
|
228
|
+ org.junit.ComparisonFailure: expected:<Hello, [Bob]!> but was:<Hello, [World]!>
|
|
|
229
|
+ at org.junit.Assert.assertEquals(Assert.java:115)
|
|
|
230
|
+ at org.junit.Assert.assertEquals(Assert.java:144)
|
|
|
231
|
+ at HelloWorldTest.helloAnotherSampleName(HelloWorldTest.java:27)
|
|
198
|
232
|
|
|
199
|
|
-With one win under our belt, we can turn our focus to some other messages
|
|
200
|
|
-that we've been ignoring: the lines ending in "`SKIPPED`".
|
|
201
|
|
-
|
|
202
|
|
-Each test suite contains a series of tests, all of which have been marked
|
|
203
|
|
-to be skipped/ignored except the first one. We did this to help you focus
|
|
204
|
|
-on getting one test running at a time.
|
|
205
|
|
-
|
|
206
|
|
-Let's tackle the next test...
|
|
207
|
|
-
|
|
208
|
|
-
|
|
209
|
|
-
|
|
210
|
|
-## Enabling and fixing the second test
|
|
|
233
|
+4 tests completed, 2 failed
|
|
|
234
|
+:test FAILED
|
|
211
|
235
|
|
|
212
|
|
-Right now, that second test is being skipped/ignored. Let's enable it.
|
|
|
236
|
+FAILURE: Build failed with an exception.
|
|
213
|
237
|
|
|
214
|
|
-(Re)open `src/test/java/HelloWorldTest.java` and find the second test:
|
|
|
238
|
+* What went wrong:
|
|
|
239
|
+Execution failed for task ':test'.
|
|
|
240
|
+> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
|
|
215
|
241
|
|
|
216
|
|
-```java
|
|
217
|
|
-...
|
|
218
|
|
-@Test
|
|
219
|
|
-@Ignore
|
|
220
|
|
-public void helloSampleName() {
|
|
221
|
|
- assertEquals("Hello, Alice!", HelloWorld.hello("Alice"));
|
|
222
|
|
-}
|
|
223
|
|
-...
|
|
224
|
|
-```
|
|
|
242
|
+* Try:
|
|
|
243
|
+Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
|
|
225
|
244
|
|
|
226
|
|
-When the JUnit test runner sees that `@Ignore` annotation on the test
|
|
227
|
|
-method, it knows to skip over that test. Remove that line:
|
|
|
245
|
+BUILD FAILED
|
|
228
|
246
|
|
|
229
|
|
-```java
|
|
230
|
|
-...
|
|
231
|
|
-@Test
|
|
232
|
|
-public void helloSampleName() {
|
|
233
|
|
- assertEquals("Hello, Alice!", HelloWorld.hello("Alice"));
|
|
234
|
|
-}
|
|
235
|
|
-...
|
|
|
247
|
+Total time: 20.855 secs
|
|
236
|
248
|
```
|
|
237
|
249
|
|
|
238
|
|
-Now, when you run the tests, both tests run:
|
|
239
|
|
-
|
|
240
|
|
-```sh
|
|
241
|
|
-$ gradle test
|
|
242
|
|
-...
|
|
243
|
|
-:test
|
|
244
|
|
-
|
|
245
|
|
-HelloWorldTest > helloNoName PASSED
|
|
|
250
|
+Woohoo! :) You can see that `helloNoName()` and `emptyStringIsComparedByValue()` are
|
|
|
251
|
+now passing.
|
|
246
|
252
|
|
|
247
|
|
-HelloWorldTest > helloSampleName FAILED
|
|
248
|
|
- org.junit.ComparisonFailure: expected:<Hello, [Alice]!> but was:<Hello, [World]!>
|
|
249
|
|
- at org.junit.Assert.assertEquals(Assert.java:125)
|
|
250
|
|
- at org.junit.Assert.assertEquals(Assert.java:147)
|
|
251
|
|
- at HelloWorldTest.helloSampleName(HelloWorldTest.java:16)
|
|
|
253
|
+Let's tackle the next test...
|
|
252
|
254
|
|
|
253
|
|
-HelloWorldTest > helloAnotherSampleName SKIPPED
|
|
254
|
255
|
|
|
255
|
|
-3 tests completed, 1 failed, 1 skipped
|
|
256
|
|
-...
|
|
257
|
|
-```
|
|
258
|
256
|
|
|
259
|
|
-The first test, `helloNoName()` continues to pass. We see that
|
|
260
|
|
-`helloSampleName` -- the test we just un-`@Ignore`'d -- is now running and
|
|
261
|
|
-failing. Yay, failing test! In fact, the "failure" message is just
|
|
262
|
|
-describing the difference between what the program does now and what it
|
|
263
|
|
-should do for us to call it "done."
|
|
|
257
|
+## Fixing the second test
|
|
264
|
258
|
|
|
265
|
|
-Right now, we've hardcoded the greeting. Enabling this second test has
|
|
266
|
|
-unleashed a new expectation: that our program incorporate a name given
|
|
|
259
|
+Right now, we've hardcoded the greeting. This second test has
|
|
|
260
|
+unleashed a new expectation: that our program must incorporate a name given
|
|
267
|
261
|
into that greeting. When given the name "`Alice`", that's who should be
|
|
268
|
262
|
greeted instead of "`World`".
|
|
269
|
263
|
|
|
|
@@ -295,23 +289,43 @@ public class HelloWorld {
|
|
295
|
289
|
$ gradle test
|
|
296
|
290
|
:test
|
|
297
|
291
|
|
|
298
|
|
-HelloWorldTest > helloAnotherSampleName SKIPPED
|
|
|
292
|
+HelloWorldTest > helloSampleName PASSED
|
|
299
|
293
|
|
|
300
|
294
|
HelloWorldTest > helloNoName FAILED
|
|
301
|
295
|
org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, []!>
|
|
302
|
|
- at org.junit.Assert.assertEquals(Assert.java:125)
|
|
303
|
|
- at org.junit.Assert.assertEquals(Assert.java:147)
|
|
304
|
|
- at HelloWorldTest.helloNoName(HelloWorldTest.java:10)
|
|
|
296
|
+ at org.junit.Assert.assertEquals(Assert.java:115)
|
|
|
297
|
+ at org.junit.Assert.assertEquals(Assert.java:144)
|
|
|
298
|
+ at HelloWorldTest.helloNoName(HelloWorldTest.java:11)
|
|
305
|
299
|
|
|
306
|
|
-HelloWorldTest > helloSampleName PASSED
|
|
|
300
|
+HelloWorldTest > emptyStringIsComparedByValue FAILED
|
|
|
301
|
+ org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, []!>
|
|
|
302
|
+ at org.junit.Assert.assertEquals(Assert.java:115)
|
|
|
303
|
+ at org.junit.Assert.assertEquals(Assert.java:144)
|
|
|
304
|
+ at HelloWorldTest.emptyStringIsComparedByValue(HelloWorldTest.java:17)
|
|
307
|
305
|
|
|
308
|
|
-3 tests completed, 1 failed, 1 skipped
|
|
|
306
|
+HelloWorldTest > helloAnotherSampleName PASSED
|
|
|
307
|
+
|
|
|
308
|
+4 tests completed, 2 failed
|
|
|
309
|
+:test FAILED
|
|
|
310
|
+
|
|
|
311
|
+FAILURE: Build failed with an exception.
|
|
|
312
|
+
|
|
|
313
|
+* What went wrong:
|
|
|
314
|
+Execution failed for task ':test'.
|
|
|
315
|
+> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
|
|
|
316
|
+
|
|
|
317
|
+* Try:
|
|
|
318
|
+Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
|
|
|
319
|
+
|
|
|
320
|
+BUILD FAILED
|
|
|
321
|
+
|
|
|
322
|
+Total time: 12.466 secs
|
|
309
|
323
|
```
|
|
310
|
324
|
|
|
311
|
325
|
Wait... didn't we just fix the test? Why is it failing? Take a closer look...
|
|
312
|
326
|
|
|
313
|
327
|
In fact, `helloSampleName()` *is* passing. It's just that at the same time,
|
|
314
|
|
-we just inadvertently broke that first test: `helloNoName()`.
|
|
|
328
|
+we just inadvertently broke the first tests: `helloNoName()` and `emptyStringIsComparedByValue()`.
|
|
315
|
329
|
|
|
316
|
330
|
This is one tiny example of the benefit of maintaining a test suite: if we
|
|
317
|
331
|
use them to drive out our code, the second we break the program the tests
|
|
|
@@ -319,7 +333,7 @@ say so. Since we saw them passing just *before* our latest change,
|
|
319
|
333
|
whatever we *just* did most likely cause that regression.
|
|
320
|
334
|
|
|
321
|
335
|
Our latest change was making the greeting dependent on the name given. Our
|
|
322
|
|
-first test expects that if either a blank string or null are given as the
|
|
|
336
|
+first two tests expects that if either a blank string or null are given as the
|
|
323
|
337
|
name, then "`World`" should be substituted in. Let's implement that.
|
|
324
|
338
|
|
|
325
|
339
|
`src/main/java/HelloWorld.java`:
|
|
|
@@ -341,68 +355,17 @@ $ gradle test
|
|
341
|
355
|
...
|
|
342
|
356
|
:test
|
|
343
|
357
|
|
|
344
|
|
-HelloWorldTest > helloNoName PASSED
|
|
345
|
|
-
|
|
346
|
358
|
HelloWorldTest > helloSampleName PASSED
|
|
347
|
359
|
|
|
348
|
|
-HelloWorldTest > helloAnotherSampleName SKIPPED
|
|
349
|
|
-
|
|
350
|
|
-BUILD SUCCESSFUL
|
|
351
|
|
-
|
|
352
|
|
-Total time: 4.804 secs
|
|
353
|
|
-```
|
|
354
|
|
-
|
|
355
|
|
-Excellent! We're now (at least) two-thirds the way done. Just one more
|
|
356
|
|
-test to go...
|
|
357
|
|
-
|
|
358
|
|
-
|
|
359
|
|
-
|
|
360
|
|
-## Enabling the last test
|
|
361
|
|
-
|
|
362
|
|
-(Re)open `src/test/java/HelloWorldTest.java` and find the last test:
|
|
363
|
|
-
|
|
364
|
|
-```java
|
|
365
|
|
-...
|
|
366
|
|
-@Test
|
|
367
|
|
-@Ignore
|
|
368
|
|
-public void helloAnotherSampleName() {
|
|
369
|
|
- assertEquals("Hello, Bob!", HelloWorld.hello("Bob"));
|
|
370
|
|
-}
|
|
371
|
|
-...
|
|
372
|
|
-```
|
|
373
|
|
-
|
|
374
|
|
-... and remove it's `@Ignore` to enable it ...
|
|
375
|
|
-
|
|
376
|
|
-```java
|
|
377
|
|
-...
|
|
378
|
|
-@Test
|
|
379
|
|
-public void helloAnotherSampleName() {
|
|
380
|
|
- assertEquals("Hello, Bob!", HelloWorld.hello("Bob"));
|
|
381
|
|
-}
|
|
382
|
|
-...
|
|
383
|
|
-```
|
|
384
|
|
-
|
|
385
|
|
-... and re-run the tests ...
|
|
386
|
|
-
|
|
387
|
|
-```
|
|
388
|
|
-$ gradle test
|
|
389
|
|
-:compileJava UP-TO-DATE
|
|
390
|
|
-:processResources UP-TO-DATE
|
|
391
|
|
-:classes UP-TO-DATE
|
|
392
|
|
-:compileTestJava
|
|
393
|
|
-:processTestResources UP-TO-DATE
|
|
394
|
|
-:testClasses
|
|
395
|
|
-:test
|
|
396
|
|
-
|
|
397
|
360
|
HelloWorldTest > helloNoName PASSED
|
|
398
|
361
|
|
|
399
|
|
-HelloWorldTest > helloSampleName PASSED
|
|
|
362
|
+HelloWorldTest > emptyStringIsComparedByValue PASSED
|
|
400
|
363
|
|
|
401
|
364
|
HelloWorldTest > helloAnotherSampleName PASSED
|
|
402
|
365
|
|
|
403
|
366
|
BUILD SUCCESSFUL
|
|
404
|
367
|
|
|
405
|
|
-Total time: 6.953 secs
|
|
|
368
|
+Total time: 11.717 secs
|
|
406
|
369
|
```
|
|
407
|
370
|
|
|
408
|
371
|
Oh, hello! Turns out, the solution we put into place didn't just apply for
|
|
|
@@ -476,9 +439,11 @@ We made a bunch of changes, let's make sure we didn't break the program!
|
|
476
|
439
|
```
|
|
477
|
440
|
$ gradle test
|
|
478
|
441
|
...
|
|
|
442
|
+HelloWorldTest > helloSampleName PASSED
|
|
|
443
|
+
|
|
479
|
444
|
HelloWorldTest > helloNoName PASSED
|
|
480
|
445
|
|
|
481
|
|
-HelloWorldTest > helloSampleName PASSED
|
|
|
446
|
+HelloWorldTest > emptyStringIsComparedByValue PASSED
|
|
482
|
447
|
|
|
483
|
448
|
HelloWorldTest > helloAnotherSampleName PASSED
|
|
484
|
449
|
...
|