Quando me deparei com a gravação de testes para um microsserviço, cuja API foi implementada de acordo com o protocolo JSON-RPC, percebi que criar verificações de qualidade para elementos json é muito mais exigente do que eu pensava antes.
O seguinte é um exemplo simples.
Uma resposta foi recebida do serviço:
{ "result": 12, "id": 46929734, "jsonrpc": "2.0" }
O que você precisa verificar:
- A resposta contém um elemento jsonrpc e seu valor é 2.0
- A resposta contém um elemento id e seu valor é igual a um elemento semelhante passado na solicitação, por enquanto, digamos que seja 46929734
A resposta contém o elemento
"resultado" e seu valor é
12Como verificar isso usando Java + TestNG + Gson:
Assert.assertTrue(response.has("result")); Assert.assertTrue(response.has("jsonrpc")); Assert.assertTrue(response.has("id")); Assert.assertTrue(response.get("result").isJsonPrimitive()); Assert.assertTrue(response.get("jsonrpc").isJsonPrimitive()); Assert.assertTrue(response.get("id").isJsonPrimitive()); Assert.assertEquals(response.get("result").getAsInt(), 12); Assert.assertEquals(response.get("jsonrpc").getAsString(), "2.0"); Assert.assertEquals(response.get("id").getAsInt(), 46929734);
Neste momento, a pergunta "Por que existem tantas afirmações?" Pode começar a se formar na mente. Sim, de fato, ao testar, você está interessado apenas no grupo das três últimas asserções, eles verificam os valores json dos elementos na resposta e, se forem aprovados, a resposta atende às expectativas. Mas e se o teste falhar? Considere vários motivos possíveis para a queda desse teste:
- Resposta ->
{ "result": 12, "id": 46929734, "jsonrpc": "1.0" }
Erro no TestNG -> java.lang.AssertionError: esperado [2.0] mas encontrado [1.0]
Eles esperaram por "2.0" , obtiveram "1.0" - tudo está claro aqui.
- Resposta ->
{ "result": 12, "id": 46929734, "jsonrpc": {} }
Erro no TestNG -> java.lang.UnsupportedOperationException: JsonObject
Eles tentaram analisar um elemento como uma sequência, que foi recebida absolutamente inesperadamente na resposta como um objeto.
- Resposta ->
{ "result": 12, "id": 46929734 }
Erro no TestNG -> java.lang.NullPointerException
Tentamos analisar um elemento que não está na resposta como uma string.
Com o primeiro exemplo, está tudo bem. O erro é compreensível, os valores reais e esperados são imediatamente visíveis. Mas o segundo e o terceiro exemplos não podem se gabar disso. Essa queda leva tempo ao testador para analisar a causa. Debater um erro tão superficial é difícil. Levará tempo para entender qual elemento específico o teste tentou analisar, qual método ele tentou analisar e como esse elemento realmente apareceu na resposta. Pode ser necessário reiniciar o teste localmente, simplesmente porque pode ser mais rápido do que coletar todas as informações necessárias dos logs do conjunto de teste.
Esse número de verificações, a necessidade de escrevê-las e apoiá-las em um estado atualizado, me deixou muito chateado, então criei uma biblioteca separada na qual coletei todas as verificações necessárias, na minha opinião, para elementos json. O mesmo nível de cobertura e detalhe que exigia o json acima usando a biblioteca é alcançado em três linhas, em vez de nove.
Gassert.verifyInteger(response, "result", 12); Gassert.verifyString(response, "jsonrpc", "2.0"); Gassert.verifyInteger(response, "id", 46929734);
A biblioteca implementa métodos para verificar:
- elementos de todos os tipos primitivos, aninhados e não, com verificação de valor e sem
- JsonObject, aninhado e não, com verificação de valor e sem
- JsonArray, aninhado e não, com e sem verificação de valor
- Elementos JsonNull aninhados e não
- tipos de elemento dentro de uma matriz
- o conteúdo da matriz de elementos esperada
- dimensões da matriz
- dimensões do objeto
Em todos os níveis de verificação, erros mais detalhados são implementados em relação àqueles que o TestNG fornece por padrão.
Considere novamente os possíveis motivos para a queda do teste:
- Resposta ->
{ "result": 12, "id": 46929734, "jsonrpc": "1.0" }
Erro de Gassert -> java.lang.AssertionError: Falha na verificação do elemento [jsonrpc]. esperado [2.0], mas encontrado [1.0]
- Resposta ->
{ "result": 12, "id": 46929734, "jsonrpc": {} }
Erro de Gassert -> java.lang.AssertionError: O elemento [jsonrpc] não é um JsonPrimitive. não esperava encontrar [verdadeiro], mas encontrou [falso]
- Resposta ->
{ "result": 12, "id": 46929734 }
Erro de Gassert -> java.lang.AssertionError: Json não contém o elemento: [jsonrpc]. não esperava encontrar [verdadeiro], mas encontrou [falso]
Além disso, a maioria dos métodos de verificação está sobrecarregada com um parâmetro de string adicional, que, no caso de uma queda de asserção, será adicionado ao texto do erro exibido. Esse recurso pode ser usado, por exemplo, para exibir o corpo inteiro de uma resposta ou solicitar + resposta com erro.
A biblioteca está no repositório público do github e também é adicionada ao repositório maven.
MavenGithubAPIDocs