CASE: liquid testing - BE standard working papers - VAT balance

CASE liquid testing - BE VAT balance

Eager to get started with liquid testing? Below you can find a case on how we implemented the liquid testing YAML code for the VAT balance template in the BE standard working papers package, as well as how we interpreted our liquid testing guidelines.

GUIDELINES IMPLEMENTATION

Coding best practices

  • Clearly separated parts with comments
  • Add a one-line comment before each test to explain in human language what this test is about
  • Add a numbering for the unit + test in each comment explaining the test
  • Test top-level key describes what this test is about

Make use of debug mode

  • All results & text properties (= values inside customs) were copied over from the debug mode. This way we’re immediately sure the values added in the test are the same as when the template is completed on the platform.
  • The data in the debug is shown in JSON format, but the liquid testing needs to be made in YAML. In order to easily include the values from the ‘Named results’, ‘TextProperties’ and ‘Rollforward parameters’ sections in the debug I used this tool to immediately convert the JSON to the correct YAML format after functionally setting up my scenario in the template: https://codepen.io/WoBr/full/RwjzoJg

Start with an empty state

  • We’ve started with an empty state to set the global settings that are applicable for all units & tests (company / context information).
  • Usually there are results being created even if nothing is completed in the template, this way we also have an overview of which results are always there.

Identifying tests

  • I’ve started with checking how values can be added and in this case the accounts could be added by both defaults and a manual user action. The explanation for these accounts is added through a collection (fori).
    • This means we’ll need to add custom values to both the accounts and the reconciliations blocks in the tests.
  • The template has reconciliation activated (green dot / red triangle), so we’ll need to write tests for both success (= reconciled) and error (= unreconciled) paths.
  • The template is not dependent on any other specific templates.
  • Tests will be defined based on how the user could complete the template
  • No specific rollforward logic is present in the template, so we don’t need to consider any rollforwards in our expectation.

Derive tests based on the code

  • There’s no duplicate or legacy code that is maintained inside this template, so we don’t have to do any additional tests of the functional situations.
  • No hidden unreconciled logic present that we need to consider.
  • The results already present in the template contain all the necessary end values we need to test the scenario’s, so we don’t have to worry about adding new results for the liquid testing.

Test suite structure

  • I’ve started with the success paths since these are the most common and important scenario’s to test. So if these tests fail, they are the first to get focused.
  • I’ve also added error paths to test if the unreconciled logic and values are always behaving correctly.

Make use of anchors and aliases

  • In the empty state I’ve created anchors for global values that are applicable to all scenario’s and tests (context / company / results that are always created). This way if we change any general data or add new results that affect all tests ,we can change that on one place.
  • In the first test of each scenario, I then created anchors for values that are used in every test of that scenario. These values would be too specific to already it on any higher level. I chose to only create new anchors in the first test of a scenario for two reasons:
  1. For consistent code structure: this way if I see a specific test calls an alias, I know that this is coming from either the first test in that scenario or from the empty state. In larger liquid tests it could otherwise start getting confusing to keep track of which value a specific alias contains.
  2. For code readability: in each test I can then immediately see which specific values are required to be defined to create the test.

Results

In this case, the template was already creating results for the end values so no new result creation was necessary.

Documentation

A documentation was attached to the test suite in order to go over the reasoning behind the testing setup and other people (and probably yourself one year in the future), can understand why the tests are setup in this way (see below).

VAT balance documentation

TEST CASES REASONING

Success paths

For the success paths we need to cover cases with and without defaults:

  • Receivable VAT amount: default accounts value are equal to the explained amounts
  • Receivable VAT amount: manual accounts value are equal to the explained amounts
  • Payable VAT amount: default accounts value are equal to the explained amounts
  • Payable VAT amount: manual accounts value are equal to the explained amounts

Error paths

For the error paths we’ll cover four cases where differences could occur and the template needs to be unreconciled:

  • Receivable VAT amount: accounts value are higher than the explained amounts
  • Receivable VAT amount: accounts value are lower than the explained amounts
  • Payable VAT amount: accounts value are higher than the explained amounts
  • Payable VAT amount: accounts value are lower than the explained amounts

The units will be split based on the type of VAT (receivable / payable).
We’ll also build test cases that use multiple accounts and inputs to test the summations.

OVERVIEW YAML TESTS

Units

UNIT 1: Receivable VAT amount
UNIT 2: Payable VAT amount

Tests per unit

TEST 1: default accounts value are equal to the explained amounts
TEST 2: manual accounts value are equal to the explained amounts
TEST 3: accounts value are higher than the explained amounts
TEST 4: accounts value are lower than the explained amounts

CODE IMPLEMENTATION

empty_state: &unit_blueprint
  context:
    period: 2021-12-31

  data:
    periods:
      2021-12-31:

  expectation:
    reconciled: false
    results: &results_blueprint
      vat_bookkeeping:
      vat_explained: 0.0
      BTW_herz_R61:
      BTW_herz_R62:

######################################################

# UNIT 1: Receivable VAT amount

######################################################

# UNIT 1 - TEST 1: default accounts value are equal to the explained amounts
receivable_amount_default_equal:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts: &accounts_blueprint
          "411000":
            name: "Terug te vorderen BTW"
            value: 4564.67
          "411500":
            name: "Terug te vorderen BTW - herziening"
            value: 46.41
        reconciliations:
          btw_saldo:
            custom: &custom_blueprint
              # Leave account collection blank (account.numbers), since the accounts should be added by the default
              account.numbers: ""
              uitreksel.uitreksel_1:
                aard: "BTW aangifte"
                value: "5418.47"
              uitreksel.uitreksel_2:
                aard: "BTW herziening"
                value: "-807.39"

  expectation:
    reconciled: true
    results:
      <<: *results_blueprint
      vat_bookkeeping: 4611.08
      vat_explained: 4611.08
      BTW_herz_R61: -807.39

# UNIT 1 - TEST 2: manual accounts value are equal to the explained amounts
receivable_amount_manual_equal:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          <<: *accounts_blueprint
          "411001":
            name: "Terug te vorderen BTW"
            value: 4564.67
        reconciliations:
          btw_saldo:
            custom:
              <<: *custom_blueprint
              account.numbers: "411001,411500"

  expectation:
    reconciled: true
    results:
      <<: *results_blueprint
      vat_bookkeeping: 4611.08
      vat_explained: 4611.08
      BTW_herz_R61: -807.39

# UNIT 1 - TEST 3: accounts value are higher than the explained amounts
receivable_amount_higher:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          <<: *accounts_blueprint
          "411000":
            name: "Terug te vorderen BTW"
            value: 5213.22
        reconciliations:
          btw_saldo:
            custom:
              *custom_blueprint

  expectation:
    reconciled: false
    results:
      <<: *results_blueprint
      vat_bookkeeping: 5259.63
      vat_explained: 4611.08
      BTW_herz_R61: -807.39

# UNIT 1 - TEST 4: accounts value are lower than the explained amounts
receivable_amount_lower:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          *accounts_blueprint
        reconciliations:
          btw_saldo:
            custom:
              <<: *custom_blueprint
              uitreksel.uitreksel_1:
                aard: "BTW aangifte"
                value: "6067.02"

  expectation:
    reconciled: false
    results:
      <<: *results_blueprint
      vat_bookkeeping: 4611.08
      vat_explained: 5259.63
      BTW_herz_R61: -807.39

######################################################

# UNIT 2: Payable VAT amount

######################################################

# UNIT 2 - TEST 1: default accounts value are equal to the explained amounts
payable_amount_default_equal:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts: &accounts_blueprint
          "451000":
            name: "Te betalen BTW"
            value: -4564.67
          "451600":
            name: "Te betalen BTW"
            value: -46.41
        reconciliations:
          btw_saldo:
            custom: &custom_blueprint
              # Leave account collection blank (account.numbers), since the accounts should be added by the default
              account.numbers: ""
              uitreksel.uitreksel_1:
                aard: "BTW aangifte"
                value: "-5418.47"
              uitreksel.uitreksel_2:
                aard: "BTW herziening"
                value: "807.39"
  expectation:
    reconciled: true
    results:
      <<: *results_blueprint
      vat_bookkeeping: -4611.08
      vat_explained: -4611.08
      BTW_herz_R62: 807.39

# UNIT 2 - TEST 2: manual accounts value are equal to the explained amounts
payable_amount_manual_equal:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          <<: *accounts_blueprint
          "451001":
            name: "Te betalen BTW"
            value: -4564.67
        reconciliations:
          btw_saldo:
            custom:
              <<: *custom_blueprint
              account.numbers: "451001,451600"

  expectation:
    reconciled: true
    results:
      <<: *results_blueprint
      vat_bookkeeping: -4611.08
      vat_explained: -4611.08
      BTW_herz_R62: 807.39

# UNIT 2 - TEST 3: accounts value are higher than the explained amounts
payable_amount_higher:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          <<: *accounts_blueprint
          "451000":
            name: "Te betalen BTW"
            value: -5213.22
        reconciliations:
          btw_saldo:
            custom:
              *custom_blueprint

  expectation:
    reconciled: false
    results:
      <<: *results_blueprint
      vat_bookkeeping: -5259.63
      vat_explained: -4611.08
      BTW_herz_R62: 807.39

# UNIT 2 - TEST 4: accounts value are lower than the explained amounts
payable_amount_lower:
  <<: *unit_blueprint

  data:
    periods:
      2021-12-31:
        accounts:
          *accounts_blueprint
        reconciliations:
          btw_saldo:
            custom:
              <<: *custom_blueprint
              uitreksel.uitreksel_1:
                aard: "BTW aangifte"
                value: "-6067.02"

  expectation:
    reconciled: false
    results:
      <<: *results_blueprint
      vat_bookkeeping: -4611.08
      vat_explained: -5259.63
      BTW_herz_R62: 807.39