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.
- 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.
- Flat File generation: Authorized File, Financial File, and a Card Status and Balances File. Flat file processing - clearing/settlement/reconciliation files.
Continuous Integration as defined by Martin Fowler:
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:
- 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
- Force Posts
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 ;)