CPSC 329 Software Development Fall 2026

CPSC 329 Lab 2: Testing and Debugging

This lab introduces some tools for testing and debugging, including JUnit, the Eclipse debugger, assertions, and Java's built-in logging. It also reinforces incorporating version control into the regular workflow.

Collaboration and AI

Labs are for learning and practice — you may help and be helped by others when it comes to figuring out what to do, but in the end you need to understand and be able to do the things for yourself.

You may not use AI to figure out what to do or to do the task for you.

Due Date, Deliverables, and Handin

due Fri 9/11 at the start of class

To hand in your work:


Preliminaries

Provided Code

You've been provided with a partial implementation of a Klondike Solitaire game, following the class organization discussed in class.

Setup


Testing: JUnit

In this part you'll practice a tests-early approach to development and learn how to use JUnit to implement and run tests.

Constructor and isEmpty

Start with two core methods of TableauColumn: the constructor and isEmpty:

There are three behaviors to test: that the constructor creates an empty column, that isEmpty() returns true when there are no cards, and that isEmpty() returns false when there are cards.

Both isEmpty() and the constructor are high-risk if they are wrong (everything depends on the constructor and many things, including many tests themselves, depend on isEmpty but low-risk for actual bugs since their bodies are very short and simple. We'll review isEmpty() directly but write a test for the constructor to help catch potential initialization errors.

The following test covers the constructor's behavior:

test namedescriptionstarting stateinputexpected result
newColumnIsEmpty a freshly constructed column has no cards isEmpty() returns true

Tests should be implemented separately from the code being tested — tests aren't part of the final production version, and testing shouldn't modify the code being tested. All of the tests for a given class typically go into a single class, which JUnit confusingly calls a "test case" (even though there are actually many different cases being tested).

Set up a new test case:

You should now see the new class TableauColumnTest with a placeholder for the constructor test.

The JUnit dashboard will pop up showing the status of each test case it completes.

To implement a test, replace the default fail("not yet implemented") with a body that does the three basic steps of a test: set up the starting state, do the operation being tested, and compared what actually happened to the expected result.

testTableauColumn should now pass — it if doesn't, fix the bug (in the constructor) and run the test again to ensure it passes.

place(Card)

The following tests cover place(Card)'s behavior — the typical operation of adding a card to a non-empty column and the special case of adding a card to an empty column:

test namedescriptionstarting stateinputexpected result
placeOnNonEmpty placing a card adds it to the top of the column column with (just) a face-up red 8 place black 7 black 7 is now on top; the column contains two cards
placeOnEmpty placing a card on an empty column empty column place red king red king is now on top; the column contains one card

For each test:

Then:

canPlace(Card)

The following tests cover canPlace(Card)'s behavior — the typical operation of adding a card to a non-empty column and the special case of adding a card to an empty column:

test namedescriptionstarting stateinputexpected result
canPlaceLegalOnTop check a legal card on a non-empty column column with (just) a face-up red 8 check black 7 returns true
canPlaceLegalOnEmpty check a legal card on an empty column empty column check red king returns true
canPlaceIllegalOnTopSameColor check an illegal card (color) on a non-empty column column with (just) a face-up red 8 check red 7 returns false
canPlaceIllegalOnTopWrongRank check an illegal card (rank) on a non-empty column column with (just) a face-up red 8 check black 5 returns false
canPlaceIllegalOnEmpty check an illegal card on an empty column empty column check black 7 returns false

Implement and test canPlace(Card):

Checkpoint


Finding Bugs: Eclipse Debugger

In this part you will use the Eclipse debugger to locate bugs in pickUp()/pickUp(n). A set of tests for these methods has been implemented for you.

Debug:

Checkpoint


Assertions and Logging


Stubs/Fakes


Integration Test