projeto de robo para automatizac˘^ ao de testes~...

80
PROJETO DE ROB ˆ O PARA AUTOMATIZAC ¸ ˜ AO DE TESTES EM M ´ AQUINAS DE CART ˜ AO DE CR ´ EDITO Luciano Vargas dos Santos Projeto de Gradua¸c˜ ao apresentado ao Curso de Engenharia Eletrˆ onicaedeComputa¸c˜ao da Escola Polit´ ecnica, Universidade Federal do Rio de Janeiro, como parte dos requisitos necess´ arios ` aobten¸c˜ ao do t´ ıtulo de Enge- nheiro. Orientadores: Heraldo Lu´ ıs Silveira de Almeida Fl´ avio Luis de Mello Rio de Janeiro Setembro de 2018

Upload: dodung

Post on 10-Nov-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

PROJETO DE ROBO PARA AUTOMATIZACAO DE TESTES

EM MAQUINAS DE CARTAO DE CREDITO

Luciano Vargas dos Santos

Projeto de Graduacao apresentado ao Curso

de Engenharia Eletronica e de Computacao

da Escola Politecnica, Universidade Federal

do Rio de Janeiro, como parte dos requisitos

necessarios a obtencao do tıtulo de Enge-

nheiro.

Orientadores: Heraldo Luıs Silveira de Almeida

Flavio Luis de Mello

Rio de Janeiro

Setembro de 2018

UNIVERSIDADE FEDERAL DO RIO DE JANEIRO

Escola Politecnica - Departamento de Eletronica e de Computacao

Centro de Tecnologia, bloco H, sala H-217, Cidade Universitaria

Rio de Janeiro - RJ CEP 21949-900

Este exemplar e de propriedade da Universidade Federal do Rio de Janeiro, que

podera incluı-lo em base de dados, armazenar em computador, microfilmar ou adotar

qualquer forma de arquivamento.

E permitida a mencao, reproducao parcial ou integral e a transmissao entre bibli-

otecas deste trabalho, sem modificacao de seu texto, em qualquer meio que esteja

ou venha a ser fixado, para pesquisa academica, comentarios e citacoes, desde que

sem finalidade comercial e que seja feita a referencia bibliografica completa.

Os conceitos expressos neste trabalho sao de responsabilidade do(s) autor(es).

iv

DEDICATORIA

Ao meu amigo e primo Vinıcius (in memoriam), pelos momentos que pudemos

viver ate o inıcio dessa jornada e pelo exemplo que ficara para sempre.

v

AGRADECIMENTO

Agradeco primeiramente a minha famılia pelo apoio e por acreditarem em

mim, dando total liberdade as minhas escolhas e ao meu tempo.

A equipe de robotica UFRJ MinervaBots que me presenteou com uma se-

gunda famılia e verdadeiros amigos e me proporcionou grandes aprendizados, me

ensinando sobretudo o que e espırito de equipe.

Agradeco tambem aos meus colegas de trabalho da Stone Pagamentos, por

permitir o uso do espaco para desenvolvimento desse projeto e permitir a divulgacao

com codigo aberto. E sobretudo pelo confianca e autonomia pra tocar o projeto e

fazer acontecer.

vi

RESUMO

O presente trabalho tem como objetivo proporcionar um ambiente para tes-

tes funcionais em maquinas de cartao de credito, assegurando maior qualidade no

desenvolvimento de software para esse tipo de sistema embarcado. Esses terminais

de pagamento, denominados Point of Sale (POS), possuem especificacoes de segu-

ranca que impoem limitacoes a testes realizados somente por software. Duas dessas

limitacoes sao: os dados de um cartao de chip nao podem ser emulados por soft-

ware, e necessaria a presenca de um cartao fısico; e a insercao de senha do cartao

tambem so possıvel via interacao fısica com o teclado do terminal. Para permitir

preencher essas lacunas para um teste totalmente automatizado, foi desenvolvido um

robo capaz interagir fisicamente com o teclados de terminais POS e realizar insercao

e remocao de cartoes utilizando atuadores. Outros tipos de interacoes de usuario

com aplicacoes do terminal foram automatizadas via software com a ferramenta

Selenium. Nesse trabalho sao descritos o projeto e implementacoes de software,

as ferramentas para configuracao do ambiente de testes e o projeto mecanico do

prototipo do robo. Por fim, serao apresentados os resultados obtidos com exemplos

de cenarios de teste automatizado em aplicacao de pagamento sem necessidade de

interacao humana com o terminal.

Palavras-Chave: robotica, teste de software, garantia de qualidade.

vii

ABSTRACT

The goal of current work is provide an environment for functional testing in credit

card machines, ensuring greater quality on software developing on this kind of em-

bedded system. These payment terminals, knowns as Point of Sale (POS), has some

safety standards that limits tests to be performed only by software. Two of this

limitations are: the data of card chips can’t be emulated by software, it is manda-

tory the presence of a physical card; and the card password also is only possible by

physical interaction with terminal’s keyboard. To overcome these limitations and

allow perform functional testing fully automated, was designed a robot capable of

act physically with POS terminals for card insertion and removal and also for key-

board entry using actuators. Another kinds of user interactions with the terminal

could be performed by software using the Selenium tool. This work describes the

software project and its implementation, the tools used for performing automated

tests and also the mechanical project of the robot prototype. Finally, is presented

the obtained results with exemples of automated test cases in a payment application

without the need of human interaction.

Key-words: robotics, software testing, quality assurance.

viii

SIGLAS

API - Application Programming Interface

CAD - Computer Aided Design ou Desenho Assistido por Computador

CNC - Comando Numerico Computadorizado

EMV - Especificacao de pagamento criada pela Europay, MasterCard e Visa

FDM - Fused Deposition Modeling

IDE - Integrated Development Environment

PCI DSS - Payment Card Industry Data Security Standards

TFT LCD - Thin Film Transistor Liquid Crystal Display

PIN - Personal Identification Number

PLA - Poliacido Lactico

POS - Point Of Sale ou Ponto de Venda

PWM - Pulse Width Modulation

QA - Quality Assurance

ix

RX - Receiver

SWIG - Simplified Wrapper and Interface Generator

TX - Transmitter

UART - Universal Asynchronous Receiver-Transmitter

UML - Unified Modeling Language ou Linguagem de Modelagem Unificada

USB - Universal Serial Bus

x

Sumario

Lista de Figuras xiii

Lista de Tabelas xv

1 Introducao 1

1.1 Tema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Delimitacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.3 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.4 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.6 Descricao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Tecnologias e Ferramentas 5

2.1 C++ e Qt Framework . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2 Testes de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.2.1 Modelo caixa-preta e testes funcionais . . . . . . . . . . . . . 6

2.2.2 Selenium WebDriver . . . . . . . . . . . . . . . . . . . . . . . 7

2.3 Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.4 Impressao 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5 Point of Sales (POS) . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.6 Aplicacao de Pagamento . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Descricao do Projeto 21

3.1 Diagrama de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.1.1 PosTestTool . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.1.2 CardController . . . . . . . . . . . . . . . . . . . . . . . . . . 22

xi

3.1.3 KeyboardController . . . . . . . . . . . . . . . . . . . . . . . . 23

3.1.4 PrinterController . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.1.5 PosObject e KeyMap . . . . . . . . . . . . . . . . . . . . . . . 23

3.1.6 PosObjectFactory e PosModel . . . . . . . . . . . . . . . . . . 23

3.1.7 AtCore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2 Controle da impressora 3D . . . . . . . . . . . . . . . . . . . . . . . . 24

3.3 Controle do teclado . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.4 Insercao e remocao de cartao . . . . . . . . . . . . . . . . . . . . . . . 39

3.5 Biblioteca Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4 Testes e Resultados Experimentais 51

5 Conclusao 58

5.1 Conclusoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

5.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Bibliografia 61

A Codigo Arduino 64

xii

Lista de Figuras

1.1 EFTPOS Terminal Testing Robot fornecido pela Abrantix®. . . . . . . . 3

2.1 Representacao do modelo de testes caixa-preta. . . . . . . . . . . . . . . 7

2.2 Imagem capturada de pesquisa com Google usando Selenium. . . . . . . . 8

2.3 Alguns modelos do Arduino. . . . . . . . . . . . . . . . . . . . . . . . . 9

2.4 Exemplos de modulos de sensores. . . . . . . . . . . . . . . . . . . . . . 10

2.5 Arduino Uno com shield ethernet. . . . . . . . . . . . . . . . . . . . . . 10

2.6 Arduino Uno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.7 Impressora 3D Anet® A6. . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.8 POS modelo PAX® S920 distribuıdo pela Stone Pagamentos® S.A. . . . 16

2.9 Modelo PAX® S920 com o MAMBA em execucao. . . . . . . . . . . . . 18

2.10 web inspector do navegador Chromium na aplicacao de pagamento do

MAMBA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.11 exemplos de paginas da aplicacao de pagamento. . . . . . . . . . . . . . 19

2.12 Diagrama de sequencia da aplicacao de pagamento. . . . . . . . . . . . . 20

3.1 Diagrama de classe da biblioteca PosTestTool. . . . . . . . . . . . . . . . 22

3.2 Diagrama de classes simplificado do controle da impressora 3D. . . . . . . 25

3.3 Vista lateral do terminal PAX® S920 mostrando inclinacao do plano do

teclado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.4 Modelo da base de apoio do POS. . . . . . . . . . . . . . . . . . . . . . 29

3.5 POS PAX® S920 posicionado sobre a base de apoio. . . . . . . . . . 29

3.6 Modelagem da peca que prende a caneta capacitiva a impressora 3D. . . . 30

3.7 foto mostrando acoplamento da caneta a impressora 3D. . . . . . . . . . 30

3.8 Visao frontal do aparato. . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.9 Modelo 3D da peca que limita o fim de curso do eixo Z. . . . . . . . . . . 32

xiii

3.10 Peca que limita o fim de curso do eixo Z em foto do projeto real. . . . . . 33

3.11 Foto do projeto real proximo ao botao de fim de curso do eixo Z. . . . . . 33

3.12 Diagrama de classes que implementam atuador do teclado. . . . . . . . . 34

3.13 Exemplo de diferencas no layout do teclado. . . . . . . . . . . . . . . . . 35

3.14 Ilustracao do sistemas de coordenadas do referencial do POS. . . . . . . . 36

3.15 Visao lateral do modelo 3d do atuador linear. . . . . . . . . . . . . . . . 39

3.16 Atuador linear impresso em PLA. . . . . . . . . . . . . . . . . . . . . . 40

3.17 Modelo 3D da peca que prende cartoes de credito. . . . . . . . . . . . . . 40

3.18 aparato completo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3.19 cartao fixado ao atuador. . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3.20 Esquema da ligacao eletronica do servo com o Arduino. . . . . . . . . . . 42

3.21 vista lateral, arduino fixado ao aparato. . . . . . . . . . . . . . . . . . . 43

3.22 Pinos de comunicacao serial do Arduino. . . . . . . . . . . . . . . . . . . 44

3.23 Resposta serial da aplicacao do Arduino. . . . . . . . . . . . . . . . . . . 46

3.24 Diagrama sequencial da insercao de cartao. . . . . . . . . . . . . . . . . 48

4.1 Aplicacao para teste da API do robo. . . . . . . . . . . . . . . . . . . . 51

4.2 Posicoes do cartao em resposta aos metodos de insercao e remocao. . . . . 52

4.3 Diagrama do ambiente de testes. . . . . . . . . . . . . . . . . . . . . . . 53

4.4 Capturas de tela realizas em teste automatizado. . . . . . . . . . . . . . 56

xiv

Lista de Tabelas

2.1 Caracterısticas do Arduino Uno [1]. . . . . . . . . . . . . . . . . . . . 12

2.2 Caracterısticas da impressora 3D Anet® A6 [2]. . . . . . . . . . . . . 14

2.3 PAX® S920 distribuıdo pela Stone Pagamentos® S.A. . . . . . . . . 17

3.1 Lista de firmwares suportados pelo AtCore[3]. . . . . . . . . . . . . . 24

4.1 Tempo de execucao de transacao usando a PosTestTool. . . . . . . . . 57

xv

Capıtulo 1

Introducao

1.1 Tema

O tema deste projeto e a automatizacao de testes funcionais em aplicacoes de

maquinas de cartao de credito. Assim, e descrito o projeto um robo com atuadores

capaz de realizar insercao e remocao de cartoes e tambem pressionamento de teclas

nas maquinas de cartao.

1.2 Delimitacao

O objeto de estudo desse trabalho sao terminais POS (Point of Sales ou

Ponto de Venda). Portanto o robo para testes e projetado para se adequar a esse

tipo de dispositivo. Vale tambem ressaltar que o intuito do projeto e ter um robo

para atuar sobre uma variedade de dispositivos desse tipo, entretanto a fim de se

ter uma prova de conceito, parte do projetos ficou delimitado para atender a apenas

um modelo de POS.

1.3 Justificativa

Para se colocar um software em producao com um mınimo de qualidade e

necessario a realizacao de testes para encontrar o maximo de erros possıvel e corrigi-

los antes que possam causar uma ma experiencia para o usuario final.

Testes de software quando feitos de maneira manual podem ser bastante cus-

1

tosos por exigir muitas horas de trabalho e tambem podem incorrer em muitos erros

por se tratarem de tarefas longas e repetitivas, estando o trabalhador sujeito ao

cansaco e eventual distracao no processo. Assim, sempre que possıvel, a automa-

tizacao de testes de software garante maior consistencia e confiabilidade uma vez

que uma rotina de testes, se bem implementada, sera executada da mesma forma.

Em dispositivos POS e necessaria interacao fısica com o dispositivo para

realizacao de um pagamento. Portanto, para completa automatizacao de testes, e

necessario o uso de atuadores roboticos para realizacao de tarefas como insercao de

cartao de credito e digitacao com o teclado do dispositivo. Dessa forma, o projeto

desenvolvido nesse trabalho se torna uma ferramenta importante para garantia da

qualidade de software de dispositivos POS, permitindo testes mais consistentes e

sem necessidade de interacao humana.

1.4 Objetivos

O presente projeto tem intuito de fornecer um robo como ferramenta para

testes automatizados em maquinas de cartao de credito a fim de garantir maior

qualidade no desenvolvimento de softwares para esse tipo de dispositivo. Dessa

forma, tem-se como objetivos especıficos:

• Construir um robo capaz de inserir, remover cartoes de credito e pressionar

teclas.

• Projetar uma arquitetura de software do robo.

• Fornecer como ferramenta para analistas de teste uma API (Application Pro-

gramming Interface) para controle do robo.

1.5 Metodologia

Primeiramente foi feita uma pesquisa de produtos disponıveis no mercado para

solucao do problema. As solucoes encontradas utilizam bracos roboticos ou sistema

de controle de 3 eixos para acionamento das teclas de dispositivos POS e a solucao

que mais se aproximou da proposta foi o EFTPOS Terminal Testing Robot fornecido

2

pela Abrantix® [4]; consiste em um robo com um sistema de controle CNC (Co-

mando Numerico Computadorizado) de 3 eixos para pressionar teclas (ver Figura

1.1) e um outro atuador para insercao/remocao de cartao.

Figura 1.1: EFTPOS Terminal Testing Robot fornecido pela Abrantix® [4].

Seguindo essa referencia, a ideia foi construir o robo reproduzindo o controle

por tres eixos. Entretanto, dado a complexidade do projeto mecanico, optou-se por

fazer o robo a partir da adaptacao uma impressora 3D por dois principais motivos:

disponibilidade de APIs para o controle e como seria necessario a fabricacao de pecas

para o robo, a propria impressora poderia ser usada para prototipacao das pecas.

Assim, para acionamento das teclas bastaria utilizar um controle da impressora

por coordenadas cartesianas, mas trocando o extrusor de filamento por uma peca

adequada para pressionar as teclas. Decidiu-se usar uma caneta capacitiva para tal

tarefa, de modo que ela tambem pudesse ser usada futuramente para interacao com

telas touchscreen.

Uma vez que o controle da impressora ja estava disponıvel a partir de uma

biblioteca de codigo aberto, foi projetado primeiro o atuador para insercao e remocao

de cartao de credito no POS. A escolha foi utilizar um servo-motor controlado por um

Arduino, sendo necessario tambem utilizar um sistema mecanico para transformar

o movimento de rotacao do servo em movimento linear.

3

Para identificar a posicao das teclas de um POS de forma simples, as carac-

terısticas fısicas do dispositivos foram descritas em um arquivo texto que e usado

pelo software para que o robo aperte as teclas na posicao correta.

Todo o software para desenvolvimento dos atuadores foi feito utilizando uma

aplicacao com interface grafica. Depois de testes e validacao, por fim foi projetada

uma arquitetura de software para desacoplar a GUI (Graphical User Interface ou

interface grafica do usuario) do que viria ser a API de controle do robo.

Para completar o ambiente de testes e automatizar outras interacoes com

as interfaces graficas do terminal POS, e possıvel utilizacao de ferramentas que

se comunicam diretamente o software de terminais POS de desenvolvimento. O

projeto foi desenvolvido com conhecimento e permissao da Stone Pagamentos S.A

[5], utilizando terminais de desenvolvimento com um dos sistemas desenvolvidos pela

empresa.

1.6 Descricao

O capıtulo 2 apresenta as principais tecnologias e ferramentas utilizadas para

implementacao do projeto com breves exemplos de utilizacao.

O capıtulo 3 detalha o projeto de software para controle do robo e tambem des-

creve como foi feita a adaptacao da impressora 3D e projeto eletronico e fısico para

construcao do robo

O capitulo 4 mostra um caso de teste automatizado utilizando a API de comu-

nicacao com o robo.

O capıtulo 5 apresenta as conclusoes e pontos de melhoria para trabalhos futuros.

4

Capıtulo 2

Tecnologias e Ferramentas

Nesse capıtulo serao apresentadas as tecnologias e ferramentas utilizadas para

implementacao tecnica do projeto. Tambem sera apresentada ao final do capıtulo o

sistema a que se aplica o ambiente de testes.

2.1 C++ e Qt Framework

O C++[6] e uma linguagem de programacao criada por Bjarne Stroustrup

em 1983 no Bell Labs, desenvolvida inicialmente como uma extencao a lingua-

gem C; e uma linguagem multiparadigma, incluindo orientacao a objetos, pro-

gramacao generica e linguagem imperativa. Ainda hoje a linguagem esta em cons-

tante evolucao, sendo o padrao ISO/IEC 14882, conhecido como C++17 (ou C++1z)

a sua ultima revisao, lancada em dezembro de 2017[7].

O Qt, criado em 1993, e bastante conhecido como um framework para de-

senvolvimento de aplicacoes graficas multiplataforma com C++, mas ele oferece

tambem um grande conjunto de ferramentas para desenvolvimento de aplicacoes

console e bibliotecas. Ele e um toolkit (conjunto de ferramentas) com mais de 55

modulos e mais de 1650 classes, com foco em alto desempenho e produtividade [8].

O Qt pode ser encontrado em sistemas de bordo de carros, avioes, em aplicacoes

medicas, automacao industrial. Atualmente na versao 5.11.0, ele e mantido e li-

cenciado pela The Qt Company e sendo tambem um framework de codigo aberto,

recebe muitas contribuicoes de comunidades de software livre [9].

Uma das grandes contribuidoras do Qt, e atualmente a maior comunidade

5

de software livre do mundo, e a KDE, bastante conhecida pelo ambiente grafico

para Linux KDE Plasma [10]. A comunidade foi fundada em 1996 e produz varios

aplicacoes e bibliotecas utilizando o Qt como principal ferramenta.

O Qt oferece modulos para comunicacao via porta serial, bluetooth, NFC

ou rede para o controle de dispositivos perifericos ou equipamentos, oferecendo ao

desenvolvedor classes de simples utilizacao sem a necessidade de implementacao de

protocolos, o que facilitou o desenvolvimento da comunicacao com o robo.

2.2 Testes de Software

Na criacao de um software e pratica comum os desenvolvedores realizarem

testes para assegurar que o programa esta de acordo com os requisitos do sistema.

Entretanto, e pouco provavel que o desenvolvedor consiga cobrir todos possıveis ca-

sos durante o teste e e muito comum que no desenvolvimento de alguma funcionali-

dade, alguma outra funcionalidade ja desenvolvida seja impactada e o desenvolvedor

nao perceba a relacao.

Os processos de Quality Assurance (QA) [11] tem como objetivo explorar um

sistema em busca de erros a fim de minimizar os riscos deles serem encontrados pelo

usuario final e assim garantir uma melhor qualidade de software.

2.2.1 Modelo caixa-preta e testes funcionais

Um importante modelo de testes e o teste caixa-preta. Nesse modelo e levado

em conta somente os requisitos do software e nao se utiliza dos detalhes de sua

implementacao na realizacao de um caso de teste. O programa e tratado como

uma caixa-preta; sao realizados diversos casos de teste com varias possibilidades de

entradas e os dados de saıda sao comparados com o que se espera dos requisitos[12].

6

Figura 2.1: Representacao do modelo de testes caixa-preta.

Uma aplicacao do modelo caixa-preta sao os testes funcionais, usados para

se testar funcionalidades do software que esta sendo desenvolvido. Para realizacao

desse tipo de testes, existem varios softwares para automatizacao de tarefas; nesse

projeto foi utilizado o Selenium WebDriver [13] para aplicacoes Qt.

2.2.2 Selenium WebDriver

O Selenium e uma ferramenta que permite automatizacao de tarefas em na-

vegadores web. Foi criado inicialmente como proposta para automatizar testes em

sites, mas nao esta restrito a somente isso [13]. Com ele e possıvel simular a uti-

lizacao de uma pagina web por um usuario. No exemplo a seguir um exemplo escrito

em Python, o o Selenium e utilizado para automatizar uma busca no Google usando

o navegador Chromium e em seguida um printscreen de tele e capturado (ver Figura

2.2).

1 import time

2 from selenium import webdriver

3 from selenium.webdriver.common.keys import Keys

4

5 browser = webdriver.Chrome()

6 browser.get('http://www.google.com')

7

8 search = browser.find_element_by_name('q') # procura caixa de pesquisa

9 search.send_keys("busca no google usando selenium")

10 search.send_keys(Keys.RETURN) # pressiona tecla RETURN

11 browser.save_screenshot("google_result.png") # salva imagem do navegador

12 time.sleep(5) # espera 5 segundos para ver resultado

13 browser.quit()

7

Figura 2.2: Imagem capturada de pesquisa com Google usando Selenium.

No exemplo explicitado, o proprio script que automatiza a busca e o res-

ponsavel por iniciar o navegador na pagina desejada. Ja no caso do projeto, a

pagina web alvo esta sendo executada em uma aplicacao embarcada no POS. O Se-

lenium tambem permite a automatizacao de paginas remotas via arquitetura cliente-

servidor. Para tal, e necessario que a aplicacao alvo tenha um servidor do Selenium

para que o script cliente possa se comunicar pela rede. No projeto foi utilizada uma

implementacao de codigo aberto do Selenium WebDriver para aplicacoes Qt feita

pela Cisco® [14]. Assim, a aplicacao Qt embarcada inicia um servidor do Selenium

em uma determinada porta e dessa forma o script como cliente pode se comunicar

com a aplicacao remota acessando o endereco disponibilizado.

2.3 Arduino

O Arduino e uma plataforma de prototipagem eletronica criada por Massimo

Banzi, David Cuartielles, Tom Igoe, Gianluca Martino e David Mellis em 2005 [15].

A placa original foi projetada sobre um microcontrolador Atmel AVR® com suporte

a entradas digitais e analogicas, e tambem alguns componentes complementares

como entrada USB e conector para alimentacao por fonte de tensao.

8

O objetivo do projeto era fornecer uma plataforma de baixo custo, expansıvel

e acessıvel para novatos e profissionais. Hoje a plataforma e bastante difundida

e aplicada em diversas areas, sendo possıvel encontrar o Arduino sendo usado em

exposicoes interativas de arte ou ate em projetos comerciais.

Tanto o hardware quanto software (IDE) sao licenciados sob livre direito de copia,

assim podem ser encontradas no mercado e em comunidades de software livre di-

versas variacoes do Arduino e uma grande variedade de modulos que se conectam a

placa. A Figura 2.3 apresenta exemplos de placas oficiais.

Figura 2.3: Alguns modelos do Arduino.

Alem das placas bases, ha no mercado muitos modulos de sensores (ver Figura

2.4) e placas de expansao, conhecidas como shields que tem intuito de adicionar mais

funcionalidade ao Arduino sem que o usuario leigo em eletronica tenha necessidade

de criar suas proprias placas. A Figura 2.5 apresenta um shield ethernet conectado

a um Arduino.

9

Figura 2.4: Exemplos de modulos de sensores.

Figura 2.5: Arduino Uno com shield ethernet.

A linguagem de programacao padrao do Arduino e o C++, que combina com a

biblioteca Wiring fornecendo funcoes e classes para facilitar o uso de entradas e

saıdas, comunicacao serial, etc. O trecho de codigo a seguir exemplifica a estrutura

basica do codigo principal de um programa em Arduino:

10

void setup()

{

// coloque instruc~oes para serem executadas na inicializac~ao

}

void loop()

{

// o codigo principal deve ficar aqui e ira executar repetidamente

}

As funcoes setup() e loop() devem ser obrigatoriamente implementadas. A

funcao setup() sera executada no boot do Arduino apenas uma vez, ja a funcao loop,

sera executada logo apos ao termino da execucao de setup() e ficara executando

repetidamente.

Para o projeto, o Arduino foi utilizado para fazer para o controle de um

servo-motor para insercao de cartao que sera melhor detalhada no capıtulo 3. O

modelo utilizado foi o Arduino Uno, ilustrado na figura 2.6 e detalhado na Tabela

2.3.

Figura 2.6: Arduino Uno.

11

Tabela 2.1: Caracterısticas do Arduino Uno [1].

Microcontrolador ATmega328P

Tensao de Entrada (recomendada) 7-12V

Tensao de entrada (limite) 6-20V

Pinos de entrada/saıda digital 14

Pinos de entrada/saıda digital com PWM 6

Pinos de entrada analogica 6

Corrente Contınua por pino 20 mA

Corrente Contınua por pino 3,3V 50 mA

Memoria Flash 32 KB

SRAM 2 KB

EEPROM 1 KB

Clock 16 MHz

2.4 Impressao 3D

Impressao 3D e uma tecnologia de prototipagem rapida que permite a fabricacao

de um modelo 3D desenhado por CAD (Computer Aided Design ou Desenho Assis-

tido por Computador) por meio da adicao de um material. A grande vantagem da

prototipagem rapida e permitir fabricar uma peca em poucos minutos ou horas e

assim testa-la para validar o modelo, o que acelera muito o desenvolvimento ate se

ter um modelo final[16].

12

Figura 2.7: Impressora 3D Anet® A6.

As impressoras 3D tem se tornado mais acessıveis financeiramente e tambem

mais compactas. Com isso estao sendo vastamente utilizadas nao so na industria,

mas tambem para uso domestico. As impressoras mais populares sao as que usam

tecnologia FDM (Fused Deposition Modeling), que consiste na fusao e deposicao de

um polımero. Esses polımeros sao comercializados em rolos na forma de filamentos

e existem em diversos materiais, onde os mais comuns sao o PLA (poliacido latico)

e o ABS (Acrilonitrila Butadieno Estireno). O material e aquecido por uma peca

chamada cabeca extrusora ou bico extrusor ate fundir e depositado em camadas

sobrepostas.

13

A Figura 2.7 apresenta o modelo que foi utilizado no projeto para impressao

das pecas e posteriormente foi adaptado como robo de testes. A Anet® A6 [2] e

uma impressora de baixo custo do tipo FDM com estrutura em acrılico. A Tabela

2.4 apresenta algumas especificacoes do modelo.

Tabela 2.2: Caracterısticas da impressora 3D Anet® A6 [2].

Volume de impressao 220x220x250mm

Velocidade de impressao 100mm/s

Precisao de espessura de camada 0,1-0,3mm

Acuracia em Posicao XY 0,012mm

Acuracia em Posicao Z 0,004mm

Material para impressao ABS, PLA, HIPS, etc

Tipo de arquivo G-code

Para impressao de um modelo 3D e necessario a utilizacao de uma ferramenta

denominada fatiadora ou slicer que tem como funcao converter um modelo 3D para

o formato que a impressora consegue interpretar para fabricacao de uma peca. O

G-code e uma linguagem de programacao para maquinarios que usam Comando

Numerico Computadorizado (CNC), no caso da impressao 3D ele basicamente e

composto por comandos para posicionamento geometrico da cabeca extrusora, velo-

cidade de extrusao, controle de temperatura do bico extrusor, temperatura da base,

etc. Como exemplo, o comando G-code a seguir tem como resultado mover o bico

extrusor para as coordenadas (X,Y,Z) = (10.1, 6.32, 2.34) mm.

G1 X10 . 1 Y6.32 Z2 .34

O controle da impressora necessario para as funcoes do robo e feito atraves do

envio de comandos G-code para impressora com auxılio de uma API, que e explicado

com mais detalhes na Sessao 3.2. Para modelagem das pecas impressas do robo foi

utilizado CAD Onshape [17], uma ferramenta de modelagem 3D online e o material

utilizado foi o PLA.

14

2.5 Point of Sales (POS)

Popularmente conhecido como ”maquininha de cartao”ou ”maquineta de

cartao”, o POS e um dispositivo embarcado para processamento de pagamentos

com cartao do tipo chip-and-PIN. Trata-se de um tipo de pagamento especificado

pelas normas EMV [18], que sao normas de pagamento criadas pela Europay®,

MasterCard® e Visa®, as tres empresas que criaram originalmente os padroes e

hoje os padroes sao mantidos pela EMVCo. Numa transacao chip-and-PIN, a au-

tenticacao e feita por meio de um identificador de 4 ou 6 dıgitos, o PIN (Personal

Identification Number) e e necessaria uma troca de mensagens entre o dispositivo

POS e o chip do cartao de credito. A norma ISO/IEC 7816-3 define o protocolo de

comunicacao entre chip e leitor de cartao, as mensagens sao trocadas por comandos

chamados de APDU (Application Protocol Data Units)[19].

O acesso a etapa de autenticacao do PIN e limitado de forma que para faze-lo

e necessario realizar uma chamada a uma funcao disponibilizada pela fabricante do

POS que executa a captura do PIN pela teclado do dispositivo e ja realiza o processo

de autenticacao com o chip do cartao. Assim nao e possıvel fazer interceptacao da

senha no fluxo de pagamento e por isso nao e possıvel inserir via software um PIN

para realizacao de testes em ambiente de producao.

Sao encontrados no mercado uma grande variedade de terminais POS. Para

o usuario, os terminais se diferenciam em portabilidade, duracao de bateria, tipos

de conectividade, tipo de tela. Para o desenvolvedor de aplicacoes para POS, cada

fabricante disponibiliza sua API (Application Programming Interface ou Interface

de Programacao de Aplicacoess) de desenvolvimento proprietaria. Alem disso, cada

modelo possui suas especifidades de sistema operacional e arquitetura de processa-

dor. Atualmente, as fabricantes de terminais POS lideres do mercado sao: Ingenico®

(Estadunidense), Verifone® (Francesa) e PAX® (Chinesa).

No Brasil, os dispositivos POS sao fornecidos pelas adquirentes, que sao as

instituicoes responsaveis por credenciar lojistas a transacionarem pagamentos de

credito e debito e tambem sao responsaveis por fazer o processamento das transacoes.

Para realizar uma transacao usando cartao de credito, alem da da leitura dos dados

do cartao pelo POS, e necessario autorizacao do emissor do cartao que verifica se o

15

portador do cartao possui saldo para transacionar e tambem e necessaria autorizacao

da bandeira do cartao, que e quem regula as regras de processamento de transacoes.

Quem realiza esse intermedio entre emissor, bandeira, portador do cartao e lojistas

sao as adquirentes. Segundo a ABECS (Associacao Brasileira das Empresas de

Cartoes de Credito e Servicos), o mercado de adquirencia transacionou so no primeiro

trimestre de 2018, 220 bilhoes de reais [20]. As quatro maiores adquirentes do

mercado atualmente sao: Cielo®, Rede®, Getnet® e Stone Pagamentos®.

Cada adquirente fornece dispositivos POS com suas proprias aplicacoes pro-

prietarias. O modelo utilizado para esse projeto foi o S920 da fabricante PAX®

com a aplicacao desenvolvida pela Stone Pagamentos®. A Tabela 2.3 apresenta as

caracterısticas do terminal e a Figura 2.8 apresenta uma ilustracao do modelo em

questao.

Figura 2.8: POS modelo PAX® S920 distribuıdo pela Stone

Pagamentos® S.A.

16

Tabela 2.3: PAX® S920 distribuıdo pela Stone Pagamentos® S.A.

Processador ARM11 32-bit 400MHz

Memoria Flash 256MB

Memoria RAM 128MB

Display 3,5 polegadas, 240x320 pixels TFT LCD

Conectividade 2G, 3G, Wi-Fi e Bluetooth

Sistema Operacional Linux

2.6 Aplicacao de Pagamento

O MAMBA, acronimo para Manufacturer Agnostic Multi-platform Base Ap-

plication, e a aplicacao base desenvolvida pela Stone Pagamentos® S.A. para seus

terminais POS lancados desde marco de 2018. A proposta de desenvolvimento era

fazer uma aplicacao que pudesse ser independente da API dos fabricantes de POS,

a fim de se ter uma aplicacao unica para diferentes terminais. Assim, melhorando

a manutenibilidade e escalabilidade da plataforma. Antes do MAMBA, cada ter-

minal possuıa seu proprio software, o que trazia o inconveniente de ter que se dar

manutencao a diferentes sistemas com o mesmo proposito.

17

Figura 2.9: Modelo S920 com o MAMBA em execucao.

Um diferencial da plataforma e que as suas diversas funcoes sao divididas em

aplicativos, possuindo um aplicativo para pagamento, outro aplicativo para confi-

guracoes, aplicativo para geracao de relatorio de transacoes. A plataforma foi desen-

volvida usando C++ com o framework Qt e alem disso, as interfaces dos aplicativos

(frontend) sao todos feitos utilizando as tecnologias web: HTML, CSS e JavaScript

(ver Figura 2.10). Dessa forma, na proposta de automatizacao de testes funcionais,

e possıvel utilizar a ferramenta Selenium WebDriver, apresentada na sessao 2.3.

18

Figura 2.10: web inspector do navegador Chromium na aplicacao de paga-

mento do MAMBA.

(a) Pagina de selecao

do metodo de paga-

mento.

(b) Pagina de entrada

da senha do cartao.

(c) Pagina de paga-

mento aprovado.

Figura 2.11: exemplos de paginas da aplicacao de pagamento.

A Figura 2.11 mostra algumas capturas de tela da aplicacao de pagamento

e a Figura 2.12 apresenta o diagrama de sequencia com um dos fluxos possıveis

de pagamento com sucesso. Inicialmente o usuario insere o cartao no POS para

iniciar fluxo de pagamento. Nesse fluxo, ele escolhe a forma de pagamento (credito,

debito), insere o valor desejado para pagamento, o numero de parcelas caso seja

escolhido credito e entao o PIN do cartao e solicitado. Caso a senha esteja correta,

a transacao e enviada para adquirente que ira fazer o processamento da transacao e

retornar o resultado. Por fim, o recibo da transacao e impresso no caso de sucesso

19

(caso contrario uma tela de erro e exibida) e a aplicacao solicita que o usuario retire

o cartao para se encerrar.

Figura 2.12: Diagrama de sequencia da aplicacao de pagamento.

20

Capıtulo 3

Descricao do Projeto

Nesse capıtulo sera discutida a implementacao do robo, apresentando as pecas

fabricadas no projeto mecanico e mais detalhadamente a implementacao a nıvel de

software. Para descricao do software, alem de trechos do codigo, serao apresentados

modelos utilizando ferramentas do UML (Unified Modeling Language ou Linguagem

de Modelagem Unificada), como o diagrama de classes [21].

3.1 Diagrama de classes

O projeto de software e composto de por dois modulos: o PosTestTool que

corresponde a todas as classes desenvolvidas no projeto para permitir o controle

do robo e a biblioteca AtCore que realiza o controle de posicao da impressora 3D.

A Figura 3.1 apresenta o diagrama de classes completo do projeto. A seguir sera

apresentada um resumo da funcao de cada classe na arquitetura do projeto.

21

Figura 3.1: Diagrama de classe da biblioteca PosTestTool.

3.1.1 PosTestTool

Com intuito de facilitar o uso da biblioteca, foi utilizado o padrao de design

de software comumente utilizado em programacao orientada a objetos conhecido

como Facade [22]. O Facade e um padrao de design em que uma classe prove uma

interface unica para acesso a funcoes de mais de um subsistema, como por exemplo,

um conjunto de classes. Assim, a classe PosTestTool, sendo um Facade, possui todos

os metodos necessarios para o usuario da biblioteca controlar o robo.

3.1.2 CardController

CardController e a classe responsavel por realizar a conexao serial com o

Arduino e enviar comandos para controle do atuador de insercao e remocao de

cartao de credito.

22

3.1.3 KeyboardController

A classe KeyboardController e a responsavel por receber as entradas de teclas

desejadas e enviar para a classe PrinterController as coordenadas para acionamento

das teclas para se ter a entrada desejada, podendo ser o acionamento de uma tecla

especıfica ou a insercao de um texto.

3.1.4 PrinterController

E a classe que recebe as coordenadas desejadas para posicao cartesiana da

cabeca extrusora da impressora 3D e realiza o controle por meio da biblioteca At-

Core.

3.1.5 PosObject e KeyMap

A classe PosObject descreve o modelo do POS com as caracterısticas ne-

cessarias para o controle do robo, como a lista de KeyMap que e uma struct formada

pela posicao cartesiana da tecla e a lista de caracteres contidos nela.

3.1.6 PosObjectFactory e PosModel

A classe PosObjectFactory utiliza o padrao de design de software conhecido

como Factory, uma padrao criacional que tem como objetivo a criacao de um objeto

de forma que o usuario da classe nao precise conhecer os detalhes de implementacao

para criacao do objeto. Essa classe tem como objetivo retornar um objeto da classe

PosObject a partir da selecao do modelo de POS desejado, representado pelo tipo

enumerado PosModel.

3.1.7 AtCore

A classe AtCore pertence a uma biblioteca externa AtCore, criada por um

grupo de desenvolvedores da KDE com objetivo de realizar o controle de impressoras

3D. A utilizacao da classe PrinterController como intermediaria entre a Keyboard-

Controller e a AtCore permite que seja mais facil a substituicao da biblioteca AtCore

se necessario, uma vez que se trata de um componente externo.

23

3.2 Controle da impressora 3D

Para realizar o controle da impressora 3D foi utilizada a biblioteca AtCore

criada pela KDE pela facilidade de reuso de codigo e para evitar a implementacao de

uma solucao ja disponıvel sobre licenca de codigo aberto. A biblioteca AtCore e uma

API generica para controle de impressoras 3D, isso e possıvel pois as impressoras

3D em sua maioria possuem firmwares com protocolos de comunicacao abertos.

A Tabela 3.2 mostra a relacao de firmwares suportados pela biblioteca; com ela

e possıvel controlar impressoras 3D diretamente por conexao serial usando portas

USB ou exportar em arquivos que podem ser utilizados por impressoras que possuem

leitoras de cartoes SD.

Tabela 3.1: Lista de firmwares suportados pelo AtCore[3].

Firmware Controle por USB Controle por SD

Repetier X X

Marlin X X

Teacup X

APrinter X

SPrinter X

Smoothie X

GRBL X

A figura 3.2 mostra o diagrama de classe da relacao com as classes Prin-

terController com as metodos da classe AtCore necessarios para o controle da im-

pressora 3D. O metodo PrinterController::setXYPosition() e o responsavel por en-

viar a impressora a posicao desejada no plano XY, ja o metodo PrinterControl-

ler::setZPosition() e utilizado para mover a cabeca extrusora verticalmente para aci-

onamento de teclas. O metodo PrinterController::wait() permite definir um tempo

em milissegundos para que a impressora nao realize nenhum movimento, o que e ne-

cessario para interacao com uma mesma tecla para insercao de diferentes caracteres.

24

Figura 3.2: Diagrama de classes simplificado do controle da

impressora 3D.

O trecho de codigo a seguir mostra como e feita a conexao com a impressora

3D. No construtor da classe PrinterController e feito uma busca em todos os dispo-

sitıvos serial conectados ao computador pela string de identificacao do fabricante do

dispositivo, ”1a86”no caso da impressora Anet® A6. O identificador da porta serial

correspondente e entao passado como parametro ao metodo AtCore::initSerial() e

caso haja falha na conexao, o metodo dispara uma excecao uma vez que a conexao

com a impressora e estritamente necessaria para o controle do robo. Caso contrario,

o metodo AtCore::home() e chamado, ele e responsavel por realizar a calibracao da

origem do sistema de coordenadas cartesianas, em seguida e definida uma posicao

segura no eixo Z que garante que o atuador do teclado se mova livremente no plano

XY sem entrar em contato com o dispositivo POS.

25

PrinterController::PrinterController(QObject* parent)

: QObject(parent)

{

QString serialPort;

foreach (const QSerialPortInfo& devinfo, QSerialPortInfo::availablePorts()) {

qDebug() << "Serial port: " << devinfo.portName();

if (devinfo.manufacturer().contains("1a86")) {

serialPort = devinfo.portName();

}

}

if (core.initSerial(serialPort, QSerialPort::Baud115200) == true) {

core.home();

moveZ(safeZPosition);

}

else

{

throw QSerialPort::OpenError;

}

}

PrinterController::~PrinterController()

{

core.close();

}

No destrutor da classe PrinterController e chamado o metodo AtCore::close(),

ele e responsavel por fechar qualquer conexao ainda ativa com uma porta serial,

dessa forma e garantido que ao se encerrar uma aplicacao que utilize a biblioteca, a

conexao com a impressora 3D seja devidamente encerrada.

A seguir, o trecho de codigo mostra como e feita a implemetacao dos metodos

para movimentacao da impressora 3D. Como explicado na Secao 2.4, esse controle

e dado pelo envio de comandos GCode para impressora. Apenas dois comandos

GCode sao necessarios para o controle desejado. O comando G0, que e utilizado

para movimentacao linear rapida para coordenadas passadas por parametro, e o

comando G4 utilizado para realizar uma espera.

O controle por coordenadas pode ser feito utilizando posicao absoluta ou posicao

relativa, passando como parametro a coordenada final desejada ou o deslocamento

em milımetros respectivamente. Nesse caso e utilizado apenas o controle por posicao

26

absoluta, devendo-se executar uma chamada ao metodo AtCore::setAbsolutePosition()

antes de enviar o comando GCode pelo metodo AtCore::pushCommand().

void PrinterController::setXYPosition(QPointF point)

{

core.setAbsolutePosition();

core.pushCommand(

GCode::toCommand(GCode::G0, QStringLiteral("X%1 Y%2")

.arg(QString::number(point.x()), QString::number(point.y()))));

}

void PrinterController::setZPosition(qreal z)

{

core.setAbsolutePosition();

core.pushCommand(

GCode::toCommand(GCode::G0, QStringLiteral("Z%1")

.arg(QString::number(z))));

}

void PrinterController::wait(int millisseconds)

{

core.pushCommand(

QStringLiteral("G4 P%1")

.arg(QString::number(millisseconds)));

}

Com esses metodos explicitados ja e possıvel realizar o controle de entradas

pelo teclado do dispositivo POS.

27

3.3 Controle do teclado

Para realizar a interacao com o teclado fısico do dispositivo POS, e utili-

zado um controle por coordenadas cartesianas. Como explicitado na Secao 3.2, a

classe PrinterController apresenta apenas duas funcoes pra controle da impressora

3D, uma para movimentacao da cabeca extrusora no plano XY e outra para mo-

vimentacao no eixo Z. Tendo apenas esses dois tipos de movimentacao disponıveis,

o controle e feito da seguinte forma: utiliza-se a movimentacao no plano XY para

alinhamento do atuador com a tecla desejada e a movimentacao do eixo Z para

realizar o pressionamento da tecla.

Pelo design fısico do dispositivo POS, o plano das teclas possui uma inclinacao

com relacao ao plano da base de apoio como e possıvel observar na Figura 3.3. Dessa

forma, para nao precisar realizar um deslocamento no eixo Z diferente para cada

tecla e para garantir que a caneta as pressione ortogonalmente, uma base de apoio e

colocada para posicionar o plano das teclas paralelo ao plano da base da impressora

3D e consequentemente paralelo ao plano XY de movimentacao da cabeca extrusora

da impressora.

Figura 3.3: Vista lateral do terminal PAX® S920 mostrando inclinacao do plano do

teclado.

Na figura 3.4 e possıvel observar o modelo 3D da peca projetada e o resultado

obtido com o posicionamento do POS sobre a base, nota-se que agora o plano das

teclas do dispositivo ficou paralelo ao plano da base.

28

Figura 3.4: Modelo da base de apoio do POS.

(a) POS sobre base, modelo 3D (b) POS sobre base, vista lateral, modelo 3D.

(c) POS sobre base, projeto real.

Figura 3.5: POS PAX® S920 posicionado sobre a base de apoio.

29

Uma vez corretamente posicionado sobre a base da impressora, o acionamento

das teclas e feito por uma haste acoplada a cabeca extrusora da impressora 3D,

para tal e usada uma caneta para telas capacitivas de forma que tambem possa ser

utilizada para interacao com a tela touchscreen em melhorias futuras. Para o projeto

da peca que prende a caneta a impressora 3D e necessario prover um ajuste no nıvel

da caneta no eixo Z para correto acionamento do teclado, a Figura 3.6 mostra a

peca modelada e na Figura 3.7 e possıvel ver uma foto da peca impressa acoplada a

impressora com a caneta presa.

Figura 3.6: Modelagem 3D da peca que prende a caneta capacitiva a impressora 3D.

Figura 3.7: foto mostrando acoplamento da caneta a impressora 3D.

30

Outra adaptacao fısica necessaria e o ajuste do fim de curso da impressora; a

calibracao do sistema de coordenadas da impressora e feita por meio de tres botoes

de fim de curso, um para cada eixo cartesiano. Uma vez a origem de um eixo

e calibrada, a impressora nao pode se deslocar para posicoes negativas no eixo.

Como o fim de curso do eixo Z e originalmente posicionado de forma que a ponta

da cabeca extrusora fique a uma distancia bem proxima a base da impressora, e

necessario uma adaptacao no fim de curso pois o dispositivo POS colocado sobre a

base da impressora ocupa uma altura consideravel, e assim o curso do eixo Z deve

ser alterado para nao haver colisao entre o dispositivo e a impressora. A Figura 3.8

apresenta uma visao frontal do aparato sobre a impressora com a cabeca extrusora

na posicao de origem desejada, assim e possıvel notar que a cabeca extrusora nao

deve se deslocar muito para baixo, somente o suficiente para acionamento das teclas.

Figura 3.8: Visao frontal do aparato.

Dessa forma, uma peca projetada e acoplada na impressora para que o botao

31

de fim de curso fosse acionado sempre em uma altura especıfica para o modelo PAX®

S920, suficiente para acionamento das teclas. A Figura 3.9 mostra o modelo 3D da

peca projetada, enquanto as Figuras 3.10 e 3.11 mostram fotos da peca no projeto

real, sendo possıvel ver como a peca altera o acionamento do botao de fim de curso.

Figura 3.9: Modelo 3D da peca que limita o fim de curso do eixo Z.

32

Figura 3.10: Peca que limita o fim de curso do eixo Z em foto do projeto real.

Figura 3.11: Foto do projeto real proximo ao botao de fim de curso do eixo Z.

Sob a otica do software implementado para interacao com o teclado, a Figura

33

3.12 apresenta um diagrama de classes simplificado do projeto mostrando apenas as

classes envolvidas no controle do teclado.

Figura 3.12: Diagrama de classes que implementam atuador do teclado.

Cada uma das teclas do POS e representada por uma struct chamada de

KeyMap que contem a posicao da tecla no plano XY representada pelo tipo QPointF

(um tipo de dados do Qt para representacao de uma coordenada XY em ponto

flutuante) e a lista de caracteres (representado pelo tipo QStringList) que e possıvel

inserir com a tecla. O acionamento sucessivo de uma mesma tecla dentro de um

tempo menor que um segundo alterna o caractere de entrada, pois cada uma das

teclas possui mais de um caractere associado (similar a um teclado telefonico), e

necessario associar uma lista de caracteres para uma mesma posicao. Ao inves

de uma lista de caracteres, e usada uma lista de strings para representar teclas

nao alfanumericas, por exemplo: return e escape em “RETURN” e “ESCAPE”

respectivamente.

struct KeyMap {

QPointF position;

QStringList keyList;

};

Cada modelo de POS possui diferentes teclas com diferentes dimensoes e

posicoes dos caracteres (ver Figura 3.13), portanto e necessario representar as ca-

34

racterısticas do dispositivo em um modelo de dados. Assim, a classe PosObject e

usada para armazenar as caracterısticas do dispositivo POS, tal como dimensoes,

nome do modelo e uma lista de KeyMap.

(a) Teclado do terminal PAX® S920. (b) Teclado do terminal PAX® D210.

Figura 3.13: Exemplo de diferencas no layout do teclado.

Para armazenar as caracterısticas de um dispositivo, e utilizado um arquivo

JSON (JavaScript Object Notation ou Notacao de Objetos JavaScript), um formato

para representacao de objetos. O trecho a seguir e mostra parte estrutura do arquivo

JSON usado para representar o as caracterıscas do POS modelo PAX® S920.

{

"vendor": "PAX",

"model": "S920",

"width": 77,

"height": 165,

"keyboardMap": [

{

"x": 15,

"y": 36,

"keyList": ["1", "q", "z", "."]

},

{

"x": 30,

"y": 36,

"keyList": ["2", "a", "b", "c"]

},

"..."

]

}

Os valores das coordenadas x e y de uma tecla estao representando a posicao

35

em milımetros das mesmas com relacao a origem do dispositivo, sendo esta defi-

nida como o vertice inferior esquerdo do retangulo que delimita o dispositivo, como

ilustrado na Figura 3.14.

Figura 3.14: Ilustracao do sistemas de coordenadas do re-

ferencial do POS.

Em tempo de execucao, a classe PosObjectFactory e a responsavel por instan-

ciar um novo objeto da classe PosObject com os dados extraıdos do arquivo JSON.

Para se obter o objeto correspondente ao dispositivo desejado, e necessario invocar

o metodo PosObjectFactory::getPosObject() passando como parametro qual o mo-

delo desejado. A lista de modelos disponıveis esta representado pelo tipo enumerado

PosModel. A seguir o trecho de codigo mostra a implementacao do construtor da

classe PosTestTool, inicialmente se obtem um objeto da classe PosObject para em

seguida configurar a instancia de KeyboardController com o modelo do dispositivo

obtido e a referencia de PrinterController.

PosTestTool::PosTestTool(PosModel device)

: m_keyboardController(new KeyboardController(this))

, m_cardController(new CardController(this))

, m_printerController(new PrinterController(this))

{

m_posObject = PosObjectFactory::getPosObject(device);

36

m_keyboardController->setDevice(m_posObject);

m_keyboardController->setPrinterController(m_printerController);

}

Tendo o dispositivo configurado e o ponteiro para o controlador da impres-

sora, ja e possıvel utilizar m keyboardController para atuar sobre o teclado. A classe

KeyboardController possui somente dois metodos para tal, o metodo Keyboard-

Controller::write() que tem como funcao a entrada de uma sequencia de caracteres,

podendo ser por exemplo a insercao de uma senha de 4 dıgitos; e o metodo Keybo-

ardController::keyPress() para insersao de um unico caractere. Os metodos PosTest-

Tool::write() e PosTestTool::keyPress() sao apenas chamadas para esses metodos de

KeyboardController. O trecho de codigo seguir apresenta um exemplo simples de

programa em C++ com Qt utilizando a biblioteca PosTestTool para escrever “tcc”

com o teclado do POS.

1 #include "postesttool.h"

2 #include <QCoreApplication>

3 int main(int argc, char* argv[])

4 {

5 QCoreApplication a(argc, argv);

6 PosTestTool ptt(PosModel::PAX_S920);

7 ptt.write("tcc");

8 return a.exec();

9 }

Para entender como o metodo KeyboardController::write() funciona, veja

o trecho de codigo a seguir. O metodo consiste em iterar sobre os caracteres

de uma string recebida como parametro e executar o metodo KeyboardControl-

ler::keyPress() passando a tecla correspondente ao caractere pelo numero de vezes

necessario para se ter o caractere desejado. Repare que, no caso de caracteres con-

secutivos localizados na mesma tecla, e necessario realizar uma espera para o POS

reconhecer como caracteres de entrada diferentes.

void KeyboardController::write(QString phrase)

{

// Verifica se foi escolhido um dispositivo POS e se impressora foi configurada.

// Caso contrario, aborta execuc~ao.

if (m_device == nullptr || m_printerController == nullptr) {

37

qCritical() << "Device or printer not set up";

return;

}

// Move impressora para uma altura fora de contato com o POS

m_printerController->moveZ(PrinterController::safeZPosition);

QPair<QPointF, int> lastCharPosition;

// Itera sobre string 'phrase'

foreach (QChar character, phrase) {

// Obtem a posic~ao do caractere

QPair<QPointF, int> charPosition = m_device->getKeyPosition(character);

// Espera se caractere esta na mesma tecla que caractere anterior

if (charPosition.first == lastCharPosition.first)

m_printerController->wait(500);

// Pressiona tecla para se obter o caractere

keyPress(character);

lastCharPosition = charPosition;

}

// Retorna impressora para posic~ao fora de contato com o POS

m_printerController->moveZ(PrinterController::safeZPosition);

}

void KeyboardController::keyPress(QString key)

{

if (m_device == nullptr || m_printerController == nullptr) {

qCritical() << "Device or printer not set up";

return;

}

// Obtem a posic~ao da tecla correspondente ao caractere.

QPair<QPointF, int> charPosition;

charPosition = m_device->getKeyPosition(key);

// Verifica se caractere foi encontrado.

// Caso contrario, aborta execuc~ao do metodo.

if (charPosition.first == QPointF(0, 0)) {

qError() << "charactere not found";

return;

}

// Move impressora para posic~ao correspondente a tecla.

m_printerController->moveZ(PrinterController::safeZPosition);

m_printerController->setXYPosition(charPosition.first);

// Pressiona tecla pelo numero de vezes necessario

38

// para se ter o caractere desejado.

for (int i = 0; i <= charPosition.second; ++i) {

m_printerController->moveZ(0);

m_printerController->moveZ(PrinterController::safeZPosition / 2);

}

m_printerController->moveZ(PrinterController::safeZPosition);

}

3.4 Insercao e remocao de cartao

Para insercao e remocao de cartoes de credito no POS, foi projetado um atuador

linear pelo acoplamento de uma engrenagem circular presa a um servo-motor com

uma cremalheira de dentes retos, dessa forma o deslocamento linear da cremalheira

e diretamente proporcional ao angulo de controle do servo-motor, ver Figura 3.15.

Portanto para realizar insercao e remocao de cartao basta definir um angulo ne-

cessario para deslocar o cartao de forma que o sensor do dispositivo POS detecte ou

nao a presenca do cartao.

Figura 3.15: Visao lateral do modelo 3d do atuador linear.

A Figura 3.16 mostra a peca ja impressa montada no robo. E importante

notar que foi necessario fixar a peca sobre outra com objetico de nivelar o atuador

para que um cartao de credito, quando fixado ao aparato, ficasse no mesmo nıvel

da entrada de cartao do dispositivo POS. A peca mostrada na Figura 3.17 e usada

para fixacao de cartoes de credito; o rebaixo retangular ao lado esquerdo da peca na

39

figura foi feito para colagem da peca a cremalheira; no lado direito existem dois furos

para parafusos usados para que a peca possa comprimir os cartoes e estes ficarem

bem fixos.

Figura 3.16: Atuador linear impresso em PLA.

Figura 3.17: Modelo 3D da peca que prende cartoes de

credito.

40

Figura 3.18: aparato completo.

Figura 3.19: cartao fixado ao atuador.

41

O motor utilizado no projeto foi o Hitec HS-311, que possui um angulo de

rotacao de 180º. O diagrama da Figura 3.20 apresenta o a conexao do servo-motor

com o Arduino. O servo-motor possui tres terminais, dois para alimentacao (conec-

tados aos pinos +5V e GND) e um para controle, conectado ao pino digital 9 do

Arduino.

Figura 3.20: Esquema da ligacao eletronica do servo com o Arduino.

42

Figura 3.21: vista lateral, arduino fixado ao aparato.

Para controlar o servo-motor, foi utilizada a biblioteca <Servo.h> que ja vem

instalada por padrao com o Arduino. A biblioteca expoe a classe Servo com alguns

metodos para facilitar o controle; a seguir um exemplo de utilizacao retirado dos

exemplos disponıveis com a IDE do Arduino, o exemplo em questao mostra como

controlar a posicao de um servo-motor a partir de uma entrada analogica controlada

por um potenciometro.

1 /*

2 Controlling a servo position using a potentiometer (variable resistor)

3 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

4

5 modified on 8 Nov 2013

6 by Scott Fitzgerald

7 http://www.arduino.cc/en/Tutorial/Knob

8 */

9

10 #include <Servo.h>

11

12 Servo myservo; // cria objeto para controlar servo

13

14 int potpin = 0; // pino analogico para conectar potenciometro

15 int val; // variavel para guardar valor de leitura anal[ogica do potenciometro

43

16

17 void setup() {

18 myservo.attach(9); // configura o pino do servo para 9

19 }

20

21 void loop() {

22 val = analogRead(potpin); // le o valor do potenciometro (entre 0 e 1023)

23 val = map(val, 0, 1023, 0, 180); // escala o valor da leitura (entre 0 e 255)

24 myservo.write(val); // define posic~ao do servo com o valor escalado

25 delay(15); // espera o servo chegar na posic~ao

26 }

Tendo o controle do servo definido, falta somente a implementacao a comu-

nicacao do Arduino com o programa rodando no computador, que foi feita utilizando

a entrada USB. Todo arduino possui pelo menos uma porta serial disponıvel para

comunicacao via protocolo UART (Universal Asynchronous Receiver/Transmiter).

Esse tipo de comunicacao e Full-duplex, que permite transmitir e receber dados ao

mesmo tempo. Essa comunicacao pode feita pelos pinos RX (pino digital 0) e TX

(pino digital 1) ou via USB. Uma vez que a comunicacao serial e utilizada, nao e

possıvel utilizar esses pinos como entrada e saıda digitais.

Figura 3.22: Pinos de comunicacao serial do Arduino.

Para tratar mensagens recebidas pela porta serial, a biblioteca do Arduino

possui a funcao serialEvent() que e chamada toda vez que chega algum dado pelo

pino de leitura RX e pode ser reimplementada para tratamento desses dados. O

trecho de codigo a seguir e utilizado para concatenar cada caractere recebido pela

porta serial na variavel inputString e definindo a string como completa quando um

caractere \n (fim de linha) e recebido.

1 /*

2 SerialEvent occurs whenever a new data comes in the hardware serial RX. This

44

3 routine is run between each time loop() runs, so using delay inside loop can

4 delay response. Multiple bytes of data may be available.

5 */

6 void serialEvent()

7 {

8 while (Serial.available())

9 {

10 // get the new byte:

11 char inChar = (char)Serial.read();

12 // add it to the inputString:

13 inputString += inChar;

14 // if the incoming character is a newline, set a flag so the main loop can

15 // do something about it:

16 if (inChar == '\n')

17 {

18 stringComplete = true;

19 }

20 }

21 }

Na funcao loop, tendo a string completa o programa compara com as opcoes

disponıveis, executa a respectiva acao e logo depois limpa o valor de inputString

para poder receber novos comandos.

1 void loop()

2 {

3 // print the string when a newline arrives:

4 if (stringComplete)

5 {

6 Serial.println("Received command: " + inputString);

7

8 if (inputString == "insert\n")

9 {

10 Serial.println("Insert card");

11 linearActuator.write(insertAngle);

12 }

13 else if (inputString == "remove\n")

14 {

15 Serial.println("Remove card");

16 linearActuator.write(removeAngle);

17 }

18 else

19 {

20 Serial.println("Nothing to do");

21 }

22

45

23 // clear the string:

24 inputString = "";

25 stringComplete = false;

26 }

27 }

A Arduino IDE possui uma ferramenta chamada “Serial Monitor” que per-

mite enviar dados para o Arduino via porta serial e tambem visualizar dados re-

cebidos do computador pelo Arduino. Na Figura 3.23 exemplifica a resposta do

programa a diferentes entradas.

Figura 3.23: Resposta serial da aplicacao do Arduino.

A comunicacao serial de um programa Qt com um dispositivo USB e feita pela

classe CardController para entender como e feita . A classe possui um objeto membro

da classe QSerialPort que e uma classe disponıvel no Qt para fazer comunicacao com

dispositivos em portas seriais e dois metodos publicos reponsaveis por mandar os

comandos de insercao e remocao de cartao ao Arduino.

1 #ifndef CARDCONTROLLER_H

2 #define CARDCONTROLLER_H

3

4 #include <QObject>

5 #include <QSerialPort>

6

7 class CardController : public QObject {

46

8 Q_OBJECT

9 public:

10 explicit CardController(QObject* parent = nullptr);

11 ~CardController();

12 void insert();

13 void remove();

14

15 private:

16 QSerialPort m_serialPort;

17 };

18

19 #endif // CARDCONTROLLER_H

O trecho de codigo a seguir destaca o construtor da classe CardController,

onde e feita a conexao com o Arduino. Inicialmente e feita uma iteracao em todas as

portas seriais disponıveis utilizando a classe QSerialPortInfo para pegar informacoes

e procurar em qual o Arduino esta conectado. Note que e esperado que o computador

esteja conectado a somente um Arduino, o responsavel pelo controle do atuador

linear.

1 CardController::CardController(QObject* parent)

2 : QObject(parent)

3 {

4 foreach (const QSerialPortInfo& devinfo, QSerialPortInfo::availablePorts()) {

5 if (devinfo.description().contains("Arduino")) {

6 m_serialPort.setPortName(devinfo.portName());

7 }

8 }

9

10 m_serialPort.setBaudRate(QSerialPort::Baud115200);

11 m_serialPort.setDataBits(QSerialPort::Data8);

12 m_serialPort.setFlowControl(QSerialPort::NoFlowControl);

13 m_serialPort.setParity(QSerialPort::NoParity);

14 m_serialPort.setStopBits(QSerialPort::OneStop);

15

16 if (!m_serialPort.open(QIODevice::ReadWrite)) {

17 qCritical() << QObject::tr("Falha ao abrir porta %1, erro: %2")

18 .arg(m_serialPort.portName())

19 .arg(m_serialPort.errorString())

20 << endl;

21 }

22 }

23

24 CardController::~CardController() { m_serialPort.close(); }

47

Ao ser encontrado, algumas configuracoes necessarias para se comunicar com

o Arduino sao setadas e e aberta a conexao pelo medoto QserialPort::open(). Caso

haja falha na abertura da porta, uma mensagem de erro crıtico e exibida. Uma

vez aberta a conexao, e possıvel se comunicar com o Arduino utilizando o metodo

QSerialPort::write() herdado da classe QIODevice para enviar dados, o trecho de

codigo a seguir apresenta a implementacao dos metodos insert e remove.

1 void CardController::insert() { m_serialPort.write("insert\n"); }

2

3 void CardController::remove() { m_serialPort.write("remove\n"); }

Assim o diagrama sequencial para insercao de cartao ficaria como na Figura

3.24, uma vez que os dados sao apenas enviados para o Arduino de maneira assin-

crona e nao se espera uma resposta da acao.

Figura 3.24: Diagrama sequencial da insercao de cartao.

3.5 Biblioteca Python

O projeto foi criado com intuito de fornecer uma API para que um analista

de testes pudesse utilizar o robo de dentro de seus scripts de testes. Assim, e

interessante que o usuario da ferramenta nao precise ficar restrito a utilizacao apenas

de C++ para utiliza-la. Em computacao, e chamado de binding uma API que

48

proporciona essa ligacao entre uma linguagem de programacao e uma biblioteca ou

servico de outra linguagem de programacao.

Para geracao de um binding da biblioteca para outra linguagem existe a li-

mitacao da biblioteca ser dependente de framework. Apesar do Qt de fornecer varias

classes que facilitaram o desenvolvimento da API, ele tambem impos a dependencia

de suas bibliotecas. Portanto para expor a API a outras linguagens, e preciso que es-

sas linguagens tambem tenham suporte ao Qt. Algumas das linguagens que possuem

bindings do Qt sao: Python, C#, Go, Haskell e Ruby.

Uma decisao de projeto levando em conta a experiencia em programacao da

equipe de analistas de testes foi disponibilizar inicialmente uma API em Python.

Para isso foi utilizado o SWIG, que e uma ferramenta de software para conectar

programas escritos em C ou C++ com outras linguagens, dentre elas o Python.

Para utilizar o SWIG e necessario criar um arquivo com extensao .i descrevendo

as interfaces que serao expostas para a linguagem desejada. A seguir e mostrado o

conteudo do arquivo postesttool.i que apenas expoe as classes PosTestTool e a enum

class PosModel.

1 /* file: postesttool.i */

2 %module postesttool

3 %{

4 /* Put header files here or function declarations like below */

5 #include "postesttool.h"

6 #include "model/posobject.h"

7 %}

8 %include <std_string.i>

9 /* list functions to be interfaced: */

10 class PosTestTool

11 {

12 public:

13 PosTestTool(PosModel device);

14 void insertCard();

15 void removeCard();

16 void keyPress(std::string key);

17 void write(std::string text);

18 };

19 enum class PosModel {

20 PAX_S920

21 };

Para gerar o binding basta entao executar o SWIG via linha de comando

49

escolhendo o arquivo postesttool.i da seguinte forma:

$ swig3 . 0 −c++ −python p o s t e s t t o o l . i

Depois de executado, o SWIG ira gerar dois arquivos postesttool.py com

a API que devera ser importada num script Python que deseje usar a biblioteca

e o arquivo postesttool wrap.cxx que deve ser compilado com a biblioteca C++.

Alem disso, deve ser incluıdo na compilacao, o cabecalho Python.h do diretorio de

instalacao do Python.

Apos o processo de geracao do binding, e possıvel importar a API em um

script Python. A trecho de codigo a seguir implementa o mesmo exemplo mostrado

na sessao 3.3, desta vez escrito em Python:

1 #!/usr/bin/env python

2 # -*- coding: utf-8 -*-

3 import sys

4 import postesttool as POS

5 from PySide.QtCore import *

6 from PySide.QtGui import *

7 if __name__ == '__main__':

8 app = QApplication(sys.argv)

9 ptt = POS.PosTestTool(POS.PosModel_PAX_S920)

10 ptt.write("tcc")

11 app.exec()

50

Capıtulo 4

Testes e Resultados Experimentais

Com intuito de testar inicialmente o funcionamento de cada uma das funcoes

expostas pela API para controle do robo, e utilizada uma aplicacao grafica simples

em Qt com botoes fazendo chamadas a cada uma dos metodos da classe PosTestTool.

A Figura 4.1 mostra a interface da aplicacao.

Figura 4.1: Aplicacao para teste da API do robo.

Na Figura 4.2 a seguir e possıvel ver a diferenca na posicao do atuador linear

em resposta aos metodos PosTestTool::insertCard() e PosTestTool::removeCard().

51

(a) Cartao removido. (b) Cartao inserido.

Figura 4.2: Posicoes do cartao em resposta aos metodos de insercao e remocao.

Uma vez averiguado que cada uma das funcoes retorna resultado esperado,

prosseguiu-se com o desenvolvimento do binding para Python e a validacao da uti-

lizacao da API em um caso de teste automatizado.

O diagrama da Figura 4.3 mostra os dispositivos que compoem o ambiente

de testes completo. O computador que executa os scripts de teste se comunica com

o robo por meio da API PosTestTool para realizar controle de insercao e remocao

de cartao que e realizado pelo Arduıno e para fazer insercao de PIN, feita pela

impressora 3D. Ja a comunicacao com o POS via Selenium e realizado por cabo USB

utilizando ferramentas de desenvolvimento disponibilizadas pela fabricante PAX®.

52

Figura 4.3: Diagrama do ambiente de testes.

O exemplo a seguir mostra uma automatizacao de uma transacao de debito

utilizando o Selenium e a API, passando por todas etapas ate aprovacao ou nao da

transacao. E importante notar que os metodos de PosTestTool sao executados de

maneira assıncrona, enquanto os metodos do Selenium sao sıncronos e bloqueiam a

execucao da aplicacao, dessa forma e necessario incluir um tempo de espera no qual

e chamado o metodo QApplication.processEvents() que e usado para nao bloquear

a execucao da aplicacao Qt, processando sua fila de eventos.

1 import sys

2 import time

3 # Importac~ao de modulos do Selenium

4 from selenium import webdriver

5 from selenium.webdriver.common.keys import Keys

6 from selenium.webdriver.common.by import By

7 from selenium.common.exceptions import TimeoutException

8 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

53

9 from selenium.webdriver.support.ui import WebDriverWait

10 from selenium.webdriver.support import expected_conditions as ExpectedConditions

11

12 # Importac~ao da biblioteca PosTestTool e dependencias

13 sys.path.append('./posTestTool')

14 import postesttool as POS

15 from PySide.QtCore import *

16 from PySide.QtGui import *

17

18 # Parametros de pagamento

19 paymentMethod = "Debito"

20 paymentAmount = "R$ 0,10"

21 installmentsMethod = "2"

22 installmentsNumber = "3"

23 cardPassword = "1234"

24

25 if __name__ == '__main__':

26 app = QApplication(sys.argv)

27

28 # Cria uma instancia de PosTestTool (inicia conexao com o robo)

29 ptt = POS.PosTestTool(POS.PosModel_PAX_S920)

30

31 # Espera ate termino da calibrac~ao inicial

32 for n in range(300):

33 time.sleep(0.1)

34 QApplication.processEvents()

35

36 # Insere cartao

37 ptt.insertCard()

38 QApplication.processEvents()

39

40 # Conecta ao servidor remoto do Selenium e procura janela com titulo 'Pagamento'

41 driver = webdriver.Remote(

42 command_executor='http://127.0.0.1:9517',

43 desired_capabilities={'browserStartWindow': 'Pagamento', 'reuseUI': True})

44

45 wait = WebDriverWait(driver, 5)

46

47 # Espera troca de pagina e seleciona metodo de pagamento

48 payment_applications_pages = wait.until(

49 ExpectedConditions.visibility_of_element_located(

50 (By.ID,"scr-methods")))

51 paymentApplicationElements = payment_applications_page

52 .find_elements_by_class_name("collection-item")

53 for element in paymentApplicationElements:

54 if paymentMethod in element.text:

55 element.click()

56 break

54

57

58 # Espera troca de pagina e insere valor desejado

59 element = wait.until(

60 ExpectedConditions.visibility_of_element_located(

61 (By.ID,'inp-proposed-amount')))

62 driver.execute_script(

63 "document.getElementById('inp-proposed-amount').value = '"

64 + paymentAmount + "'")

65 element.send_keys(Keys.RETURN)

66

67 # Insere PIN e confirma usando PosTestTool

68 ptt.write(cardPassword)

69 ptt.keyPress('RETURN')

70

71 # Espera ate termino da inserc~ao de senha

72 for n in range(300):

73 time.sleep(0.1)

74 QApplication.processEvents()

75

76 # Verifica se transacao teve erro ou sucesso

77 WebDriverWait(driver, 150).until(

78 lambda driver:

79 driver.find_element_by_id('scr-print-receipt').is_displayed()

80 or driver.find_element_by_id('scr-error').is_displayed()

81 )

82

83 if driver.find_element_by_id('scr-print-receipt').is_displayed():

84 driver.save_screenshot('payment_success.png')

85 # Caso tenha sucesso cancela impress~ao de recibo

86 driver.find_element_by_id('btn-print-receipt-no').click()

87 else:

88 # Caso tenha erro salva captura de tela em arquivo

89 driver.save_screenshot('payment_error.png')

90

91 # Remove cartao

92 ptt.removeCard()

O script salva em arquivo uma imagem com a captura de tela da aplicacao

caso ocorra erro no processamento da transacao. Assim, forcando um caso de erro

no qual uma transacao nao e completada por falha de conexao com a rede, por

exemplo, a execucao do script ira gerar a imagem mostrada na Figura 4.4.

55

(a) Captura de tela no caso de

sucesso na transacao.

(b) Captura de tela da mensa-

gem de erro de rede.

Figura 4.4: Capturas de tela realizas em teste automatizado.

O caso de teste anteriormente mostrado poderia ser alterado para ser facil-

mente configuravel e receber os parametros de pagamento por linha de comando

como mostrado a seguir.

import sys

[...]

# Parametros de pagamento

paymentMethod = sys.argv[0]

paymentAmount = sys.argv[1]

installmentsMethod = sys.argv[2]

installmentsNumber = sys.argv[3]

cardPassword = sys.argv[4]

Assim, poderia ser executado diversos casos de teste de pagamento com base

em diferentes parametros, compondo uma massa de dados de testes. Ainda, essas

rotinas poderiam ser programadas para serem realizadas periodicamente ou toda vez

que fosse gerada uma nova versao da aplicacao do POS de maneira automatizada e

consistente, sem necessidade de intervencao humana durante execucao dos testes.

A Tabela 4 mostra o tempo de execucao do teste transacional acima repetido

algumas vezes em condicao de boa conectividade, garantindo sucesso nas transacoes.

E possıvel observar que o tempo de execucao do teste e praticamente constante em

48 segundos.

56

Tempo da transacao

47,90 s

47,22 s

47,89 s

48,01 s

47,68 s

47,76 s

47,88 s

47,56 s

Tempo medio - 47,74 s

Tabela 4.1: Tempo de execucao de transacao usando a PosTestTool.

Levando em conta o tempo medio de execucao do teste, seria possıvel realizar

em um perıodo de 1 hora, cerca de 75 transacoes, suficiente para cobrir muitos casos

de teste. Por outro lado, o tempo medio de uma transacao realizada de forma manual

e de cerca de 22 segundos, portanto o prototipo ainda e cerca de 3,4 vezes mais lento

que um ser humano. Entretanto, o robo permite uma execucao mais consistente e

tambem mais barata que um funcionario pelo unico gasto ser com energia eletrica.

A potencia media da Anet A6 e estimada em 110 watts, somado ao consumo medio

de um computador de 90 watts, se for considerado um tempo de trabalho de 24

horas por dia, em um mes e consumido 146 kWh, custando apenas cerca de R$ 136

[23].

57

Capıtulo 5

Conclusao

5.1 Conclusoes

Os objetivos propostos pelo projeto foram todos atendidos levando em conta

a prova de conceito de se automatizar testes para um determinado modelo de POS,

o PAX S920. Para automatizacao de outros modelos com teclado fısico, e apenas

necessaria uma adaptacao de estrutura do robo, por outro lado, a arquitetura do

software nao precisa de outras adequacoes, so e necessario inserir um arquivo JSON

descrevendo o novo modelo.

Para implementacao do projeto, se utilizou de algumas ferramentas de codigo

aberto, o que foi um grande facilitador. Com isso ficou claro que no processo de

desenvolvimento de um software e essencial a pesquisa de ferramentas que podem

ser utilizadas antes de se iniciar a fase de implementacao.

A ideia inicialmente era utilizar somente o robo para automatizacao das en-

tradas em testes funcionais, realizando todas passos do fluxo transacional como

insercao de valor de pagamento por interacao com teclado. Entretanto, pela vanta-

gem da aplicacao da Stone Pagamentos ser feita com tecnologia web, o Selenium e

capaz de fazer esse tipo de automatizacao de entrada de maneira mais eficaz. As-

sim, e possıvel concluir que nao e necessario o uso de uma unica ferramenta para a

automatizacao de testes, podendo-se combinar a utilizacao do robo somente quando

necessario e ferramentas de teste ja consolidadas como o Selenium quando possıvel.

O projeto cumpriu com a proposta de fornecer uma ferramenta capaz de

automatizar a execucao do fluxo de pagamento em terminais POS, sendo assim

58

capaz de auxiliar durante os processos de qualidade de software.

5.2 Trabalhos Futuros

Embora a API ja seja utilizavel para automatizacao de testes funcionais,

alguns pontos ainda necessitam de melhoria:

• Adequar estrutura do robo para se adequar a diferentes modelos de POS, pois

a base de apoio e o fim de curso foram projetados especificamente para o PAX

S920.

• Remover a dependencia do Qt da API. A dependencia traz o inconveniente do

analista de testes ter que se adequar a somente linguagens que tenham suporte

ao Qt.

• Permitir o controle do robo remotamente. Atualmente toda comunicacao com

o robo e feita por porta serial, assim os scripts de testes transacionais precisam

ser executados na maquina em que o robo esta conectado, dificultando o uso

da ferramenta por mais de um analista de teste ou desenvolvedor.

• Implementar interacao com teclado virtual. Alguns modelos de POS mais

recentes no mercado nao possuem teclado fısico e por isso utilizam teclado

virtual que devem ser utilizador por touchscreen.

• Utilizar OCR (Optical Character Recognition ou reconhecimento otico de ca-

racteres) para alinhar a posicao correta das teclas e assim realizar um controle

em malha fechada.

• Implementar atuador para passar cartoes de tarja magnetica.

• Projetar mecanismo para realizar troca de cartoes.

• Utilizar atuador para nivelamento do dispositivo POS ao inves de utilizar uma

base diferente para cada modelo.

Para o primeiro item, basta projetar pecas com ajustes de largura, compri-

mento e inclinacao do dispositivo, mantendo porem a posicao da origem do dispo-

59

sitivo. Tambem seria necessario alteracao na maneira que e feito o fim de curso do

eixo Z.

O controle remoto do robo poderia ser feito pela implementacao de uma

aplicacao servidor em um computador embarcado no robo que aceitasse comandos

via requisicoes pela rede, isso consequentemente iria remover a dependencia do fra-

mework Qt para o utilizador da API.

O controle de teclados virtuais tem uma complexidade porque para aumen-

tar a seguranca de privacidade do PIN, o teclado virtual numerico e exibido com

os numeros em posicoes randomicas, isso porque a interacao com telas touchscreen

deixa marcas visıveis e se a posicao fosse fixa seria mais facil identificar o PIN inse-

rido. Portanto, nesse caso para identificar a posicao dos algarismos seria necessario

usar uma camera e algoritmos de visao computacional.

O atuador para cartoes de tarja magnetica poderia ser igual ao atuador linear

utilizado para insercao e remocao de cartao, mas com a peca para segurar o cartao

diferente. Seria tambem necessario expandir o codigo do Arduino para adicionar

mais um comando e expor um metodo na API para executar a acao.

O projeto atual ainda exige o trabalho manual de realizar troca de cartoes

do robo e alem disso, ainda e necessario fornecer os dados de entrada para o cartao.

Seria possıvel eliminar essa etapa manual projetando um meio de realizar a troca

de cartoes de teste de maneira automatizada e armazenar suas informacoes em uma

base de dados.

Vale ainda ressaltar que o projeto tratou-se de um prototipo; como o robo

foi feito a partir da conversao de uma impressora 3D, isso tornou os seus custos de

construcao mais elevado. Para evolucao do robo para um produto e necessario o

projeto de mecanismos mais adequados.

60

Referencias Bibliograficas

[1] “Arduino Uno Rev3”, https://store.arduino.cc/usa/arduino-uno-rev3, 2018,

(Acesso em 27 Fevereiro 2018).

[2] “Anet A6 3D Printer-Shenzhen Anet Technology Co.,Ltd”,

http://www.anet3d.com/English/3D Printer/105.html, (Acesso em 1 Marco

2018).

[3] “AtCore: Main Page”, https://atelier.kde.org/static/atcore doc/index.html,

(Acesso em 28 Fevereiro 2018).

[4] “EFTPOS Terminal Testing Robot - Abrantix Pty Ltd”,

http://www.abrantix.com/AXRobot.html, (Acesso em 27 Fevereiro 2018).

[5] “Stone Pagamentos”, https://www.stone.com.br/, (Acesso em 16 Setembro

2018).

[6] STROUSTRUP, B., The C++ Programming. New York, Osborne, 2013.

[7] “ISO/IEC 14882:2017 - Programming Languages – C++”,

https://www.iso.org/standard/68564.html, 2017, (Acesso em 28 Fevereiro

2018).

[8] “All Classes — Qt 5.11”, http://doc.qt.io/qt-5/classes.html, 2018, (Acesso em

26 Junho 2018).

[9] “Complete software development framework – Qt”, https://www.qt.io/what-

is-qt/, 2018, (Acesso em 28 Fevereiro 2018).

[10] “Plasma - KDE.org”, https://www.kde.org/plasma-desktop, (Acesso em 28 Fe-

vereiro 2018).

61

[11] “Quality Assurance - Wikipedia”, https://en.wikipedia.org/wiki/Quality assurance,

(Acesso em 16 Setembro 2018).

[12] MYERS, G. J., The Art of Software Testing, 3rd Edition, chapter The Psyco-

logy and Economics of Software Testing, New Jersey, John Wiley & Sons, pp.

5–18, 2012.

[13] “Selenium - Web Browser Automation”, https://www.seleniumhq.org/, (Acesso

em 1 Marco 2018).

[14] “cisco-open-source/qtwebdriver: WebDriver implementation for Qt”,

https://github.com/cisco-open-source/qtwebdriver, (Acesso em 1 Marco

2018).

[15] “Arduino - Wikipedia”, https://pt.wikipedia.org/wiki/Arduino, 2018, (Acesso

em 27 Fevereiro 2018).

[16] VOLPATO, N., Prototipagem Rapida - Tecnologias e Aplicacoes. Sao Paulo,

Blucher, 2007.

[17] “Onshape: Modern CAD. Finally.”, https://www.onshape.com/, (Acesso em 1

Marco 2018).

[18] “HOME - EMVCo”, https://www.emvco.com, 2018, (Acesso em 27 Fevereiro

2018).

[19] “EMV - Wikipedia”, https://en.wikipedia.org/wiki/EMV, 2018, (Acesso em 27

Fevereiro 2018).

[20] “ABECS - Graficos”, https://www.abecs.org.br/indicadores-graficos, 2018,

(Acesso em 16 Setembro 2018).

[21] “UML - Wikipedia, a enciclopedia livre”, https://pt.wikipedia.org/wiki/UML,

(Acesso em 14 Julho 2018).

[22] GAMMA, E., Design Patterns: Elements of Reusable Object-Oriented Software.

Addison-Wesley, 1995.

62

[23] “Portal Light - Composicao da tarifa”, http://www.light.com.br/para-

residencias/Sua-Conta/composicao-da-tarifa.aspx, (Acesso em 17 Setembro

2018).

63

Apendice A

Codigo Arduino

1 /** file CardActuator.ino **/

2 #include <Servo.h>

3

4 String inputString = ""; // a String to hold incoming data

5 boolean stringComplete = false; // whether the string is complete

6

7 const int insertAngle = 20;

8 const int removeAngle = 100;

9 const int servoPin = 9;

10

11 Servo linearActuator; // create servo object to control a servo

12

13 void setup()

14 {

15 // initialize serial:

16 Serial.begin(115200);

17 // reserve 200 bytes for the inputString:

18 inputString.reserve(200);

19 linearActuator.attach(servoPin); // attaches the servo on pin 9 to the servo object

20 linearActuator.write(removeAngle);

21 }

22

23 void loop()

24 {

25 // print the string when a newline arrives:

26 if (stringComplete)

27 {

28 Serial.println("Received command: " + inputString);

29

30 if (inputString == "insert\n")

31 {

64

32 Serial.println("Insert card");

33 linearActuator.write(insertAngle);

34 }

35 else if (inputString == "remove\n")

36 {

37 Serial.println("Remove card");

38 linearActuator.write(removeAngle);

39 }

40 else

41 {

42 Serial.println("Nothing to do");

43 }

44

45 // clear the string:

46 inputString = "";

47 stringComplete = false;

48 }

49 }

50

51 /*

52 SerialEvent occurs whenever a new data comes in the hardware serial RX. This

53 routine is run between each time loop() runs, so using delay inside loop can

54 delay response. Multiple bytes of data may be available.

55 */

56 void serialEvent()

57 {

58 while (Serial.available())

59 {

60 // get the new byte:

61 char inChar = (char)Serial.read();

62 // add it to the inputString:

63 inputString += inChar;

64 // if the incoming character is a newline, set a flag so the main loop can

65 // do something about it:

66 if (inChar == '\n')

67 {

68 stringComplete = true;

69 }

70 }

71 }

65