From fresh to shared fixture #2 – a refactoring example

In the first post of this series I started with stating the intention that …

I would like to display a very simple, though instructive, example of how easy refactoring works when you have both app and test code at your disposal.

And that’s what I am going to do in this second post as I had to “elaborate on a number of concepts that I will be using” first in the previous post.

The example I am going to display is one I often make use of in my TA courses and workshops: Blocking Deletion of Warehouse Shipment Line that you can find in the Test-Automation-Examples GitHub repo and consist out of two sub features, or so-called ATDD features:

  • Unblock Deletion of Whse. Shpt. Line enabled
  • Unblock Deletion of Whse. Shpt. Line disabled

In this example I focus on the test automation part only, so, I am not going down the TDD path where test and app code evolve in sync. Here app code is already in place and test code still needs to be created. Note that whatever road I follow my test coding is always based on a test plan and test design (see chapter 5 of my book), aka as ATDD sheet, that defines the scenarios my tests should be verifying.

Test Plan and Test Design

This is how I describe a test plan in my book:

A test plan should list all possible tests that are needed to verify whether the application, or just a singular feature, is doing what it is expected to do. First of all, it should entail both the sunny scenarios, a.k.a. positive tests and often defined as user stories or use cases, and rainy scenarios, a.k.a. positive-negative tests, that is, tests that check that exceptions are handled.

For the Blocking Deletion of Warehouse Shipment Line functionality the test plan in ATDD format would be:

[FEATURE] Unblock Deletion of Whse. Shpt. Line enabled
[SCENARIO #0002] Delete by user with no allowance automatically created whse. shpt. line
[SCENARIO #0003] Delete by user with allowance manually created whse. shpt. line
[SCENARIO #0004] Delete  by user with allowance automatically created whse. shpt. line
[SCENARIO #0009] “Allowed to Delete Shpt. Line” is not editable on warehouse employees page

[FEATURE] Unblock Deletion of Whse. Shpt. Line disabled
[SCENARIO #0005] Delete  by user with no allowance manually created whse. shpt. line
[SCENARIO #0006] Delete by user with no allowance automatically created whse. shpt. line
[SCENARIO #0007] Delete by user with allowance manually created whse. shpt. line
[SCENARIO #0008] Delete  by user with allowance automatically created whse. shpt. Line with confirmation
[SCENARIO #0011] Delete by user with allowance automatically created whse. shpt. line with no confirmation
[SCENARIO #0010] “Allowed to Delete Shpt. Line” is editable on warehouse employees page

Now fully applying the ATDD pattern detailing out our scenarios with the GIVENWHENTHEN parts, transforms our test plan into a test design. Leaving to you to study the full test design – the ATDD sheet – you can find here, this would be the test design for the first scenario:

[FEATURE] Unblock Deletion of Whse. Shpt. Line enabled
[SCENARIO #0001] Delete by user with no allowance manually created whse. shpt. line
[GIVEN] Enable “Unblock Deletion of Shpt. Line” on warehouse setup
[GIVEN] Location with require shipment
[GIVEN] Warehouse employee for current user with no allowance
[GIVEN] Manually created warehouse shipment from released sales order with one line with require shipment location
[WHEN] Delete warehouse shipment line
[THEN] Warehouse shipment line is deleted

Test Coding

OK, now, given the (full) test design, I am set to work on my first ATDD feature and get scenario #0001 coded. Once completed, that is, running successful, I proceed to #0002, #0003, #0004 and #0009. In this flow of getting one scenario coded after the other, I might pay attention to rule 2 of the TDD game (see the first post of this series), but I very often do not want or have to for the following reasons (in random order):

  1. I adhere as much as possible to the ATDD attitude of “getting the tests passing asap” and not allowing me a lot of time to refactor.
  2. Using the ATDD.TestScriptor PowerShell module and given a consistent description of the various ATDD tags, the test code setup generated often already has created reusable helper functions.

This leads to a first complete version of coded tests for the first feature:

[FEATURE] Unblock Deletion of Whse. Shpt. Line enabled

As this test codeunit entails all together 270 lines of code it is a bit too much to include it fully in this post. Therefore a reference to it: UnblockDeletionEnabled.Codeunit.al. And of course have some kind of proof that these indeed are successful tests:

Given app and test code, that seemingly are in balance as the test are passing, I am set to finally start on the goal of this blog post series: refactoring. Cleaning up the code to remove duplication and transform the specific into generic. Doing this I try to keep in mind that each change is done in small enough steps – another ATDD attitude – and is always verified by rerunning the tests. Any failure in any of the tests after a change cannot but have its root in this change.

Refactoring can start

Ouch, yes, sorry for keeping you in suspense with another round of introductory stuff. Badly planned, I must admit, but I nevertheless leave the real refactoring for a next post that will follow very soon.

One Comment

  1. Pingback: From fresh to shared fixture – refactoring can start #3 – Van Vugt's DynamiXs

Leave a Reply

Your email address will not be published. Required fields are marked *