Testing Insights

How to write effective interface tests?

2025-10-29

Front-line development students may have caused online bugs or even failures to a greater or lesser extent; You will also encounter such a scenario, a student reconstructs the code when developing a function, causing online bugs or failures; When developing a function, it is found that it is necessary to modify the public logic, fearing that it will affect other functions, so it is very unsightly to copy the code and rewrite the separate logic to support it.

The above situations contain a key question, whether it is functional development or logical refactoring, how to ensure the quality of code development. The means of protection, everyone knows, is testing. The first is the new function test to ensure that the new function logic is correct; The second is regression testing to ensure that the original business function logic is correct. There are generally two ways to test, manual testing and automated testing. With the continuous development of testing technology and tools, the proportion of manual testing has gradually decreased and is gradually replaced by automated testing. Automated testing is sustainable and repeatable, even AI-enabled.

1. Test stratification

The tests are also layered, as shown in the image below:

//img.enjoy4fun.com/news_icon/d40th1b8hlms72p2p4cg.png

In a system, automated testing is generally divided into unit testing, module testing, and interface testing.

Unit tests

At present, my application code is basically based on the programming mode of the Spring framework for interfaces, and the unit tests have been weakened. The requirement for unit tests is basically tests for a single class and a single method, which is too expensive to write in our current mode. Of course, if it is a tool or a piece of more cohesive and complex logic (such as algorithmic logic), unit tests should still be used to ensure the correctness of the logic.

Module testing

In the case of a relatively large system and many modules, a module test layer can be established to ensure the correctness of each module's function. However, the current system development trend is microservice architecture, so the module test layer is not very necessary and can be covered by the interface test layer.

Interface testing

Personally, I think it should be called entrance testing to be precise, and this layer is to start from the system entrance for integration testing. Application ingress is usually HSF (a distributed RPC service framework) service, messages, and scheduled tasks.

As a development, there are thousands of testing methods, and interface testing is indispensable. When the interface testing of our application is effective and fully covered, it not only ensures the development quality of our new functions, but also allows us to have the ability to regress when modifying the function logic, which is also the prerequisite for our code refactoring. At the same time, testability is also an indicator of reasonable code structure, if it is found that a piece of code is difficult to write a test script or cannot be tested, it means that the current code structure is unreasonable and needs to be reconstructed. Next, I will mainly talk about the effectiveness of interface testing.

2. Test principles

Basic principles:

Automation: Interface testing is non-interactive, automated execution that does not require human participation.

Independence: Interface tests should not depend on each other.

Repeatable: Interface tests can be performed repeatedly regardless of environmental influences.

Interface testing adheres to the BCDE principle to ensure the quality of interface delivery. Border: Boundary test. Correct: Correct input, correct expected output. Design: Write test logic according to requirements and design documents. Error: Wrong input, expected output.

Data preparation: Data preparation is carried out through system services and cannot be directly inserted into the DB.

Measurability: Unmeasurable code needs to be reconstructed into a reasonable structure.

Coverage: Interface tests need to cover all UCs, and the code coverage and branch coverage should meet certain standards, and the new code must be covered.

Continuity: If code modifications cause existing interface tests to fail, you must fix the code problem or test the code logic.

Time requirements: Interface testing should be completed before the project is released, and should not be supplemented after the project is released.

The above basic principles should be applied to automated test cases at all layers, and when writing interface tests, in addition to the above principles, there are other principles that need to be followed, let's take a look at a diagram first:

//img.enjoy4fun.com/news_icon/d40tafh9q3nc72veqr60.png

Analyze the ingress calls from a system perspective, taking the HSF service as an example:

·Peripheral systems call services provided by our systems.

· The system executes a bunch of code logic with branching logic.

· The system relies on the external HSF service during execution, makes calls, and obtains the return value.

· During the execution process, the system relies on DB queries or landed data, and relies on cache queries or landed data.

· A message was sent to the outside world during the execution of the system.

· Return the HSF execution result to the upstream system.

The key principle of effective interface testing is to cover all entrances, mock all dependencies, and verify the traces left during execution, which are summarized as follows:

Ingress override: The interface test case must cover the HSF service portal, message portal, and scheduled task portal.

Dependency mock: Among the basic principles, there is a repeatable principle, that is, interface tests cannot be dependent on the environment, and need to mock external dependencies. However, for DB dependencies, it is not recommended to completely mock them, on the one hand, the cost of mocking is high, and on the other hand, it may not cover SQL and table constraint logic.

Complete verification: Valid interface tests should have complete verification, and interface tests without verification are meaningless. As long as the traces left during execution have an impact on the business, complete verification must be performed to ensure the effectiveness of the interface test. HSF interface return value verification: HSF return parameter verification is performed according to the scenario and interface convention. DB verification: verifies the correctness of landing data. cache verification: verifies the correctness of data stored in the cache. HSF dependent input parameter verification: uses the mock tool to obtain input parameters that depend on HSF calls and performs input parameter verification. Message verification: The message object sent is obtained through the mock tool and the message body is verified.

3. Test code structure

When writing test code, you should also consider the readability, scalability, and reusability of the code as well as writing business code. At the same time, according to the business characteristics of the system, you can also package the test components suitable for the current system on the basis of the test framework to improve the efficiency of test code writing and standardize the test code structure.

The approximate structure of the test code for an interface is as follows:

(1) Test preparation

Dependent data preparation

Many times, our tests have data dependencies, either configuration data or business data (e.g., refunds need to rely on payment data).

Configuration data: Configuration can be initialized by defining a configuration file.

Business data: This type of data is prohibited from being generated by directly inserting data, but should be generated by calling business services.

Dependent on mock

For external dependencies, you need to mock the dependent service to avoid real calls.

Interface test parameter preparation

Prepare the interface parameters.

(2) Test execution

Call the interface method to execute the business logic.

(3) Test and verification

· Return Parameter Validation: Validate the return parameters of the interface.

· DB: Verify the landing data of the DB.

· Cache data validation: Verify the data that lands in the cache.

· Message verification: Verify the message objects sent externally.

· External HSF call verification: Validates the input parameters of external HSF calls.

4. Practical skills

(1) Execution efficiency

For interface testing, execution efficiency is a point that must be paid attention to, if an interface test can be executed for more than 3 minutes to see the results, it will greatly reduce the enthusiasm of development students to write interface tests. For more efficient test execution, the recommended scenarios are:

· Minimize the startup test context, such as the app of Spring Boot, and start Spring is fine

· Use an in-memory database, such as h2

· Mock the middleware dependencies

(2) Test frame selection

For test frameworks, it is recommended to choose a test framework based on testng that can provide data preparation through configuration files. If you can't find a suitable one, you can encapsulate it based on testng yourself.

(3) Interface test coverage

On the one hand, it is necessary to enumerate normal and abnormal situations based on the input and test experience of development students based on business scenarios, and on the other hand, interface methods also have some fixed points that need to be tested, such as idempotent tests, boundary value tests, incorrect parameter tests, etc.

At the same time, you should also use the coverage tool to view the code or branch logic that is not covered by the interface and conduct targeted scenario coverage tests. In my experience, full branch coverage is very important, especially exceptionally branched.

5. Summary

To ensure the stable operation of the system online, quality assurance means are essential. Although there are many automated safeguards now, interface testing is still one of the most basic and important safeguards. If the coverage and effectiveness of interface tests can be continuously guaranteed, the occurrence of online bugs will be greatly reduced, and development students will be more motivated to refactor code.

more stories
See more