Hypertest v2 Docs
HyperTest
  • Overview
    • How It Works?
  • SETUP GUIDE
    • Installation
      • Deploy HyperTest Server
      • Creating your first User
      • Adding your first service
      • Integrate SDK
        • Node.js
          • Node.js SDK with CJS
          • Node.js SDK with ESM
        • Java
    • Start a Test Run
      • CLI Login
      • Type References
      • Java
  • Interpreting Test Results
    • Test Results
    • Understanding Results Categories
    • Mock Not Found
    • AI Match Mocks
    • Accepting Changes
  • USER GUIDES
    • Node.js SDK
      • Limit memory usage
      • Supported NPM packages
      • Mock Dependencies Manually
      • Unmocking/Passing Through
      • Sampling and blocking requests
      • Manage Global Variables
      • Mocking Environment Variables
      • Tags
      • Set HTTP path patterns
      • Discard a test case(Request) while recording
      • Set Git Commit Hash
      • Code coverage based features
        • Continuous Coverage
        • Updating test coverage
        • Running post test deduplication
        • Only testing modified requests
        • Ignore differences for unmodified requests
      • Experimental flags
      • Manual Request
      • Only testing modified requests
      • Server hooks
    • Java SDK
      • Sampling and blocking requests
      • Mock Dependencies Manually
      • Tags
      • Unmocking/Passing Through
      • Code Coverage Setup and Report Generation
      • Supported Java packages
    • Build your own Docker Image
    • CLI Config
    • Ignoring Differences
      • Type References for Filter functions
  • Impact Features
    • Fast Mode
    • Code Coverage Report
    • Delete Recorded Requests
    • Inter Service Testing
  • Release History
    • Slack Integration
    • Version History
Powered by GitBook
On this page
  • 1. Case
  • 2. Label
  • 3. Annotation
  1. USER GUIDES
  2. Java SDK

Tags

Tags are used to provide additional information for the request and contribute to a better control over deduplication. A request can only contain a unique tag with same name and value.

There are three types of tags.

  1. Case

  2. Label

  3. Annotation

1. Case

Case is a tag that is used to create a mock at a particular branching which needs to be covered in a request and does not let it get deduplicated if there is a version of the same request already present.

Case is created with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("case name", "case value", EnumManager.TagType.CASE);

Case contributes to the deduplicating hash and essentially creates a new version of the request if the latter was already present. Typically this is used to create different versions of the same request to increase code coverage and cover all branching statements.

Case can also be added in the root context of an application. If a case is added in root context then the same case is inserted in every incoming request when the server span is created.

Case is created at root context with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootCase("case name", "case value");

E.g.,

Imagine an api where the logic splits based on a requestParam action.

Suppose, we hit a request with requestParam itemType as credit, and then with requestParam itemType as debit then the 2nd request would get deduplicated (so there won't be generation of test case for it).

To generate a test case for both the branches we can use case tag like this:

@GetMapping("/updateBalance")
public ResponseEntity<?> updateBalance(@RequestParam("userId") String userId,
                                       @RequestParam("amount") BigDecimal amount,
                                       @RequestParam("action") String action) {
    // Use the CASE tag to record the branch of execution based on the action parameter.
    HypertestAgent.addTag("action", action, EnumManager.TagType.CASE);
    
    // Fetch the current balance for the user
    BigDecimal currentBalance = userService.getBalance(userId);
    
    if ("credit".equalsIgnoreCase(action)) {
         // Credit branch: add the specified amount to the current balance
         BigDecimal updatedBalance = currentBalance.add(amount);
         userService.updateBalance(userId, updatedBalance);
         return ResponseEntity.ok("User " + userId + " credited with " + amount +
                                  ". Current balance: " + updatedBalance);
    } else if ("debit".equalsIgnoreCase(action)) {
         // Debit branch: subtract the specified amount from the current balance
         BigDecimal updatedBalance = currentBalance.subtract(amount);
         userService.updateBalance(userId, updatedBalance);
         return ResponseEntity.ok("User " + userId + " debited with " + amount +
                                  ". Current balance: " + updatedBalance);
    } else {
         // Invalid action handling
         return ResponseEntity.badRequest().body("Invalid action specified.");
    }
}

2. Label

Label is a tag that is used to create a mock inside a particular route to avoid more versions of the same request due to difference in response schema. If there is a label inside a request, then only the cases and labels are considered for creating the deduplicating hash value thereby retaining the desired version of the request.

Label is created with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("label name", "label value", EnumManager.TagType.LABEL);

Label can also be added in the root context of an application. If a label is added in root context then the same label is inserted in every incoming request when the server span is created.

Label is created at root context with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootLabel("label name", "label value");

E.g.,

Imagine an endpoint that returns user details in two different response schemas based on the detailLevel query parameter.

The underlying business logic remains similar, but the schema of outbound JPA call varies. Without intervention, these schema differences would result in multiple test cases.

By adding a Label tag, you ensure that the deduplication process considers only your defined label value (e.g., a fixed output schema version), thus retaining a single desired version of the request.

@GetMapping("/users")
public ResponseEntity<?> getUser(@RequestParam("detailLevel") String detailLevel) {
    // By adding a label with a constant value (e.g., "v1"),
    // we ensure that differences in the output details don't result in separate test cases.
    HypertestAgent.addTag("outputSchema", "v1", EnumManager.TagType.LABEL);
    
    if ("full".equals(detailLevel)) {
        // Full branch: returns comprehensive user details.
        User fullUser = userService.getFullUser();
        return ResponseEntity.ok(fullUser);
    } else {
        // Basic branch: returns minimal user details.
        User basicUser = userService.getBasicUser();
        return ResponseEntity.ok(basicUser);
    }
}

3. Annotation

Annotation is a tag that is used to create an unimportant mock inside a route to provide additional context to the request. This does not contribute to the deduplicating hash.

Annotation is created with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("annotation name", "annotation value", EnumManager.TagType.ANNOTATION);

Annotation can also be added in the root context of an application. If a annotation is added in root context then the same annotation is inserted in every incoming request when the server span is created.

Annotation is created at root context with the following syntax in source code.

import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootAnnotation("label name", "label value");

E.g.,

In this scenario, there are 2 kind of APIs one for handling user operations (such as creating a user and logging in), while the other manages order-related operations.

The annotations add metadata that can later be used on Hypertest dashboard to filter or in .htTestConf.js to run only selected groups of APIs.

@RestController
public class Controller {

    @PostMapping("/create")
    public ResponseEntity<?> createUser(@RequestBody User user) {
        // Annotate this endpoint as belonging to the "user" group.
        HypertestAgent.addTag("apiGroup", "user", EnumManager.TagType.ANNOTATION);
        
        // Business logic for creating a user
        userService.createUser(user);
        return ResponseEntity.ok("User created successfully");
    }

    @PostMapping("/login")
    public ResponseEntity<?> loginUser(@RequestBody LoginRequest loginRequest) {
        // Annotate this endpoint as belonging to the "user" group.
        HypertestAgent.addTag("apiGroup", "user", EnumManager.TagType.ANNOTATION);
        
        // Business logic for logging in a user
        boolean success = userService.login(loginRequest);
        if (success) {
            return ResponseEntity.ok("User logged in successfully");
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }
    }
    
    @PostMapping("/place")
    public ResponseEntity<?> placeOrder(@RequestBody Order order) {
        // Annotate this endpoint as belonging to the "order" group.
        HypertestAgent.addTag("apiGroup", "order", EnumManager.TagType.ANNOTATION);
        
        // Business logic for placing an order
        orderService.placeOrder(order);
        return ResponseEntity.ok("Order placed successfully");
    }
}
PreviousMock Dependencies ManuallyNextUnmocking/Passing Through

Last updated 2 months ago