skip to Main Content

I have a JSON file that contains nested key-value pairs. My JSON file looks like this

{
   "TagName1":{
      "TestCaseName1":{
         "Status":"pass",
         "RunTime":"063045"
      },
      "TestCaseName2":{
         "Status":"fail",
         "RunTime":"064045"
      }
   },
   "TagName2":{
      "TestCaseName3":{
         "Status":"pass",
         "RunTime":"073045"
      },
      "TestCaseName4":{
         "Status":"fail",
         "RunTime":"074045"
      }
   }
}

I want to fetch the name of test cases based on their Status. Is there a way to do fetch nested key-values from JSON file?

I tried to solve this problem by using Reader and creating nested Hashmap of key-value pair, something like this

try{
    Gson gson = new Gson();
    Reader reader = Files.newBufferReader(Paths.get(filePath));
    HashMap<String, HashMap<String, HashMap<String,String>>> parsedJson = gson.fromJson(reader,HashMap.class);
} 

I am struck at extracting the Status value. Is there a way to read the Status value and fetch the name of test case.

4

Answers


  1. With the gson library it could be achived like this:

    final List<String> failedCases = JsonParser.parseString(jsonString)
            .getAsJsonObject().entrySet()
            .stream() // get stream of all json entries, i.e. tags
            .map(Map.Entry::getValue) // get stream of tag values
            .map(JsonElement::getAsJsonObject)
            .flatMap(e -> e.entrySet().stream()) // get stream of all test cases entries (name to value)
            .filter(e -> e.getValue().getAsJsonObject() // filter test cases with "failed" Status value
                    .get("Status").getAsString().equals("fail")
            )
            .map(Map.Entry::getKey) // get test cases names
            .collect(Collectors.toList());
    
    Login or Signup to reply.
  2. You can use JSONObjects to parse the document

    public static void main(String[] args) {
        // ...
        JSONObject jsonObject = new JSONObject(json);
        String targetStatus = "fail";
        List<String> testCaseName = getTestCaseNameByStatus(jsonObject, targetStatus);
        System.out.println("TestCases with Status '" + targetStatus + "': " + testCaseName);
    }
    
    private static List<String> getTestCaseNameByStatus(JSONObject jsonObject, String targetStatus) {
        List<String> testCases = new ArrayList<>();
        for (String tag : jsonObject.keySet()) {
            JSONObject tagObject = jsonObject.getJSONObject(tag);
            for (String testCase : tagObject.keySet()) {
                JSONObject testCaseObject = tagObject.getJSONObject(testCase);
                try {
                    String status = testCaseObject.getString("Status");
                    if (status.equalsIgnoreCase(targetStatus)) {
                        testCases.add(testCase);
                    }
                } catch (JSONException jsonException) {
                    System.out.printf("Status not found for TestCase {%s}, Skipping next", testCases);
                }
            }
        }
        return testCases;
    }
    
    Login or Signup to reply.
  3. @gdomo ‘s answer is pretty clean, here is how you can do the same with jackson

    Map<String, Map<String, TestCase>> json = objectMapper.readValue(file, new TypeReference<>() {});
        List<String> passes = json
                .values() // Lists of Entry { testCaseName: TestCase } grouped by tagName
                .stream().flatMap(entry -> entry.entrySet().stream())   // 1 list of all Entries { testCaseName : TestCase }
                .filter(entry -> entry.getValue().getStatus().equals("pass")) // filter entries that pass
                .map(Map.Entry::getKey)       // get the testCaseNames of entries that pass
                .toList();
    

    notice I am using a defined TestCase class "which is cleaner practice"

    public class TestCase {
        @JsonProperty(value = "Status")
        private String status;
        @JsonProperty(value = "RunTime")
        private String runtime;
        // getters, setters
    }
    
    Login or Signup to reply.
  4. You may try library Josson.

    https://github.com/octomix/josson

    Josson josson = Josson.fromJsonString(jsonString);
    JsonNode node = josson.getNode("**.*[value.Status='pass']*.get(..key)");
    System.out.println(node.toPrettyString());
    

    Output

    [ "TestCaseName1", "TestCaseName3" ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search