Skip to content

Commit 55ba62a

Browse files
committed
Prefix test classes with the step number for better usability
1 parent 7fbed87 commit 55ba62a

8 files changed

+30
-22
lines changed

.idea/runConfigurations/All_tests.xml

+1-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,25 @@ This tutorial has been used in the [TDD programming technique and designing code
3131
The Steps of the Tutorial
3232
-------------------------
3333

34-
Use the tests in the [src/test/java/tetris](http://github.com/orfjackal/tdd-tetris-tutorial/tree/tutorial/src/test/java/tetris/) directory to write a Tetris game. Implement code to pass the tests, one file and one test at a time, in the same order as they are listed below, starting with `FallingBlocksTest.java`.
34+
Use the tests in the [src/test/java/tetris](http://github.com/orfjackal/tdd-tetris-tutorial/tree/tutorial/src/test/java/tetris/) directory to write a Tetris game. Implement code to pass the tests, one file and one test at a time, in the same order as they are listed below, starting with `FallingBlocksTest`.
3535

3636
When you first run the tests, you should see the first test (`A_new_board.is_empty`) failing. Fix the code and run the tests to see it pass. Then uncomment the following test (`A_new_board.has_no_falling_blocks`). When that test passes, uncomment the next one (`When_a_block_is_dropped.the_block_is_falling`) and make it pass, until finally you have written code which passes all tests in that class. Then open the next test class and keep on continuing in the same fashion.
3737

3838
Reference implementations for the steps of this tutorial have been [tagged in its Git repository](https://github.com/orfjackal/tdd-tetris-tutorial/tags) (the [beyond branch](http://github.com/orfjackal/tdd-tetris-tutorial/tree/beyond) contains the most complete implementation). It might be helpful to have a look at them *after* you have yourself implemented this tutorial that far. The reference implementation may teach you something about writing clean code.
3939

40-
1. **FallingBlocksTest.java**
40+
1. **FallingBlocksTest**
4141

4242
In Tetris, the most important feature is that there are blocks which fall down, so that is the first behaviour which we will specify by writing tests. It is good to start the writing of a program with a very trivial test. In this case, we will first make sure that we have an empty game board.
4343

4444
We'll use the [Simplification strategy](http://www.infoq.com/presentations/responsive-design) and first deal with just falling 1x1 blocks. We can expand that later to handle more complex multi-block pieces. It's best to avoid taking too big steps.
4545

46-
2. **RotatingPiecesOfBlocksTest.java**
46+
2. **RotatingPiecesOfBlocksTest**
4747

4848
Rotating the pieces in Tetris is also very important, so let's code that next. You might need pen and paper when figuring out how the shape coordinates change when the shape is rotated.
4949

5050
I decided to go for a generic algorithm for rotating any shapes. Another option would have been to hard-code the rotations of each shape. Both have their pros and cons. But even if this decision would prove to be bad when the game evolves furher, good test coverage and decoupled code will make it possible to change it afterwards.
5151

52-
3. **RotatingTetrominoesTest.java**
52+
3. **RotatingTetrominoesTest**
5353

5454
[Tetrominoes](http://en.wikipedia.org/wiki/Tetromino) can have 1, 2 or 4 different orientations when they are rotated. Now we can take advantage of the shape rotation code which we wrote just a moment ago.
5555

@@ -59,19 +59,19 @@ Reference implementations for the steps of this tutorial have been [tagged in it
5959

6060
If you are thinking of making the `Tetromino` class extend the `Piece` class, first read about the [Liskov Substitution Principle](http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod) to know when it's right for a class to inherit another. In general, it's best to [favor composition over inheritance](http://www.artima.com/lejava/articles/designprinciples4.html).
6161

62-
4. **FallingPiecesTest.java**
62+
4. **FallingPiecesTest**
6363

6464
Next we will connect the falling blocks and the rotatable pieces. In order to make the first test pass, you will probably need to refactor your code quite much (for me it took 1½ hours). You will need to build suitable abstractions, so that single-block pieces and multi-block pieces can be handled the same way (changing the test code should not be necessary). When refactoring, you must keep the tests passing between every small change, or you will end up in [refactoring hell](http://c2.c2.com/cgi/wiki?RefactoringHell). If more than five minutes have passed since the last time all tests passed, it's best to revert your code from source control to the last version where all tests passed.
6565

6666
The difficulty of this refactoring depends on how well factored the code is. You could even say that the difficulty of this refactoring is inversely proportional to the length of the `Board.tick()` method (if most of the logic is in that one method, instead of using [Composed Method](http://www.infoq.com/presentations/10-Ways-to-Better-Code-Neal-Ford), then you're in trouble). If you get stuck, you may get some hints from [this example refactoring](http://www.cs.helsinki.fi/u/luontola/tdd-2009/kalvot/04.1-Refactoring-Example.pdf).
6767

68-
5. **MovingAFallingPieceTest.java**
68+
5. **MovingAFallingPieceTest**
6969

7070
Now it's your turn to write the tests. I've provided some TODO items which should hint you on what tests to write.
7171

7272
Feel free to refactor the test code and change any of the previosly used class or method names to be more descriptive, because there are no more predefined tests which might become incompatible with your code. Both production code and test code need to be taken care of, so you should regularly see if there is something to improve and then refactor it.
7373

74-
6. **RotatingAFallingPieceTest.java**
74+
6. **RotatingAFallingPieceTest**
7575

7676
Keep on writing your own tests. You're getting the hang of it!
7777

src/test/java/tetris/FallingBlocksTest.java renamed to src/test/java/tetris/Step1_FallingBlocksTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Before;
10+
import org.junit.Test;
911
import org.junit.runner.RunWith;
1012

1113
/**
1214
* @author Esko Luontola
1315
*/
1416
@RunWith(NestedJUnit.class)
15-
public class FallingBlocksTest extends Assert {
17+
public class Step1_FallingBlocksTest extends Assert {
1618

1719
// Step 1: Starting small
1820
// - See the README for motivation

src/test/java/tetris/RotatingPiecesOfBlocksTest.java renamed to src/test/java/tetris/Step2_RotatingPiecesOfBlocksTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Before;
10+
import org.junit.Test;
911
import org.junit.runner.RunWith;
1012

1113
/**
1214
* @author Esko Luontola
1315
*/
1416
@RunWith(NestedJUnit.class)
15-
public class RotatingPiecesOfBlocksTest extends Assert {
17+
public class Step2_RotatingPiecesOfBlocksTest extends Assert {
1618

1719
// Step 2: Stepping stone for rotation algorithms
1820
// - Remove the @Ignore annotation from this class

src/test/java/tetris/RotatingTetrominoesTest.java renamed to src/test/java/tetris/Step3_RotatingTetrominoesTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Before;
10+
import org.junit.Test;
911
import org.junit.runner.RunWith;
1012

1113
/**
1214
* @author Esko Luontola
1315
*/
1416
@RunWith(NestedJUnit.class)
15-
public class RotatingTetrominoesTest extends Assert {
17+
public class Step3_RotatingTetrominoesTest extends Assert {
1618

1719
// Step 3: The actual rotation algorithms
1820
// - Remove the @Ignore annotation from this class

src/test/java/tetris/FallingPiecesTest.java renamed to src/test/java/tetris/Step4_FallingPiecesTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Before;
10+
import org.junit.Test;
911
import org.junit.runner.RunWith;
1012

1113
/**
1214
* @author Esko Luontola
1315
*/
1416
@RunWith(NestedJUnit.class)
15-
public class FallingPiecesTest extends Assert {
17+
public class Step4_FallingPiecesTest extends Assert {
1618

1719
// Step 4: Safe steps
1820
// - Remove the @Ignore annotation from this class

src/test/java/tetris/MovingAFallingPieceTest.java renamed to src/test/java/tetris/Step5_MovingAFallingPieceTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Ignore;
910
import org.junit.runner.RunWith;
1011

1112
@Ignore("contains no test")
1213
@RunWith(NestedJUnit.class)
13-
public class MovingAFallingPieceTest extends Assert {
14+
public class Step5_MovingAFallingPieceTest extends Assert {
1415

1516
// Step 5: It's your turn now
1617
// - Remove the @Ignore annotation from this class

src/test/java/tetris/RotatingAFallingPieceTest.java renamed to src/test/java/tetris/Step6_RotatingAFallingPieceTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
package tetris;
66

77
import net.orfjackal.nestedjunit.NestedJUnit;
8-
import org.junit.*;
8+
import org.junit.Assert;
9+
import org.junit.Ignore;
910
import org.junit.runner.RunWith;
1011

1112
@Ignore("contains no test")
1213
@RunWith(NestedJUnit.class)
13-
public class RotatingAFallingPieceTest extends Assert {
14+
public class Step6_RotatingAFallingPieceTest extends Assert {
1415

1516
// Step 6: Training wheels off
1617
// - Remove the @Ignore annotation from this class

0 commit comments

Comments
 (0)