SlideShare uma empresa Scribd logo
1 de 105
Qualidade de código Android
técnicas e ferramentas
1
Rafael Araujo
Android Developer Sênior
Campinas - SP, Brasil
2
O que será apresentado
Técnicas
Análise de padrão de código
Análise de código
Análise de projeto Android
Integração continua
3
Técnicas
Conhecimentos detalhados para resolução de um problema; a
parte material de uma arte
4
Pair programming
#tecnicas
Dois desenvolvedores trabalhando na mesma tarefa
Ambos com o mesmo objetivo
Ambos com diferente conhecimento
Um executa a tarefa (driver)
O outro observa e ajuda de uma forma mais macro (navigator)
5
Pair programming
#tecnicas6
Pair programming
#tecnicas
Driver
Navigator
7
Vale a pena fazer pair programming?
#tecnicas
Dois desenvolvedores fazendo o trabalho de um desenvolvedor
Um desenvolvedor Junior irá diminuir a velocidade do desenvolvedor Sênior
Menos trabalho pronto ao mesmo tempo
Porque colocar dois desenvolvedores fazendo o trabalho de um?
8
Ganhos do pair programming
#tecnicas
Minimizar falhas de código e de fluxo
Manutenibilidade
Confiança do código
Amadurecimento mútuo
Compartilhar conhecimento
Aumento de atenção/concentração
9
#tecnicas
Exemplo de pair programming
10
#tecnicas
Exemplo de pair programming
11
#tecnicas
Exemplo de pair programming
12
Exemplo de pair programming
#tecnicas13
Exemplo de pair programming (HARD)
14
Code review
#tecnicas
Um ou mais membros da equipe devem aprovar o código gerado
Feito através de ferramentas
Previne adicionar bugs
Disseminar conhecimento entre a equipe
Garantir código legível para todos
Garantir código familiarizado para todos
15
Ferramentas de code review
#tecnicas16
Como funciona code review
#tecnicas
Código em
review
Código
aprovado
Código
integrado
Código
gerado
Comentário
em review
17
Code review no Gerrit
#tecnicas
0
-1
+1
+2
Não está OK. Por favor, olhe meus comentários
Código enviado. Por favor, revisem
Está OK, mas prefiro que mais alguém confirme
Está OK, aprovado!
18
Medidor de
qualidade do
Code Review
#tecnicas19
Atenção no
Code Review
#tecnicas20
Quebrar métodos para melhor leitura
#tecnicas
private void findJonSnow(List<Person> persons) {
for (Person person : persons) {
if (person.getHouse().getName().equals("Stark")) {
if (person.isAlive()) {
if (person.getName().equals("Jon Snow")) {
Log.i(TAG, "Jon Snow was founded!");
}
}
}
}
}
21
Comentários mais compreensiveis
#tecnicas
private boolean isAlive(Person person) {
// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
// eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
// ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
// aliquip ex ea commodo consequat. Duis aute irure dolor in
// reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
// pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
// culpa qui officia deserunt mollit anim id est laborum
return person.isAlive();
}
22
JavaDoc auto-explicativo
#tecnicas
/**
* Returns if the person is alive.
*
* @param person Person to check if is alive.
* @return <code>true</code> if is alive. <code>false</code> otherwise.
*/
private boolean isAlive(Person person) {
return person.isAlive();
}
23
Soluções melhores
#tecnicas
int countPersons(List<Person> persons) {
int counter = 0;
for (Person person : persons) {
counter++;
}
return counter;
}
int countPersons(List<Person> persons) {
return persons.size();
}
24
"Rubber duck debugging"
#tecnicas25
Qualquer um pode ser um pato de borracha
#tecnicas26
Ferramentas
Don't be a fool. Use a tool.
27
Android Studio + Gradle
Organizar arquivos de configuração de ferramentas
Garantir sempre o uso das ferramentas
Gradle e amigos
28
project/
├── app/ (módulo app do projeto)
│ └── src/
│ └── build.gradle (gradle do módulo)
│ └── ...
├── build.gradle (gradle do projeto)
├── ...
29
project/
├── app/
│ └── src/
│ └── build.gradle
│ └── ...
├── config/ (Pasta de configuração)
│ └── quality/ (Pasta de configuração)
│ └── quality.gradle (gradle da
qualidade)
├── build.gradle
├── ...
30
apply plugin: 'com.android.application'
apply from: '../config/quality.gradle'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
...
}
...
31
#ferramentas
Manter padrão estético do código
Deixar a equipe confortável com o código
O código é da equipe
Valida se o código mantem o padrão Java​
Plugin está no Android Studio, porém desabilitado
32
if (isSupported) {
doSomething();
}
if (isSupported)
{
doSomething();
}
#ferramentas33
#ferramentas
Você não precisa seguir um padrão
se não tiver um padrão no projeto
34
if (isSupported) {
doSomething();
}
if (isSupported)
{
doSomething();
}
#ferramentas35
#ferramentas
if (isSupported) {
doSomething();
}
if (isSupported)
{
doSomething();
}
36
#ferramentas37
#ferramentas38
#ferramentas39
apply from: "../config/quality/checkstyle.gradle"
config/
├── quality/
│ └── checkstyle/
│ └── checkstyle.xml
│ └── checkstyle.gradle
├── quality.gradle
#ferramentas40
apply plugin: 'checkstyle'
checkstyle {
configFile file("${rootDir}/config/quality/checkstyle/checkstyle.xml")
toolVersion = "8.2"
}
task checkstyle(type: Checkstyle) {
source 'src/main/java'
include '**/*.java'
classpath = project.configurations.compile
}
check.dependsOn 'checkstyle'
#ferramentas41
<!DOCTYPE ...>
​<module name="Checker">
<module name="NewlineAtEndOfFile">
<property name="severity" value="ignore"/>
</module>
<module name="JavadocMethod">
<property name="scope" value="package"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
</module>
</module>
#ferramentas42
#ferramentas
public void allAlive(List<Person > pers) {
for (Person person : pers)
if (person.isAlive()) {
Log.i(TAG, "Person is alive!");
} else {
}
}
43
#ferramentas44
#ferramentas45
#ferramentas
public void allAlive(List<Person > pers) {
for (Person person : pers)
if (person.isAlive()) {
Log.i(TAG, "Person is alive!");
} else {
}
}
46
#ferramentas
public void allAlive(List<Person > pers) {
for (Person person : pers)
if (person.isAlive()) {
Log.i(TAG, "Person is alive!");
} else {
}
}
/**
* Print if anyone is alive.
*/
public void allAlive(List<Person> pers) {
for (Person person : pers) {
if (person.isAlive()) {
Log.i(TAG, "Person is alive!");
}
}
}
47
#ferramentas48
#ferramentas49
#ferramentas
150 regras
checkstyle.sourceforge.net/checks.html
50
#ferramentas
“Pretty Much Done” ou “Project Meets Deadline”
Inspeciona o código escrito procurando possíveis bugs
Código desnecessário, com muita complexidade ou confuso, tamanho de
declarações​, mal uso de memória e processamento, etc
Plugin está no Android Studio, porém desabilitado
51
apply from: "../config/quality/checkstyle.gradle"
apply from: "../config/quality/pmd.gradle"
config/
├── quality/
│ └── checkstyle/
│ └── checkstyle.xml
│ └── checkstyle.gradle
│ └── pmd/
│ └── pmd-ruleset.xml
│ └── pmd.gradle
├── quality.gradle
#ferramentas52
#ferramentas
apply plugin: 'pmd'
task pmd(type: Pmd) {
ignoreFailures = false
ruleSetFiles = files("${project.rootDir}/config/quality/pmd/pmd-ruleset.xml")
ruleSets = []
source 'src'
include '**/*.java'
exclude '**/gen/**'
reports {
html.enabled = true
html {
destination "${project.buildDir}/reports/pmd/pmd.html"
}
}
}
check.dependsOn 'pmd'
53
<ruleset ...>
<exclude-pattern>.*/R.java</exclude-pattern>
<exclude-pattern>.*/gen/.*</exclude-pattern>
<rule ref="rulesets/java/android.xml"/>
<rule ref="rulesets/java/controversial.xml">
<exclude name="AtLeastOneConstructor"/>
</rule>
<rule ref="rulesets/java/braces.xml"/>
<rule ref="rulesets/java/strings.xml"/>
<rule ref="rulesets/java/basic.xml"/>
<rule ref="rulesets/java/naming.xml"/>
</ruleset>
#ferramentas54
#ferramentas
private boolean isMelisandre(Person p) {
Boolean result = new Boolean(false);
String melisandre = new String("Melisandre");
if (p.getName().equals(melisandre.toString())) {
result = true;
}
return result;
}
55
#ferramentas56
#ferramentas57
#ferramentas
private boolean isMelisandre(Person p) {
Boolean result = new Boolean(false);
String melisandre = new String("Melisandre");
if (p.getName().equals(melisandre.toString())) {
result = true;
}
return result;
} 58
#ferramentas
private boolean isMelisandre(Person person) {
Boolean result = Boolean.FALSE;
String melisandre = "Melisandre";
if (person.getName().equals(melisandre)) {
result = true;
}
return result;
}
private boolean isMelisandre(Person p) {
Boolean result = new Boolean(false);
String melisandre = new String("Melisandre");
if (p.getName().equals(melisandre.toString())) {
result = true;
}
return result;
}
59
#ferramentas60
#ferramentas
280 regras
pmd.github.io/pmd-5.8.1/pmd-java/rules/index.html
61
#ferramentas
Similar ao PMD, porém atua direto no bytecode
Além de bugs busca potenciais problemas de segurança
Plugin está no Android Studio, porém desabilitado
62
apply from: "../config/quality/checkstyle.gradle"
apply from: "../config/quality/findbugs.gradle"
apply from: "../config/quality/pmd.gradle"
#ferramentas
config/
├── quality/
│ └── checkstyle/
│ └── checkstyle.xml
│ └── checkstyle.gradle
│ └── pmd/
│ └── pmd-ruleset.xml
│ └── pmd.gradle
│ └── findbugs/
│ └── findbugs-filter.xml
│ └── findbugs.gradle
├── quality.gradle
63
apply plugin: 'findbugs'
task findbugs(type: FindBugs, dependsOn: "assembleDebug") {
ignoreFailures = false
effort = "max"
reportLevel = "low"
excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
classes = files("${project.rootDir}/app/build/intermediates/classes")
source 'src'
include '**/*.java'
exclude '**/gen/**'
reports {
html.enabled = true
html {
destination "${project.buildDir}/reports/findbugs/findbugs.html"
}
}
classpath = files()
}
check.dependsOn 'findbugs'
#ferramentas64
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<Class name="~.*.R$.*"/>
</Match>
<Match>
<Class name="~.*.Manifest$.*"/>
</Match>
<!-- All bugs in test, except for JUnit-specific bugs -->
<Match>
<Class name="~.*.*Test"/>
<Not>
<Bug code="IJU"/>
</Not>
</Match>
</FindBugsFilter>
#ferramentas65
#ferramentas
private void persons() {
Person arya = new Person("Arya Stark");
Person jaqen = new Person("Jaqen H'ghar");
whoAreYou(arya);
whoAreYou(null);
}
private void whoAreYou(Person person) {
Log.d(TAG, "Who are you?" + person.getName());
}
private void isNoOne(Person person) { }
66
#ferramentas67
#ferramentas68
#ferramentas69
#ferramentas70
#ferramentas
private void persons() {
Person arya = new Person("Arya Stark");
Person jaqen = new Person("Jaqen H'ghar");
whoAreYou(arya);
whoAreYou(null);
}
private void whoAreYou(Person person) {
Log.d(TAG, "Who are you?"
+ person.getName());
}
private void isNoOne(Person person) { } 71
#ferramentas
private void persons() {
Person arya = new Person("Arya Stark");
Person jaqen = new Person("Jaqen H'ghar");
whoAreYou(arya);
whoAreYou(null);
}
private void whoAreYou(Person person) {
Log.d(TAG, "Who are you?"
+ person.getName());
}
private void isNoOne(Person person) { }
private void persons() {
Person arya = new Person("Arya Stark");
Person jaqen = new Person("Jaqen H'ghar");
whoAreYou(arya);
whoAreYou(jaqen);
}
private void whoAreYou(Person person) {
Log.d(TAG, "Who are you?"
+ person.getName());
}
72
#ferramentas73
#ferramentas74
#ferramentas
420 regras
findbugs.sourceforge.net/bugDescriptions.html
75
#ferramentas
Analisa todo o projeto, não só o código
Possíveis bugs, resources não utilizados, segurança e performance
Checagens tem prioridade, gravidade e categoria
Plugin está no Android Studio, porém desabilitado
Lint
76
#ferramentas
config/
├── quality/
│ └── checkstyle/
│ └── pmd/
│ └── findbugs/
│ └── lint/
│ └── lint.xml
│ └── checkstyle.gradle
│ └── findbugs.gradle
│ └── lint.gradle
│ └── pmd.gradle
├── quality.gradle
Lint
77
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
...
}
lintOptions {
apply from: "${rootDir}/config/quality/lint.gradle", to: it
lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
htmlOutput file("${project.buildDir}/reports/lint/lint-result.html")
xmlOutput file("${project.buildDir}/reports/lint/lint-result.xml")
}
}
#ferramentas
Lint
78
warningsAsErrors true
abortOnError true
xmlReport false
htmlReport true
#ferramentas
Lint
79
<lint>
<issue id="NewApi" severity="ignore"/>
</lint>
#ferramentas
Lint
80
#ferramentas
Lint
81
#ferramentas
Lint
<TextView
android:id="@+id/activity_main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quality Fest 2017"/>
82
#ferramentas
Lint
<LinearLayout...>
<LinearLayout...>
<TextView...>
</LinearLayout>
</LinearLayout>
83
#ferramentas
Lint
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="confirmButton"
android:text="@string/app_name"/>
84
#ferramentas
Lint
@Override
protected void onCreate(Bundle bundle) {
setContentView(R.layout.activity_main);
}
85
#ferramentas
Lint
compile 'com.android.support:appcompat-v7:+'
86
#ferramentas
Lint
87
#ferramentas
Lint
<EditText
android:id="@+id/main_user_password"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
88
#ferramentas
Lint
private void isNull(String name) {
Objects.requireNonNull(name, "Name is null");
}
89
#ferramentas
Lint
@SuppressLint("NewApi")
private void isNull(String name) {
Objects.requireNonNull(name, "Name is null");
}
<EditText
android:id="@+id/main_user_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="TextFields"/>
90
#ferramentas
Organização de features
Notifique todos da equipe que o código foi alterado
Code review!
91
#ferramentas92
#ferramentas93
#ferramentas94
#ferramentas
Integração continua
Verificação a cada commit
E-mail avisando a equipe
95
#ferramentas
Roda
Checkstyle
Roda
PMD
Roda
FindBugs
Roda
Lint
Roda Testes
Unitários
Code
Review
Código
gerado
Código
integrado
96
Code review
no Github
#ferramentas97
Code review
no Github
#ferramentas98
#ferramentas99
#ferramentas100
#ferramentas101
Como eram as entregas X Como serão as entregas
102
Como eram as entregas X Como serão as entregas
103
github.com/orafaaraujo/QualityFest-17
104
Obrigado!
@orafaaraujo
/in/rafaeldearaujo
/orafaaraujo
105

Mais conteúdo relacionado

Mais procurados

[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...
[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...
[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...GUTS-RS
 
Java+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalJava+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalEduardo Bregaida
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Claudinei Brito Junior
 
Criando aplicações com PHP-GTK
Criando aplicações com PHP-GTKCriando aplicações com PHP-GTK
Criando aplicações com PHP-GTKPablo Dall'Oglio
 

Mais procurados (8)

[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...
[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...
[GUTS-RS] Workshop (prático) de Testes Automatizados para dispositivos móveis...
 
TDD em 220V
TDD em 220VTDD em 220V
TDD em 220V
 
Java acsp
Java acspJava acsp
Java acsp
 
Java+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalJava+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso Total
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
 
Be React. Do Tests!
Be React. Do Tests!Be React. Do Tests!
Be React. Do Tests!
 
Criando aplicações com PHP-GTK
Criando aplicações com PHP-GTKCriando aplicações com PHP-GTK
Criando aplicações com PHP-GTK
 
BDD com Cucumber
BDD com CucumberBDD com Cucumber
BDD com Cucumber
 

Semelhante a Qualidade código Android técnicas ferramentas

Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a TestesGregorio Melo
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoFreedom DayMS
 
Todas as abordagens de testes dentro do ágil
Todas as abordagens de testes dentro do ágilTodas as abordagens de testes dentro do ágil
Todas as abordagens de testes dentro do ágilElias Nogueira
 
4. Introdução à linguagem de programação Java – Fundamentos de Programação
4. Introdução à linguagem de programação Java – Fundamentos de Programação4. Introdução à linguagem de programação Java – Fundamentos de Programação
4. Introdução à linguagem de programação Java – Fundamentos de ProgramaçãoManuel Menezes de Sequeira
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
TDC2016POA | Trilha Web - Front-end that scales
TDC2016POA | Trilha Web - Front-end that scalesTDC2016POA | Trilha Web - Front-end that scales
TDC2016POA | Trilha Web - Front-end that scalestdc-globalcode
 
Treinamento básico de Android
Treinamento básico de AndroidTreinamento básico de Android
Treinamento básico de AndroidTiago Barreto
 
TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores
TDC2016 Boas Práticas SQL em Banco Relacional para DesenvolvedoresTDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores
TDC2016 Boas Práticas SQL em Banco Relacional para DesenvolvedoresFernando Franquini
 
Aulas Google Android
Aulas Google AndroidAulas Google Android
Aulas Google AndroidIury Teixeira
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5Diego Pacheco
 
JavaScript Firme: Módulos com RequireJS e BDD com Jasmine
JavaScript Firme: Módulos com RequireJS e BDD com JasmineJavaScript Firme: Módulos com RequireJS e BDD com Jasmine
JavaScript Firme: Módulos com RequireJS e BDD com JasmineAndré Willik Valenti
 
Kyrios: Infra-estrutura livre para desenvolvimento de software
Kyrios: Infra-estrutura livre para desenvolvimento de softwareKyrios: Infra-estrutura livre para desenvolvimento de software
Kyrios: Infra-estrutura livre para desenvolvimento de softwareFábio Nogueira de Lucena
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokReduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokWellington Pinheiro
 
Tdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalTdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalAdriano Petrich
 

Semelhante a Qualidade código Android técnicas ferramentas (20)

Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a Testes
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
 
Todas as abordagens de testes dentro do ágil
Todas as abordagens de testes dentro do ágilTodas as abordagens de testes dentro do ágil
Todas as abordagens de testes dentro do ágil
 
4. Introdução à linguagem de programação Java – Fundamentos de Programação
4. Introdução à linguagem de programação Java – Fundamentos de Programação4. Introdução à linguagem de programação Java – Fundamentos de Programação
4. Introdução à linguagem de programação Java – Fundamentos de Programação
 
Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
TDC2016POA | Trilha Web - Front-end that scales
TDC2016POA | Trilha Web - Front-end that scalesTDC2016POA | Trilha Web - Front-end that scales
TDC2016POA | Trilha Web - Front-end that scales
 
Treinamento básico de Android
Treinamento básico de AndroidTreinamento básico de Android
Treinamento básico de Android
 
TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores
TDC2016 Boas Práticas SQL em Banco Relacional para DesenvolvedoresTDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores
TDC2016 Boas Práticas SQL em Banco Relacional para Desenvolvedores
 
Aulas Google Android
Aulas Google AndroidAulas Google Android
Aulas Google Android
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5
 
JavaScript Firme: Módulos com RequireJS e BDD com Jasmine
JavaScript Firme: Módulos com RequireJS e BDD com JasmineJavaScript Firme: Módulos com RequireJS e BDD com Jasmine
JavaScript Firme: Módulos com RequireJS e BDD com Jasmine
 
Precisamos falar sobre Gradle
Precisamos falar sobre GradlePrecisamos falar sobre Gradle
Precisamos falar sobre Gradle
 
Google apps script - Parte - 1
Google apps script - Parte - 1Google apps script - Parte - 1
Google apps script - Parte - 1
 
Kyrios: Infra-estrutura livre para desenvolvimento de software
Kyrios: Infra-estrutura livre para desenvolvimento de softwareKyrios: Infra-estrutura livre para desenvolvimento de software
Kyrios: Infra-estrutura livre para desenvolvimento de software
 
Design Patterns em Ruby
Design Patterns em RubyDesign Patterns em Ruby
Design Patterns em Ruby
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Reduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com LombokReduzindo o boilerplate code com Lombok
Reduzindo o boilerplate code com Lombok
 
Tdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalTdd em django sem desculpas versao final
Tdd em django sem desculpas versao final
 

Qualidade código Android técnicas ferramentas