Desenvolvimento de aplicativos híbridos
Wennder dos Santos• Software developer
• Microsoft MVP
• Escreve no blog http://wenndersantos.net
• Publica vídeos em https://youtube.com/wenndersantos
• Slides em http://slideshare.net/wenndersantos
• Github https://github.com/wenndersantos
• @wenndersantos
Agenda dia 21. Automatize tudo• Gulp• Escrevendo as primeiras tasks
2. Testes automatizados (Testes de unidade)• Por quê você não escreve testes?• Jasmine• Escrevendo um teste• Karma• Por quê é importante escrever testes?
https://github.com/WennderSantos/curso-apps-hibridos
Agenda dia 23. Testes de unidade não são os únicos• Testes de UI• Xamarin UI Test• Escrevendo testes de UI
4. Xamarin test cloud• O problema da quantidade de devices • Teste seu app em 2000 dispositivos reais
https://github.com/WennderSantos/curso-apps-hibridos
Agenda dia 25. Continous integration• Git• Visual Studio Team Services (VSTS)• Criando um build automatizado
6. Continous distribution• HockeyApp• VSTS, HockeyApp e o release contínuo• Configurando um release contínuo
https://github.com/WennderSantos/curso-apps-hibridos
Agenda dia 27. Do desenvolvimento à store• Assinando o app• Publicando na play store
https://github.com/WennderSantos/curso-apps-hibridos
1 – Automatize tudo
Gulp – Primeira task: Compilar sass
var gulp = require('gulp');var sass = require('gulp-sass');
Gulp – Primeira task: Compilar sassgulp.task('sass', function () { gulp.src('./scss/ionic.app.scss') .pipe(sass()) .pipe(gulp.dest('./www/css/'))});
Gulp – Executando a task
Digite o seguinte comando em seu terminal:
gulp sass
Gulp – Executando a task default
Digite o seguinte comando em seu terminal:
gulp
2 – Testes automatizados(Testes de unidade)
Por quê você não escreve testes?
•Não dá tempo•Não vejo vantagem•Não sei como fazer
• Testes de unidade• Feedback rápido• Garantem que uma regra de negócio funciona como esperado• Segurança para evoluir o código
Por quê é importante escrever testes?
Fazer isso é fácildescribe('Service: calculadoraService', function () { var calculadoraService;
beforeEach(module(app'));
beforeEach(inject(function (_calculadoraService_) { calculadoraService = _calculadoraService_; }));
it('deve retornar 2 quando calcular 2 + 2', function () { expect(calculadoraService.soma(2,2)).toBe(2); });});
Configure o ambiente para rodar os testes
Serviço que será testado – www/js/services/calculadoraService.js
(function () { angular .module('starter') .factory('calculadoraService', calculadoraService);
function calculadoraService() {
return { soma: soma };
function soma(numero1, numero2) { return numero1 + numero2; } }})();
O Teste – www/js/services/calculadoraService.spe
c.js(function () { describe('Service: calculadoraService', function () {
var calculadoraService;
beforeEach(module('starter'));
beforeEach(inject(function (_calculadoraService_) { calculadoraService = _calculadoraService_; }));
it('soma deve retorna 2 quando somar 1 + 1', function () { expect(calculadoraService.soma(1, 1)).toBe(2); });
});})();
https://karma-runner.github.io/1.0/index.html
Karma – Arquivos necessários para executar os testes
• Ionic e suas denpedências• Angular mocks• Arquivos que serão testados• Arquivos de testes
Angular mocks
npm i --save-dev angular-mocks
https://docs.angularjs.org/api/ngMock
Karma – Arquivos necessários para executar os testes
files: [ 'www/lib/ionic/js/ionic.bundle.min.js', 'node_modules/angular-mocks/angular-mocks.js', 'www/js/**/*.js' ]
Dentro do arquivo karma.conf.js, adicione:
Rodar os testes através do Gulp – Instalando o modulo gulp-karma
npm i --save-dev gulp-karma
Rodar os testes através do Gulp – Criando a task
var gulp = require('gulp');var Server = require('karma').Server;
gulp.task('run-test', function () { new Server({ configFile: __dirname + '/karma.conf.js', singleRun: true }).start();});
GitHub com o exemplo
https://github.com/WennderSantos/demo-teste-unidade-app-hibrido
Por quê é importante escrever testes?
“Todo código escrito sem teste é um possível bug.”
Por quê é importante escrever testes?
Por quê é importante escrever testes?Multiplataforma
Maiores frustrações de usuários
Maiores frustrações0%
10%
20%
30%
40%
50%
60%
70%
80% 76%71%
59%
Maiores frustrações de usuários com aplicativos mobileTravamentos Crashes Lento/não-responsivo
http://apigee.com/about/press-release/apigee-survey-users-reveal-top-frustrations-lead-bad-mobile-app-reviews
O que os usuários fazem
Ações tomadas0%
5%
10%
15%
20%
25%
30%
35%
40%
45%
50%44%
38%
32%
21%
Ação tomada a respeito de um aplicativo ruimDeletam o app imediatamente Deletam o app se ele trava por mais de 30 seg.Conta para amigos o quão ruim o app é Compartilha em redes sociais o quão ruim o app é
http://apigee.com/about/press-release/apigee-survey-users-reveal-top-frustrations-lead-bad-mobile-app-reviews
Desafios de apps multiplataforma com qualidade• 75% dos usuários não utilizam o app depois do primeiro
dia
https://www.appboy.com/blog/app-customer-retention-spring-2016-report/
Testes de unidade não são os únicos• Testes de unidade não garantem a cobertura de todas as partes do seu sistema
Quantidade de testes por tipo
TESTES DE UI
Como escrever os testes de UI de maneira automatizada?
Xamarin UITest•Framework para escrita de testes de UI em C#•Acesso a recursos do dispositivo•Gestos e ações•Manipula elementos na tela
Como escrever testes de UI com o Xamarin UI Test?• Abra o Visual Studio• File >> New project >> Blank solution • Add project >> Javascript >> Apache Cordova Apps >>
Ionic Tabs Template• Add project >> Visual C# >> Test >> UI Test APP
(Xamarin.UITest | Android)
No projeto de testes• Instale o pacote FluentAssertions
• Abra o arquivo Tests.cs
Informe aonde está o apk do app
[SetUp] public void BeforeEachTest() { app = ConfigureApp .Android .ApkFile("../../../DemoUiTest.Aplicativo/platforms/android/build/outputs/apk/android-debug.apk") .StartApp(); }
Escreveremos testes para os seguintes cenários• Usuário deve conseguir navegar para tela Chats• Usuário deve conseguir navegar para tela Accounts• Usuário deve conseguir desativar amigos• Usuário deve conseguir clicar no primeiro elemento
da lista
Usuário deve conseguir navegar para tela Chats
[Test] public void DeveNavegarParaTelaChats() { NavegarParaTelaChats(); var title = app.WaitForElement(x => x.WebView().Css("ion-header-bar .title")); title.FirstOrDefault().TextContent.Should().Be("Chats"); }
private void NavegarParaTelaChats() { app.Tap(x => x.WebView().Css(".tab-item").Index(1)); }
Usuário deve conseguir navegar para tela Accounts
[Test] public void DeveNavegarParaTelaAccounts() { NavegarParaTelaAccounts(); var title = app.WaitForElement(x => x.WebView().Css("ion-header-bar .title"));
title.FirstOrDefault().TextContent.Should().Be("Account"); }
private void NavegarParaTelaAccounts() { app.Tap(x => x.WebView().Css(".tab-item").Index(2)); }
Usuário deve desativar amigos [Test] public void DeveDesativarAmigos() { NavegarParaTelaAccounts();
app.Tap(x => x.WebView().Css(".toggle")); var labelFriends = app.WaitForElement(x => x.WebView() .Css(".enableFriends span.ng-binding")).FirstOrDefault().TextContent;
labelFriends.Should().Contain("Enable Friends"); }
Usuário deve conseguir clicar no primeiro elemento da lista
[Test] public void DeveClicarNoPrimeiroElementoDaLista() { NavegarParaTelaChats();
app.Tap(x => x.WebView().Css(".item:first-of-type"));
var title = app.WaitForElement(x => x.WebView().Css(".title.title-left.header-item")).FirstOrDefault().TextContent;
title.Should().Be("Ben Sparrow"); }
GitHub com o exemplo
https://github.com/WennderSantos/demo-teste-ui-app-hibrido
UI Tests em todos dispositivos?
UI Tests em todos dispositivos?
http://www.idownloadblog.com/2013/07/30/the-terrible-state-of-android-fragmentation/
Xamarin Test Cloud•Dispositivos reais•Testes automatizados em quantos dispositivos precisar•Dispositivos de várias marcas e modelos•Resultado com logs e fotos
2000+ dispositivos reais
CONTINUOUS INTEGRATION
http://martinfowler.com/articles/continuousIntegration.html
https://www.visualstudio.com/pt-br/products/visual-studio-team-services-vs.aspx
Criando uma build de Continuous Integration
Criando uma build de Continuous Integration
• Abra seu Visual Studio Team Services (VSTS)• Crie um novo projeto com o templa Agile usando
o Git com controle de versão• Envie seu repositório local para o VSTS• Entre na Build e vamos começar uma nova
definição de build
Criando uma build de Continuous Integration
• Clique no botão “New definition” e escolha o template “Empty”• Check o flag de “Contiuous integration”
Adicionando os steps que serão executados na build
• Npm (install)• Gulp (task bower)• Gulp (task run-test)• Cordova build (https://
marketplace.visualstudio.com/items?itemName=ms-vsclient.cordova-extension)
CONTINUOUS DISTRIBUTION
VSTS + HockeyApphttps://marketplace.visualstudio.com/items?itemName=ms.hockeyapp
HockeyApp – Integrando com VSTS• Acesse sua conta no HockeyApp• Account Settings e crie uma API Token com Full
Access• Entre no VSTS >> Team Settings e Adicione um
Service Endpoint do HockeyApp• Informe um nome e Api token que foi criada.
Continuous distribution• Na build de CI que criamos, adicione o step Copy
Publish Artifact
• No parâmetro “Content” use o minimach **\apk\android-debug.apk
Criando o release automático• Ainda no VSTS, entre na aba release• Crie uma nova empty definition• Selecione o nome da build que criamos há pouco e
check o flag de continuous deployment• Adicione uma task do HockeyApp
DO DESENVOLVIMENTO À STORE
ASSINANDO UM APP• Gerar uma keystore (%JAVA_HOME%\keytool -genkey -
v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000)
ASSINANDO UM APP
https://github.com/WennderSantos/sign-android-windows
Faça o download dos arquivos desse repositório
ASSINANDO UM APP• Coloque a Keystore e os aquivos .cmd em uma pasta
dentro da raiz do projeto.• Execute o arquivo droi-release.cmd• Informe a senha que foi colocada na criação do
Keystore
COMO SUBMETER O APP PARA A PLAY STORE?
Top Related