Skip to content

swittest

swittest is a a full EMV functional test automation system.

Key concepts

Info

swittest uses JSON format for its test files.

Test suites

A test suite is a document that regroups a certain number of tests together usually under a common criteria, such as:

  • Certification level (EMV Level 2 / EMV Level 3)
  • Scheme (Visa, Mastercard, Amex, ...)
  • Specification version
  • Test environment version

Format

{
    "name": "MCL v3.1.4 TAL2-Testing Env Dec2021",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        ...
    },

    "tests": [
        ...
    ]
}

With:

  • name: The name of the test suite. It should more or less contain the same details as the env section.
  • version: The version of the file.
  • date: The date when the file was generated.
  • environment: The test suite details (see Environment).
  • tests: The list of tests to execute (see Test).

Environment

The environment section contains information about the test suite usage. The content of the section is described below:

{
    ...
    "environment": {
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },
    ...
}

With:

  • type: The type of testing this test suite covers (for ex "TA L2" or "TA L3").
  • scheme: The payment scheme (for ex "Mastercard" or "Visa").
  • spec_version: The corresponding specification version.
  • test_plan_version: The test plan version.
  • test_env: The test environment version.

Test

The tests section contains a list of tests to be run as part of the test suite identified by their file name. The content is described below:

{
    ...
    "tests": [
        "3B02-0001_first-trx-5-mutualappls",
        "3B02-0002_first-trx-4-mutualappls",
        ...
    ],
    ...
}

Test files are is JSON format. No need to specify the file extension in the tests list.

Note

The tool will look for the test files under a strict hierarchy of folders defined as follows: <project_root>/${type}/${scheme}/${spec_version}/${test_plan_version}/${test_env}/tests, with each of the ${xxx}parameters belonging to the environment section.

Test suite data organization

The test suite data follow a very scrict orgnization:

  • The test suite(s) must be at the root of the directory.
  • The test suite environment description is an exact representation of the folder structure: <project_root>/${type}/${scheme}/${spec_version}/${test_plan_version}/${test_env}
  • At the end of the environment folder structure should be the capks, crs, emvs and tests directories, holding the corresponding data.

Below an example of what it could look like:

.
├── L2
   └── Mastercard
       └── v3.1.4
           └── v1.0.1
               └── Dec 2021
                   ├── capks
                      └── CAPK_MCL_1.json
                   ├── crs
                      └── CR_MCL_1.json
                   ├── emvs
                      └── PPS_MChip_1.json
                   └── tests
                       ├── 3B02-0001_first-trx-5-mutualappls.json
                       └── 3B02-0002_first-trx-4-mutualappls.json
└── L2-Mastercard-v3.1.4-v1.0.1-dec_2021.json

Full example

Below is a full example of what a test suite file could look like:

{
    "name": "MCL v3.1.4 TAL2-Testing Env Dec2021",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },

    "tests": [
        "3B02-0001_first-trx-5-mutualappls",
        "3B02-0002_first-trx-4-mutualappls",
    ]
}

Test

A test file is a document that describes the inputs and expected outputs of a perticular transaction (or group of transactions).

Format

{
    "name": "3B02-0001_first-trx-5-mutualappls",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        ...
    },

    "description": "...",

    "card": "my-test-card",

    "poi_config": {
       ...
    },

    "payments": [
        ...
    ]
}

With:

  • name: The name of the test suite. It should more or less contain the same details as the env section.
  • version: The version of the file.
  • date: The date when the file was generated.
  • environment: The test suite details (see Environment).
  • description: Optional information about the test (conditions, goal, etc...).
  • card: The virtual card to be used.
  • poi_config: The EMV configuration to be used for the test (see POIConfig).
  • payments: The payment(s) to trigger and their expected results (see Payment).

Environment

The environment section contains information about the test suite usage. The content of the section is described below:

{
    ...
    "environment": {
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },
    ...
}

With:

  • type: The type of testing this test suite covers (for ex "TA L2" or "TA L3").
  • scheme: The payment scheme (for ex "Mastercard" or "Visa").
  • spec_version: The corresponding specification version.
  • test_plan_version: The test plan version.
  • test_env: The test environment version.

POIConfig

The poi_config section gathers the different pieces of configuration to be used for the test. These pieces are references to other files only. The content of the section is described below:

{
    ...
    "poi_config": {
        "name": "POI_Config_1",
        "emv_config": "PPS_MChip_1",
        "capk_list": "CAPK_MCL_1",
        "cr_list": "CR_MCL_1",
    },
    ...
}

With:

  • name: The name of the POI Config.
  • emv_config: The complete EMV config file (e.g. supported combinations or AIDs).
  • capk_list: Set of CAPKs to be allowed for the test (optional).
  • cr_list: Set of revoked certificates to be used for the test (optional).

Payment

A test can hold one or several consecutive payments (e.g. transactions) with expected results (e.g. information to check) for each of them. The payments are gathered into a payments list. Each payment should then be described as below:

{
    ...
    "payments": [
        {
            "randoms": ["AABBCCDD", "BBCCDDEE"],
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "authorization_response": "",
            "expectations": {
                ...
            }
        },
        ...
    ]
}

With:

  • randoms: A list of randoms to use for the transaction(s) (optional).
  • trd: A list of tags corresponding to the Transaction Related Data. Only the following tags are supported: 9C, 9F02, 5F2A, 5F36, 9A, 9F21, 9F53, 9F7C (mandatory).
  • authorization_response: Authorization response to provide when the cards requires an authorization (optional).
  • expectations: A list of objects, tags, etc... to be verified for each payment (see Expectations).

Expectations

Expectations are a set of payment related data that must be checked in order for a test to be considered 'pass' or 'fail'. The content of the section is described below:

{
    ...
    "payments": [
        {
            ...
            "expectations": {
                "restart": {
                    "error_indication": "0003006A85FF",
                    "outcome_parameter_set": "5020F0F018F0FF00"
                },
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                },
                "completion": {
                    ... (same as authorization)
                }
            }
        }
    ]
}

With:

  • restart: An expected 'restart' signal to be found in the list of signals provided by the kernel (optional).
  • authorization: Kernel data provided to perform an authorization request (optional).
  • completion: Kernel data provided to perform the transaction completion (optional).

Note: Though authorization and completion are individually optional, there must at least be one of them in the test expectations.

The authorization and completion objects hold the below sub-objects (all of which are optional): * user_interface_request_data (full TLV value). * data_record (list of tags which value or presence should be checked). * discretionary_data (list of tags which value or presence should be checked). * outcome_parameter_set (full TLV value).

Note on data_record and discretionary_data

These objects contains at most 3 sub-objects (all of which are optional): * tags: Holds a list of tags (keys) and their expected values (values). * tags_present: Holds a list of tags which presence should be confirmed (whatever the value). * tags_not_present: Holds a list of tags which absence should be confirmed.

Notes

See below the tags corresponding to the authorization and completionsub-objects: * user_interface_request_data: DF8116 * data_record: FF8105 * discretionary_data: FF8106 * outcome_parameter_set: DF8129

Full example

Below is a full example of what a test suite file could look like:

{
    "name": "3B02-0001_first-trx-5-mutualappls",
    "version": "0.2.0",
    "date": "2024-10-05",

     "environment": {
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },

    "card": "my-test-card",

    "poi_config": {
        "name": "POI_Config_1",
        "emv_config": "PPS_MChip_1",
        "capk_list": "CAPK_MCL_1",
        "cr_list": "CR_MCL_1"
    },

    "payments": [
        {
            "randoms": ["AABBCCDD", "BBCCDDEE"],
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "authorization_response": "3030",
            "expectations": {
                "restart": {
                    "error_indication": "0003006A85FF",
                    "outcome_parameter_set": "5020F0F018F0FF00"
                },
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                }
            }
        },
        {
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "expectations": {
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        }
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        }
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                }
            }
        }
    ]
}

POI Config

A POI Config, in switstack's terminology is a set of files representing different layers of an EMV transaction's configuration.

Those layers are:

  • The EMV configuation which holds the supported applications and their respective configurations (TLVs).
  • The list of CA keys which is a list of all supported/authorized CA public keys used during card authentication.
  • The list of revoked certificates which is a list of CA public keys identifiers that must not be used anymore.

EMV Config

The EMV config is a file, that holds a set of applications to be supported by a kernel with their respective configuration. The contents of the file is described just below:

{
    "emvs": {
        "EMV Contactless Visa 1": {
            "technology_type": "CONTACTLESS",
            "kernel": "03",
            "aid": "A0000000031010",
            "transaction_type": "00",
            "asf": true,
            "tlv": "E15EDF810C01039F0607A00000000310109C0100DFA0100101E2459F6604270040009F1B04000027109F820D060000000002009F820E06000000010000DFA02006000000000400DFA0140101DFA0150101DFA0160101DFA01701019F1A020840"
        },
        "EMV Contactless Visa 2": {
            "technology_type": "CONTACTLESS",
            "kernel": "03",
            "aid": "A0000000032010",
            "transaction_type": "00",
            "asf": true,
            "tlv": "E15EDF810C01039F0607A00000000310109C0100DFA0100101E2459F6604270040009F1B04000027109F820D060000000002009F820E06000000010000DFA02006000000000400DFA0140101DFA0150101DFA0160101DFA01701019F1A020840"
        }
    },
    "emv_lists": {
        "EMVList Contactless Visa 1" : {
            "name": "EMVList Contactless Visa 1",
            "emvs": ["EMV Contactless Visa 1", "EMV Contactless Visa 2"]
        }
    },
    "emv_config": { 
        "name": "EMVConfig Contactless Visa 1",
        "emv_nominal_list": "EMVList Contactless Visa 1",
        "emv_failsafe_list": "EMVList Contactless Visa 1"
    }
}

With:

  • emvs: List of individual emv (e.g. combinations or configurations) for a specific quadruplet (technology_type, kernel, aid and transaction_type). Each emv must contain the following elements:
    • technology_type: Either CONTACTor CONTACTLESS.
    • kernel: The kernel ID (see kernels specifications).
    • aid: The Application IDentifier.
    • transaction_type: The type of transaction
      • 00 for Purchase.
      • 01 for Cash.
      • 09 for Purchase with Cashback.
      • 20 for Refund.
    • asf: The Application Selection Flag.
    • tlv: The actual TLV configuration.
  • emv_lists: List of emv_list to group combinations together. An emv_list is represented as follows:
    • name: Name of the list.
    • emvs: List of emv.
  • emv_config: The global config item. It is composed of:
    • name: The config name (for ex PPS_MChip_1).
    • emv_nominal_list: The list of combinations to use in nominal cases (e.g. most of the time).
    • emv_failsafe_list: The list of combinations to use in specific conditions (for ex prolongated offline mode).

CAPK List

The CAPK list is a file, that holds a list of EMV CA public keys to be used by the kernel(s) to perform card authentication. The contents of the file is described just below:

{
    "capks": {
        "mastercard_01": {
            "rid": "A000000004",
            "index": "01",
            "hash_type": "UNDEFINED",
            "algorithm_type": "RSA",
            "modulus": "AABBCCDDEEFF...",
            "exponent": "03",
            "hash": "000...00",
            "expires_at": "2024-12-31"
        },
        "mastercard_02": {
            "rid": "A000000004",
            "index": "02",
            "hash_type": "UNDEFINED",
            "algorithm_type": "RSA",
            "modulus": "AABBCCDDEEFF...",
            "exponent": "03",
            "hash": "000...00",
            "expires_at": "2024-12-31"
        },
        ...
    },
    "capk_list": {
        "name": "My CAPK List",
        "capks": ["mastercard_01", "mastercard_02"]
    }
}

With:

  • capks: A list of individual CAPK objects defined by a name and the following attributes:
    • rid: The RID.
    • index: The key index.
    • hash_type: The key checksum/hash type (UNDEFINED for now).
    • algorithm_type: The key algorithm (RSA for now).
    • moduls: The key modulus.
    • exponent: The key exponent.
    • hash: The key checksum / hash.
    • expires_at: The key expiration date.
  • capk_list: The list of CAPKs. It is composed of:
    • name: The list name.
    • capks: A list of CAPKs defined above in the document identified by their name.

CR List

The CR list is a file, that holds a list of revoked EMV CA public keys that cannot be used by the kernel(s) anymore to perform card authentication. The contents of the file is described just below:

{
    "crs": {
        "mastercard_01": {
            "rid": "A000000004",
            "index": "01",
            "serial_number": "AABBCC"
        },
        "mastercard_02": {
            "rid": "A000000004",
            "index": "02",
            "serial_number": "AABBCC"
        },
        ...
    },
    "cr_list": {
        "name": "My CR List",
        "crs": ["mastercard_01", "mastercard_02"]
    }
}

With:

  • crs: A list of individual CR objects defined by a name and the following attributes:
    • rid: The RID.
    • index: The key index.
    • serial_number: The key serial number (6 hex digits).
  • cr_list: The list of CRs. It is composed of:
    • name: The list name.
    • crs: A list of CRs defined above in the document identified by their name.

Virtual cards

Automated testing relies on virtual cards or, to be more exact, expected exchanges between a terminal and a card. The so called virtual cards can hold one or several transactions and for each of those transactions the full set of C-APDUs/R-APDUs expected to be exchanged between a terminal and what would be the equivalent card.

Info

Virtual card files should end up with a .vcard extension.

Format

<poll>
00A404000E325041592E5359532E444446303100
6F59840E325041592E5359532E4444463031A547BF0C44610C4F07A0000000041010870101610C4F07A0000000043060870103610A4F05B012345678870109610C4F07B0123456781020870108610C4F07B01234567810308701079000
00A4040007A000000004101000
6F3B8407A0000000041010A530870101500A4D6173746572436172645F2D06656E646566729F1101019F38089F02069F33039C01BF0C069F5D030004009000
80A800000C830A0000000015000000080000
770A820200809404100101009000
00B2011400
70485F24034912315A0854133390000015138C0E95059F02069F34039F33039F37048E0A000000000000000000009F0D0500000000009F0E0500000000009F0F0500000000009F4A01829000
80AE40001580000000010000000015003F0000006000D04F877600
77299F2701809F360200029F2608AC123456789ABCDE9F10120110000000020000DAC000000000000000009000
<poll>
00A404000E325041592E5359532E444446303100
6F31840E325041592E5359532E4444463031A51FBF0C1C610C4F07A0000000041010870101610C4F07A00000000430608701039000
00A4040007A000000004101000
6F3B8407A0000000041010A530870101500A4D6173746572436172645F2D06656E646566729F1101019F38089F02069F33039C01BF0C069F5D030004009000
80A800000C830A0000000015000000080000
770A820200809404100101006A85
00A4040007A000000004306000
6F1BA51987010350074D61657374726F5F2D06656E646566729F1101019000

Settings

For the service to run, swittest needs a certain number of settings:

  • Organization admin credentials to create/delete configuration files in switcloud.
  • Machine basic user credentials as well as a POI ID to create/update/read Payment data.
  • The system under test's (terminal) IP address and port to communicate with it.

These will all be passed to the CLI application through environment variable.

Please define, wherever suits you, the following variables:

ST_ORG_ADMIN_EMAIL=<the Org Admin email>
ST_ORG_ADMIN_PASSWORD=<the Org Admin password>
ST_USER_MACHINE_CLIENT_ID=<the machine user client ID>
ST_USER_MACHINE_CLIENT_SECRET=<the machine user client secret>
ST_TARGET_URL=<the target IP address> (port included, ex: 192.168.1.10:1234)
ST_SWITCLOUD_URL=<the switcloud service URL> (port included, ex: https://prod.switcloud.io:8000)
ST_POI_ID=<the POI ID>