Iteration 6: Compositional Design and Test Spy

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

The learning goals are Private Interfaces, Test Spy and again the compositional design principles.

Prerequisites

Carefully read FRS § 37.5 which outlines the Interface-Segregation-Principle and private/role interface refactoring, and the new EtaStone and SemiStone (and optionally ThetaStone) variants. FRS 2nd Edition §15.8 and §15.9 provides the theory you need.

Kata

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

... Private Interface

Briefly read the FRS's §37.5 about a MutableGame private interface, in order to addresse the following Kata...

... UnitTesting Card Effects

We need to TDD that a card effect like Brown Rice: "Deal 1 damage to opponent hero" works correctly. We can do this either by unit testing the effect or integration testing the effect. Unit testing means "in isolation" while integration testing means "in collaboration".

Thus integration testing the Brown Rice effect would follow a GWT like:

          GIVEN a Game with Peddersen Hero health equal to 21
          WHEN Findus plays the Brown Rice Card to the field
          THEN Peddersen's hero's health is 20
        
That is - both the card, its effect strategy, the game object, and the hero object are all required to verify correct behaviour. And any defect in any of them, may make the test fail.

However, unit testing the Brown Rice effect would isolate the effect object completely, which would then amount to a GWT like:

          GIVEN the Effect object (instance of the Effect Role interface) for Brown Rice
          WHEN the 'execute(mutableGame)' method is called
          THEN the Test Spy (implementing MutableGame) has recorded that the method
          'changeHeroHealth(who, delta)' has been called with who=Peddersen, and delta=-1.
        
That is, no other object but the effect itself and a spy object is involved.

Sketch code for the unit testing approach:

  1. How does the test method for the above GWT look like?
  2. How does the setup (@BeforeEach) method look like?
  3. How is the Test Spy coded?
  4. Argue why the 'Private Interface' concept is essential to make this unit testing work.

Exercises

Private Interfaces and ISP

Refactor your HotStone code base to adhere to the Program to an Interface principle by introducing appropriately named private interfaces to handle mutation of internal game state.

Document your design as outlined in the report template.

FRS 2nd Edition §15.8 provides the theory you need, and, as a supplement, I have written this cheatsheet for private interface.

EtaStone

Note that this exercise strongly requires you to have developed a private interface for Game, as outlined in the previous exercise, to be solved correctly!

Develop EtaStone using TDD by refactoring the existing HotStone production code, and using a Test Spy to ensure card effects are Unit Tested, and not Integration Tested.

Document your card effect testing and argue for unit testing as outlined in the report template.

SemiStone

Develop the SemiStone variant: The combination of all your most playable HotStone variants. Including ThetaStone, below, is of course optional.

Document your design as outlined in the report template.

Parametric 'getWinner()'

Consider the situation that you have designed all variants using a purely parametric design . That is, all variable behaviors are controlled by if's and switches in a single large implementation of Game containing code for all the requirements.

Sketch how method 'getWinner()' would look like this if a purely parametric design had been employed as variant handling technique in the HotStone code.

Optional: Polymorphic ZetaStone

Consider the situation that you have designed all variants using a purely polymorphic design. That is, a design in which variants are created by subclassing the original AlphaStone implementation, like shown below:


For instance, the BetaStone winning algorithm would be handled by overriding the getWinner() method in class AlphaStone, etc.

  1. Sketch a design proposal for how to implement ZetaStone based upon a purely polymorphic design, by drawing a UML diagram of the interfaces and classes involved. You may only consider a design in a language that does not support multiple implementation inheritance, like Java.
  2. Sketch how the actual getWinner() method implementation in the ZetaStone subclass would look like in (pseudo) code.

Optional: ThetaStone

Develop ThetaStone using TDD and by generalizing/extending your HotStone production code. Be sure to use a role interface for Categories.

This is purely an optional exercise, for 'fun' and improved game play.

Deliveries:

  1. Develop on a feature branch named "iteration6" and release using a merge request.
  2. You should document your group's work using the iteration 6 report template (pdf) (LaTeX source)

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 6 Grade sheet to evaluate your submission.

Learning Goal Assessment parameters
Submission Git repository contains merge request associated with "iteration6". Git repository is not public! Required artifacts (report following the template) are present.
Private Interfaces The report clearly and concisely describes the new design of card, hero, game using private interfaces. Casting to concrete classes/declaring datastructures by concrete classes have been removed. The code base and code examples correctly reflect introducing private interfaces.
EtaStone Design The EtaStone/card effect is designed and coded using a compositional/3-1-2 approach. The design uses a Role Interface. The design is clearly and correctly documented in the report.
Unit Testing via Test Spy The card effects of EtaStone is TDD/tested by unit testing and a test spy.
SemiStone The report clearly and concisely describes the SemiStone configuration table and configuration code. The compositional design principles are correctly applied in the code base to support all variants and in particular support the multi-variance SemiStone. There are no source-code-copy, parametric, or polymorphic based variant handling code. The 'variant to use' code is localized in the ConcreteFactory for each variant.
Parametric Analysis The report clearly and concisely presents a correct solutions to the parametric 'getWinner()' through correct (pseudo) code fragments.
TDD and Clean Code TDD process has been applied. Test code and Production code keeps obeying the criteria set forth in the previous iterations, including adhering to Clean Code properties for newly developed code. Missing features are noted in the backlog (ThetaStone features allowed there (permanently)).