Continuous integration

Testing acquirer side implementations are hard. The incoming message formats and communication protocols from the card acceptors ( Payment Terminals, Point-of-Sale Machines, Store Controllers) are known and the endpoint’s message formats and communication protocols are also known. The challenge is testing and validating the translated incoming messages to various outbound endpoints, their communication protocols and message formats. Some end-points provide simulators (very very few) others will allow test access over leased lines and communication equipment over a separate test ip/port combination. This works well for our customers to perform user acceptance and certification -to these endpoints – this isn’t viable for regression and testing during phases and development before code delivery. We have solved some of this with various custom build response simulators that have basic logic – typically transaction amount prompted to provide alternating response messages. These response messages are built from message specs or are built from captured network traffic on test systems. We can only be sure we are simulating basic transaction types and request and response channels, however. Oh, and then there is always this problem.

Issuer side implementations are easier test – you can feed into the authorization host both simulated network and local transaction sets to test implemented authorization rules and other features.

In 2009 we built and launched a new Issuing Payment Switch and tested it using Continuous Integration techniques. This system has 3 primary interfaces.

Network – connected to an association’s network to recieve incoming transactions based on BIN ranges.

Local – Card Management style interface – Manage Cardholder, Cards, and Accounts on the system – and allow local transaction sets to be performed.

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. This article is a quick overview of Continuous Integration summarizing the technique and its current usage.

CI’s general steps:

Maintain a code repository

Automate the build

Make the build self-testing

Everyone commits every day

Every commit (to mainline) should be built

Keep the build fast

Test in a clone of the production environment

Make it easy to get the latest deliverables

Everyone can see the results of the latest build

Automate Deployment

Our CI model is based on an implementation that is scheduled multiple times a day – It checks out the code from our software repository, compiles it, builds a new database and schema and required setup data, starts our software services up – performs unit tests, shutdown the software services, and we receive an email and attachments that tell us if the code compiled and the results of the unit tests and which ones were successful and unsuccessful. The email attachments we receive contain the run log zipped of the transactions, and a unit test report.
Our Unit tests are written using the Groovy Programming Language and we leverage the TestNG testing framework. We act as a network client to our switch which was built and ran from the current source, and perform both Network and Local Side testing. The system is also setup using some of the Local Transaction sets, Here is a short list of a few of the transaction types:
Local:

Add Cardholder

Add Card

Add Account

Debit Account (Load Funds)

Set Cardholder/Card/Account Status (Active/Lost/Stolen/Suspended/etc)

Local Debit and Credits

Balance Inquiry

Expire Authorization

View Transaction History

Network:

Authorization

Completions

Chargebacks

Representments

Force Posts

Returns

Reverals

The combination of local and network transaction types are tested against various test cases.
If we setup a Cardholder with AVS information and run an AVS Authorization – do we get the expected results, and for each AVS result code ? Does an authorization on a statused card get approved ? Do transactions with amounts greater then, equal to, or less then the cardholder’s available balance get authorized or declined properly ? Authorization on a Card not Found ? You get the idea.
We build and test our issuer platform a few times a day – each developer can also run the test suite locally on their development environment, this ensures that future changes doesn’t impact existing functionality. On a test failure – relevant information in included in the autotest emails so issue discovery can be identified by our business analysts and developers without logging into test systems.
Oh, and Please don’t break the build 😉