Monday, 3 January 2022

Planning the first sprint part 1: What are we making?

Sprints in the Solo Project are split up by feature, where the sprint is finished when the feature is implemented. So what is the feature to be implemented in the first?

The core purpose of Omnihedron is selecting random items from a user-defined list, where the randomness is generated via virtual dice rolls. As such the first requirement is the ability to roll dice to generate random (or rather pseudo-random) results, seeing as the other features rely on this functionality.

Feature: The user can roll dice. ⬅ A good feature, but somewhat vague and unclear.

 There already exists structured notation for describing dice-rolls that is widely used by roleplaying games and roleplaying communities: Wikipedia: Dice Notation, as well as programming libraries able to evaluate and execute dice rolls. From both a user and developer point of view it makes sense to implement such existing familiarity and tools into Omnihedron.

Feature: The user can make dice rolls described via dice notation. ⬅ The use of dice notation can be argued to be a implementation detail, but seeing as it is user facing I'll allow it.

What kind of dice rolls should we support? If we want to make the program as widely useful as possible we should support as much of the commonly used dice notation as is possible, preferentially even a superset thereof. Most important are:

  • NdM: Where N is the number of dice and M the number of faces on those dice.
  • Mathematical Operators: Specifically +, -, /, and *.
  • Comparisons: Checking the rolled value against a given value.
  • Reroll: Reroll a die if a comparison succeeds. The ability to rerolls 1's is common in games.
  • Keep/Drop: Discard dice until N dice are left.

In all honesty, these options are taken from the library I'll be using, and as such could be considered programming to an implementation.

With that we have a feature and a series of examples of that feature, finishing the discovery phase of the BDD process.

Behaviour Driven Development

BDD is a re-implementation or expansion of Test Driven Development that is intended to be less focussed on the tests and more on the purpose of tests in the entire software development cycle. Tests in traditional TDD is heavily focussed on the programmer. The programmer decides what is tested and what the tests expect from the program.

In contrast BDD involves the rest of the software development team with deciding what is expected from the program, and how the program should behave under specific circumstances, which in turn is used to define the tests.

This is accomplished by bringing together the product owner, programmers and testers to together define requirements in a structured manner. The first part of this post is an example of the first phase: Discovery, where a feature to be worked on is selected and discussed so that the meaning, purpose and expectations from that feature are agreed upon.

When doing this on your own it is important to remember that you cannot be just the programmer and product owner, you also have to be the tester. This is something that developers find difficult, as it is our jobs to make things work, while when you are a tester your job is to break a poor programmer's hard work. And indeed, I forgot to put on a tester's hat during the above discovery.

Employing BDD should keep this from happening

So from there we have another feature:

  • Malformed dice notation should return an error message to the user.

Formulation

Once the features and examples have been decided on, the next step is to formulate them into formalized documentation. By using a formal language to describe features they are easy to understand for both humans and automated tools. The most common language used for this is Gherkin, which is designed to be human readable.

Gherkin used a Given, When, Then structure to describe scenarios, these are analogous to the Arrange, Act, Assert structure used in unit tests. Given describes the prerequisite state for starting the scenario, When indicates actions taken and Then describes the expected results.

Like all tests and related scenarios should be short and separate from the code. Don't reference buttons, commands or specific classes, but rather specify desired functionality and abstract user actions. This makes certain it does not need to change as the program changes and keeps it relevant as documentation for the program's desired functionality.

With formulation done we have a clear picture of what functionality we want to implement in the first sprint, we know the end goal and have specified clear acceptance criteria and know when the sprint is finished. In the next post I'll continue with planning the first sprint, now focusing on planning the classes themselves.

No comments:

Post a Comment

A Philosophy of Software Design - Chapter 1

 A Philosophy of Software Design is it's author's attempt to teach an often neglected core skill in software development: How to des...