Iteration 2: Test-Driven Development II and Git

Deadline

Always at 23.59 on the same day as your TA session (Except if another deadline has been agreed with the TA). Consult the deadline for your class on the delivery plan.

Learning Goals

Learning to use Git for release management, and continued training in TDD.

Kata

Spend the first 15-20 minutes of the class in plenum discussing...

The Card and Hero interfaces only have methods to access/read data, not to mutate/write data. The argument is of course that of 'strong encapsulation'---we do not want anyone to cheat by modifying the health value of a card.

There is, however, a problem, as a HotStone game is all about changing state as the game play progresses---getting that damn opponent hero's health to zero. That is, the object implementing Game must be able to mutate objects that represents cards and heroes. So - what to do?

We could consider:

  1. Adding mutator methods to the interfaces, ala: public interface Card { int getHealth(); void setHealth(int newValue); // ADDED }
  2. Not changing the interfaces at all, but adding mutator methods only to the implementing class, ala public interface Card { int getHealth(); } public class StandardCard implements Card { int getHealth() { return health; } void setHealth(int newValue) { health = newHealth; } }
    and then let Game declare the instances by the class type, ala
    public class StandardGame implements Game { private StandardCard[][] hand; // Just an example datastructure }
  3. Same as point 2 above, and then let Game declare the instances by the interface type, ala
    public class StandardGame implements Game { private Card[][] hand; // Just an example datastructure }
    and then do casts whenever it is necessary, ala
    StandardCard asStdCard = (StandardCard) card; asStdCard.setHealth(7);
  4. Same as point 3 above, but encapsulate the cast in a private methods, which is used instead of the cast, ala
    StandardCard asStdCard = asStandardCard(card); asStdCard.setHealth(7);

I strongly advice against option 1. Argue why option 1 is a problematic idea. Next, discuss benefits and liabilities of the other options. (And we will later in the course discuss a fifth option, which solves many of the liabilities of all these options.)

Next, consider mutating the health of a card with either of these two methods:

  1. void setHealth(int newValue); // Set to specific health
  2. void changeHealthByAmount(int delta); // Add 'delta' to health

The first method will set health to the given value 'newValue'; whereas the second method will add the given delta to the current health value, so you will normally use negative delta values ala
card.changeHealthByAmount(-2);

Given the specifications and 'feel' of HearthStone which of the two types of methods would you prefer? Argue why.

Exercises

GitLab SCM

Put AlphaStone under software configuration management control using Git and AU GitLab as repository/"origin" hosting.

Be sure to create a feature branch, named iteration2, and associated GitLab Merge Request, and make your AlphaStone (continued) TDD work happen there.

Ensure that your repository is private and that your TA is granted clone/read access ('Reporter', not only 'Guest') so they can pull your repository.

Note: Quite a lot of software engineering trickery is involved, and a lot can go wrong. Remember, that specific and detailed screencast guides are available - find the links on Weekplan 2.

TDD Part II

Continue your TDD and finish (or nearly finish) your AlphaStone implementation. (None or a few, minor, features on the backlog.) Take small steps, commit often :)

Release your AlphaStone by merging the merge request back into 'main' branch.

Deliveries:

Evaluation criteria

Your submission is evaluated against the learning goals and adherence to the submission guidelines. The grading is explained in Grading Guidelines. The TAs will use the Iteration 2 Grade sheet to evaluate your submission.

Learning Goal Assessment parameters
Submission Git repository can be pulled. Git repository is not public! Required artifacts (screencasts, backlog, repository link) must all be present. The quality of screencast (video, audio) is OK.
Git and Work flow Repository is set up correctly. Repository is clean of derived artifacts (class-files, test output, etc.). The feature branch iteration2 exists with associated merge request. Final release is merged into 'main' branch.
Git Log Commit log shows relevant activity by all group members. Commit log messages express the actual work task carried out for each commit.
TDD Process Code is written 'test-first'; TDD Rhythm is followed (and referred to in screencast); TDD Principles are applied (and referred to); TDD values are used (and referred to); code is cleaned up (and referred to). Commits in Git are made often (reflecting TDD iterations or similar small chunks of self-contained and focused work tasks).
Test Code The test code is simple (no complex constructs, basically only assignments, simple private method calls, very basic for loop). The test code reflects using the TDD principles (Isolated Test, Evident Test, Evident Data, etc.). The production code is 'well' covered by test code (JaCoCo coverage is 'green' for production code (some yellow lines allowed for branches)).
Production Code Missing features are described in the backlog! There is no Fake-it code (or it is adequately described in the backlog). The covered AlphaStone requirements are correctly implemented ('simplest interpretation' is fine in case of ambiguities; minor deviations acceptable). The production code has been 'cleaned up' to avoid duplicated code. The production code follows guide lines from Barnes and Koelling (No side effects/mutation in accessor methods; source code follows Java conventions; identifiers/names make sense for the abstractions they model; no use of 'magic constants'); no test code has been put in the 'src' tree an vice versa; there are understandable overview comments in the code).