Cenários de teste complexos exigem a capacidade de escrever uma lógica complexa para lidar com eles. E é nesse momento que a abordagem orientada por palavras-chave começa a ser quebrada. Para resolver certos tipos de problemas, será necessário escrever o código da sua forma mais "pura" em JavaScript.
O OpenTest permite que os testadores usem códigos em JavaScript em praticamente qualquer lugar de um teste, conforme necessário. As principais formas de incorportar um código JS a um teste são:
- Ações de script
- Expressões JavaScript ad hoc
- Arquivos JavaScript externos
Vamos ver cada uma dessas técnicas adiante.
As ações de script podem ser usadas para inserir blocos de código JavaScript em qualquer fluxo de teste. A forma mais simples é através de uma ação de script da seguinte forma:
- script: var message = "Hello world!"
A maioria dos blocos de script irá utilizar várias linhas de código, e normalmente irão incluir uma descrição do que aparecerá nos relatórios de execução de teste. PAra incluir blocos de código maiors, devemos usar a barra "|" ou pipe do YAML, essa sintaxe irá permitir que os scripts sejam escritos em várias linhas. Como mostrado no exemplo abaixo:
- description: Click button1 trough button100
script: |
for (var buttonNo = 1; buttonNo <= 100; buttonNo++) {
$runAction("org.getopentest.selenium.Click", {
locator: { id: "button" + buttonNo }
});
}
As expressões JavaScript podem ser usadas para fornecer os valores para argumentos/variáveis das ações de teste ou valores de propriedades nos arquivos de dados. Vamos ver o seguinte exemplo:
- description: Criar um novo blogpost
action: org.getopentest.actions.HttpRequest
args:
url: $data("urls").jsonplaceholder + "/posts"
verb: POST
contentType: application/json
body: |
$json(
{
id: 123,
title: "My fist post"
}
)
Os valores dos argumentos url
e body
do código acima são expressões JavaScript que serão avaliadas e usadas para preencher esses dois argumentos.
Quando o valor de um argumento de uma ação copmeça com o símbolo de dolar (como em $json
ou $data
no exemplo anterior), o ator do teste irá entender que a expressão é um código JavaScript, irá avaliar a expressão e usar o resultado como valor para o argumento.
Em alguns casos as expressões JavaScript devem começar com algo diferete de um simbolo prefixado em dólar. Para que o ator possa compreender que tal expressão é um código JS, e não apenas uma string comum, então, será necessário prefixar a expressão com $script
seguido por um ou mais caracteres de espaço branco. Ficando da seguinte forma:
- description: Type a random user name into the "username" textbox
action: org.getopentest.selenium.SendKeys
args:
locator: { id: username }
text: $script "user" + (1 + Math.floor(Math.random() * 10000))
Quando for necessário reutilizar um trecho de um código JavaScript em dois ou mais casos de teste ou ações de macro, a melhor solução é implementar o código como uma ou mais funções JS e salva-las em um arquivo com a extensão .js
no diretório de scripts de repositório de teste.
Por exemplo, vamos supor que seja necessária uma função JS para extrair as primeiras n
palavras de uma string. Podemos criar uma função chamada excerto e coloca-la em um arquivo *.js
no diretório de scripts. Como no arquivo helpers.js
do exemplo abaixo:
test-repo-path/scripts/helpers.js
function excerpt(text, wordCount) {
var words = text.split(' ');
words.splice(wordCount || 10, words.length - 1);
return words;
}
Para usar esta função em um teste, primeiro precisamos "incluir" o arquivo usando a sintaxe includes
:
description: Incluir um arquivo JS e chamar uma função nele
includes: helpers.js
actors:
- actor: ACTOR1
segments:
- segment: 1
actions:
- script: |
var text = "Lorem ipsum dolor sit amet consectetur adipiscing elit"
$log("The first five words are " + excerpt(text, 5).join(", "));
Para incluir vários arquivos JS, o valor da propriedade includes
pode ser especificado como um array de caminhos relativos. Como por exemplo:
includes: [moment.min.js, underscore.min.js, helpers.js]
Dessa forma, os arquivosa serão incuidos na ordem em que eles foram especificados.
O ator do OpenTest executa o código JavaScript usando o interpretador JavaScript Nashorn que acompanha o tempo de execução do Java 8. Há muitas informações sobre o Nashorn na internet, por isso, a documentação do OpenTest não se preocupa em explica-la (Apenas aceite, e use, jovem padawan). A única coisa que é necessário que seja aprofundado é a API Java.type()
que irá permitir o acesso a qualquer classe Java de dentro de um código JavaScript. Como mostrado no exemplo abaixo:
- script: |
var Files = Java.type("java.nio.file.Files");
var Paths = Java.type("java.nio.file.Paths");
var System = Java.type("java.lang.System");
var JavaString = Java.type("java.lang.String");
var content = new JavaString(Files.readAllBytes(Paths.get("C:/content.txt")), "UTF-8");
System.out.println(content);
A capacidade de acessar qualquer classe no tempo de execução do Java a partir do JavaScript irá oferecer aos testadores poder e flexibilidade ilimitados. Por isso deve ser evitado a tentação de "traduzir" trechos de código Java completos para JavaScript.