2ª Reunião Porto - 14/04/2012   http://netponto.orgComo ser programador durante o dia e    mesmo assim dormir bem à noite ...
Bruno Lopes•   Co-founder de uma startup•   Tirei o curso há 6 anos•   80% do que fiz e faço é web e .Net•   Éramos uma em...
Motivação2000        2005       2007      2012Faculdade    Mestrado         weListen                   ?
3 actosNão são as ferramentas São as metodologias
Acto 1
Logging• Registo da aplicação de  – Acções  – Avisos  – Erros• Serve acima de tudo para diagnóstico• Muitas formas de faze...
Logging10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bln/11366 HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNK...
Logging
Logging  Aplicação      Infrastrutura   Persistência                                      Event                           ...
LoggingMau exemplo de infrastrutura/persistência
LoggingMuito mau exemplo de aplicaçãoprivate Sprocket DoWork(){    try    {        var sprocketFactory = new SprocketFacto...
Logging Melhor exemplo de aplicaçãoPM> install-package NLogSuccessfully installed NLog 2.0.0.2000.  private Logger Log = L...
Logging Wiring de configuração<?xml version="1.0" encoding="utf-8" ?><nlog xmlns="http://www.nlog-project.org/schemas/NLog...
Logging                           O quê?         NivelQuando            Onde
Logging
Como é que Logging me ajuda a           dormir melhor?• Menos tempo à procura de erros• Mais informação de diagnóstico• Nã...
Acto 2
Instrumentação           De Negócio                             Tecnologia             Volume                             ...
InstrumentaçãoProfilers      Counters   Dashboards
InstrumentaçãoProfilers      Counters   Dashboards
Profilers
Profilers
InstrumentaçãoProfilers      Counters   Dashboards
Counters - Windows
Counters – RavenDB /stats
Counters - etsy
InstrumentaçãoProfilers      Counters   Dashboards
Dashboards
Dashboards
Como é que Instrumentação me ajuda         a dormir melhor?• Consigo identificar  – Quais os problemas  – Antes que o clie...
Acto 3
Testes unitários•   Quem conhece o conceito?•   Quem regularmente usa?•   Quem acha que lhes poupa trabalho?•   Quem acha ...
Testes unitários[Fact]public void CanImportJustOneItemIntoPythonClassUsingDecorator(){    var pythonCode =                ...
Testes unitários[Fact]public void CanImportJustOneItemIntoPythonClassUsingDecorator(){    var pythonCode =                ...
Testes unitáriospublic class MakeSureIDoNotScrewUpHashingTests : TestClass{    [Fact]    public void DidIScrewUpHashingInN...
Testes unitários  Red GreenRefactor
Testes unitários                         automáticos• A correrem sempre em background   – (eu falei disto na minha apresen...
Testes unitários                  automáticos• Se repetimos, vemos se podemos automatizar  – Computador não se cansa nem s...
Testes unitários                           automáticosSetup                    Desenvolvimento       Produção    • Ir busc...
Como é que Automatização me ajuda        a dormir melhor?• Computadores a verificar comportamento  enquanto durmo• Posso a...
EpílogoNão são as ferramentasNão são as metodologias    São as pessoas
Questões?
Patrocinadores "GOLD"
Próximas reuniões presenciais• 14/04/2012 – Abril• 21/04/2012 – Abril (Lisboa)• 12/05/2012 – Maio (Coimbra)• 26/05/2012 – ...
Obrigado!Bruno Lopesbrunomlopes@gmail.comhttp://www.brunomlopes.comhttp://twitter.com/brunomlopes
Upcoming SlideShare
Loading in …5
×

Como ser programador durante o dia e mesmo assim dormir bem à noite

2,111 views
2,001 views

Published on

Apresentação do Bruno Lopes sobre variados temas como instrumentação, profiling, logging e boas práticas de programação e desenvolvimento de software, incluindo lições tiradas do processo de desenvolvimento, manutenção e suporte à produção de várias aplicaçoes e produtos, na 2a Reunião Presencial da Comunidade NetPonto (http://netponto.org) no Porto.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,111
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
19
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • ** Se o contexto onde estiverem for diferente, as lições podem ser aplicadas de forma diferente** Podem também ter incentivos suficientemente fortes para se tornarem pouco relevantes** Caveat emptor
  • Que é quegostavaque me tivessemchamadado a atençãonafaculdadeQue me tinhaajudadonaweListen
  • O foco aqui não é as ferramentas em siÉ as metodologias, pitfals e dicas
  • E por melhores que sejamos, vai ser sempre preciso fazer diagnóstico, nem que seja durante o desenvolvimento** Ou melhor, feedback correcto do que aconteceu
  • Quando me falamem logs, é nistoquecostumopensarCasomuitoconhecido, logs de servidor web (apache, nestecaso)
  • Windows tem o event viewer, queagregaeventos de log de váriossitios e é um serviçofornecidopelosistemaoperativoEstesdoiscasossão a perspectiva “persistida” dos eventos, queapenas é uma 3 partes.É o resultado final de fazer loggingEunãoquerofalardesta parte.
  • Logging tem 3 componentesAplicação é o quevocesdesenvolvem, e é a origemInfrastrutura e persistencianão é paravocestocarem (em 99% dos casos)Nlog é uma das infrastruturasem.net, outraseria log4net
  • Info maissensivelfoiremovidaExcepçãoguardadana Base de dadosMas cortamalipelomeio a stacktraceNestecasonãotemosinformaçãonenhuma de ondeestá a darerro, porquetoda a stack tarce é ocupadapor frames de infrastrutura
  • Quantasrazõesparafuzilar o autordestecódigoencontram?ExcepçãoignoradaRetornar null!!111Console.Out.WriteMesmocorrigindoisso:Printf é um mau exemplo porque em aplicações que são mais do que pequenos spikes, vamos querer:Redirecionarparabd/event viewerFilterbaseado no tipo/origem/nivelNãoincluiinformação de ondefoifeitoNão tem standard para output de excepçõesRseponder
  • NugetEmvez de irmos á consola, usamos um Logger Este logger podia serinjectadocomodependenciapor DI, mas essa é outraapresentaçãoTambém se calharnaodeviamosapanhar a excepçãoaqui, mas essa é outraapresentação
  • Configuramos (fazemos o wiring) de ondevaipara o quê.Em runtime devemos poder ligar/desligarPorque nem sempre queremos info de debugNem em todo o ladoQuando houver problemas, não queremos ter que estar a recompilar a aplicação e fazer outro deploy.Idealmente, enquanto se alterarmos o ficheiro enquanto corre, a aplicaçºao apanharia isso
  • O resultado é melhor, tem maisinformaçãoE se quiserempodemortogonalmenteaocódigoquefaz logging, acrescentarmaisparâmetros(layout renderer emNlog)Uma entrada de log deve ser explicitaWhoWhatWhenWhereTambém podemos incluir o URL e currentuser, mas isso será ortogonal aoLog.Info
  • E mesmo mesmomesmo fixe é quando as mensagens de erro nos ajudamIdealmente mensagens de erro, excepções devem nos ajudar a corrigirUm bom exemplo de excepção (aparte de algum Engrish):- Indica a causa mais provavel de erro e como corrigir
  • Mesmo abstrair uma biblioteca de logging é duvidoso, na minha opiniãoExcepto talvez para bibliotecas
  • Instrumentaçãohttp://photo-dictionary.com/phrase/7984/car-dashboard.htmlhttp://www.plane-pictures.com/Boeing-777/Boeing-777-Cockpit-242-picture.htm
  • Instrumentação de negócio
  • Profiler é uma aplicação, módulo ou parecido que ligamos na aplicação e nos mostra “as entranhas”Pode fazer profile a CódigoMemóriaLigações a bases de dados
  • Eu falo imenso desta ferramenta porque a acho genialÉ um profiler que “se atarracha” a aplicações de Nhibernate que nos permite tudo o que se passa entre a aplicação e a BD, com NhibernateMostra QueriesOnde é que foram executadosTempos de sessãoEstatisticasFerramenta indispensavel paraMonitorizar que não estou a fazer asneiraQuando estou a fazer asneira, perceber exactamente que asneira
  • Mini ProfilerFerramenta brutal, e mostra não só timings internos no servidor, como no browser webEste funciona em produção
  • Counters são apenas numeros que são guardados e analisadosTipicamente são dados “em barda”, com grande volume mas cada um é muito pequeno.Emitir este tipo de dados não deve ter impacto na performance da aplicação, e pode servir para análise histórica
  • Casomais simples: Performance counters de windowsQualquermaquina windows tem istoNestecaso de exemploestamos a olharpara dados de tempo de CPU no total, e dados de memória de umaaplicaçãochamada “ILoveLucene”Se nósestivermos com um problema de memóriaporexemplo, podiamosusarestegráfico e analisarquando é que a memóriasaltacoordenado com acções no software.
  • Aqui olhamos para “counters” que são emitidos por RavenDB (document database em .net).É informação “raw” que podemos guardar, ou apenas inspecionar momentaneamente para perceber o que se passa cá dentroNeste caso particular temos tambem alguma informação de diagnostico, como extensões activas
  • http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/Um caso muito interessante, na etsy eles monitorizam milhares de contadores, e aqui consegue-se não só detectar padrões, como permite “empurrar” código com mais confiança. Se algum contador começar a ter comportamentos fora do comum, consegue-se detectar e relacionar com uma actualizaçãoEtsy é um marketplace global para “handmade goods” e falam publicamente de como guardam dados para tudo.
  • SQLMonitor, uma ferramenta de monitorização de SQL, inclui info sobre top 10 queries, problemas de performance, carga
  • Esta é um toolkit para construir dashboards, por exemplo.
  • http://blog.autoworld.com.my/index.php/2009/02/26/swarm-technology-the-biggest-contribution-to-eco-tech/
  • Este terceiro acto começa com testes unitários.Quem conhece? Usa?Fixe, não fixe? Limitações?
  • Exemplo de um projecto opensource meuTetes tipicamente teem um padrao
  • AAAPermiteguiar o design da aplicação
  • Mas também podem servir para validar que não fazemos asneira (foco no nome do metodo)Capturoestainformaçãonumtestequepossocorrersempre
  • E se há coisa importante em testes unitários, e não só, é este ciclo
  • Invariantes como:- Todas as stored procedures na BD têm de estar configuradas para o role public as poder executar - Um teste pode verificar isto em todos os commitsUm determinado método tem que responder a todos os valores de um enum(se bem que neste caso pode fazer mais sentidoabstrair para uma classe em vez de enum)Verificar que todos os textos se encontram traduzidos em todas as linguasPor isso falo em testes automáticosDe unidade, para “comportamentos pequenos”De integração, para verifcar mapeamentos com base de dados, comportamento de componentes inteirosDe performance, para validar De interface, porque é o que o utilizador vê
  • Antes de terminar.Espero que esta apresentação vos tenha ajudado e mostrado algumas formas de melhorar o processo de desenvolver, manter e suportar software.
  • Como ser programador durante o dia e mesmo assim dormir bem à noite

    1. 1. 2ª Reunião Porto - 14/04/2012 http://netponto.orgComo ser programador durante o dia e mesmo assim dormir bem à noite Bruno Lopes
    2. 2. Bruno Lopes• Co-founder de uma startup• Tirei o curso há 6 anos• 80% do que fiz e faço é web e .Net• Éramos uma empresa de custom development• Agora estamos agora a vender, desenvolver, comercializar e suportar um produto
    3. 3. Motivação2000 2005 2007 2012Faculdade Mestrado weListen ?
    4. 4. 3 actosNão são as ferramentas São as metodologias
    5. 5. Acto 1
    6. 6. Logging• Registo da aplicação de – Acções – Avisos – Erros• Serve acima de tudo para diagnóstico• Muitas formas de fazer mal• Muitas formas de fazer bem
    7. 7. Logging10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bln/11366 HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /source/vendors/dbdeploy/1.0 HTTP/1.1" 207 712 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/vcc/default HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bc/11366/source/vendors/dbdeploy/1.0 HTTP/1.1" 207 1397 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/)t20111128_1553"10.0.0.10 - - [13/Apr/2012:01:12:24 +0100] "OPTIONS /source/gof/Dependencies/trunk HTTP/1.1" 401 482 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "OPTIONS /source/gof/Dependencies/trunk HTTP/1.1" 200 - "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /source/gof/Dependencies/trunk HTTP/1.1" 207 716 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/vcc/default HTTP/1.1" 207 384 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bln/11366 HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /source/gof/Dependencies/trunk HTTP/1.1" 207 716 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/vcc/default HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bc/11366/source/gof/Dependencies/trunk HTTP/1.1" 207 1693 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/)t20111128_1553"10.0.0.10 - - [13/Apr/2012:01:12:24 +0100] "OPTIONS /source/projects/build-scripts/trunk HTTP/1.1" 401 482 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "OPTIONS /source/projects/build-scripts/trunk HTTP/1.1" 200 - "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /source/projects/build-scripts/trunk HTTP/1.1" 207 728 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/vcc/default HTTP/1.1" 207 384 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bln/11366 HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /source/projects/build-scripts/trunk HTTP/1.1" 207 728 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/vcc/default HTTP/1.1" 207 443 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/) t20111128_1553"10.0.0.10 - read.only [13/Apr/2012:01:12:24 +0100] "PROPFIND /!svn/bc/11366/source/projects/build-scripts/trunk HTTP/1.1" 207 1432 "-" "SVN/1.6.17 SVNKit/1.3.6-v1 (http://svnkit.com/)t20111128_1553"10.0.0.114 - - [13/Apr/2012:01:12:50 +0100] "OPTIONS /documents HTTP/1.1" 401 482 "-" "SVN/1.7.1-SlikSvn-1.7.1-X64 neon/0.29.6"10.0.0.114 - bruno.lopes [13/Apr/2012:01:12:50 +0100] "OPTIONS /documents HTTP/1.1" 200 179 "-" "SVN/1.7.1-SlikSvn-1.7.1-X64 neon/0.29.6"10.0.0.114 - bruno.lopes [13/Apr/2012:01:12:52 +0100] "PROPFIND /documents HTTP/1.1" 207 676 "-" "SVN/1.7.1-SlikSvn-1.7.1-X64 neon/0.29.6"10.0.0.114 - bruno.lopes [13/Apr/2012:01:12:53 +0100] "REPORT /!svn/vcc/default HTTP/1.1" 200 9928054 "-" "SVN/1.7.1-SlikSvn-1.7.1-X64 neon/0.29.6"
    8. 8. Logging
    9. 9. Logging Aplicação Infrastrutura Persistência Event ViewerInnovationCast NLog Base de dados Ficheiros
    10. 10. LoggingMau exemplo de infrastrutura/persistência
    11. 11. LoggingMuito mau exemplo de aplicaçãoprivate Sprocket DoWork(){ try { var sprocketFactory = new SprocketFactory(); return sprocketFactory.Manufacture(); } catch (Exception e) { Console.Out.Write("An error OCURRED!!!11!!"); return null; }}
    12. 12. Logging Melhor exemplo de aplicaçãoPM> install-package NLogSuccessfully installed NLog 2.0.0.2000. private Logger Log = LogManager.GetCurrentClassLogger(); private Sprocket DoWorkBetter() { try { var sprocketFactory = new SprocketFactory(); return sprocketFactory.Manufacture(); } catch (Exception e) { Log.ErrorException("Error while manufacturing a sprocket", e); throw; } }
    13. 13. Logging Wiring de configuração<?xml version="1.0" encoding="utf-8" ?><nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="console" xsi:type="Console" /> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="console" /> </rules></nlog>
    14. 14. Logging O quê? NivelQuando Onde
    15. 15. Logging
    16. 16. Como é que Logging me ajuda a dormir melhor?• Menos tempo à procura de erros• Mais informação de diagnóstico• Não preciso de ligar à Maya para saber o que se passou• Boas mensagens de erro ajudam-me a resolver problemas mais depressa
    17. 17. Acto 2
    18. 18. Instrumentação De Negócio Tecnologia Volume Bases DeClientes Devoluções Servidores Aplicações Negócios Dados
    19. 19. InstrumentaçãoProfilers Counters Dashboards
    20. 20. InstrumentaçãoProfilers Counters Dashboards
    21. 21. Profilers
    22. 22. Profilers
    23. 23. InstrumentaçãoProfilers Counters Dashboards
    24. 24. Counters - Windows
    25. 25. Counters – RavenDB /stats
    26. 26. Counters - etsy
    27. 27. InstrumentaçãoProfilers Counters Dashboards
    28. 28. Dashboards
    29. 29. Dashboards
    30. 30. Como é que Instrumentação me ajuda a dormir melhor?• Consigo identificar – Quais os problemas – Antes que o cliente note• Observar o comportamento do sistema enquanto ele corre• Não tenho que divinar qual o problema – Consigo verificar, corrigir e refactorizar
    31. 31. Acto 3
    32. 32. Testes unitários• Quem conhece o conceito?• Quem regularmente usa?• Quem acha que lhes poupa trabalho?• Quem acha que é banha da cobra?
    33. 33. Testes unitários[Fact]public void CanImportJustOneItemIntoPythonClassUsingDecorator(){ var pythonCode = @"class StringItemSource: @import_one(IActOnItem) def import_action(self, action): self.action = action"; var engine = Python.CreateEngine(); var script = engine.CreateScriptSourceFromString(pythonCode); var typeExtractor = new ExtractTypesFromScript(engine); var exports = typeExtractor.GetPartsFromScript(script).ToList(); var container = new CompositionContainer(new TypeCatalog(typeof(MockExporter), typeof(MockImportActions))); var batch = new CompositionBatch(exports, new ComposablePart[] {}); container.Compose(batch); object action = exports.First().Instance.action; Assert.NotNull(action); Assert.IsAssignableFrom<IActOnItem>(action);}
    34. 34. Testes unitários[Fact]public void CanImportJustOneItemIntoPythonClassUsingDecorator(){ var pythonCode = Arrange @"class StringItemSource: @import_one(IActOnItem) def import_action(self, action): self.action = action"; var engine = Python.CreateEngine(); var script = engine.CreateScriptSourceFromString(pythonCode); var typeExtractor = new ExtractTypesFromScript(engine); var exports = typeExtractor.GetPartsFromScript(script).ToList(); Act var container = new CompositionContainer(new TypeCatalog(typeof(MockExporter), typeof(MockImportActions))); var batch = new CompositionBatch(exports, new ComposablePart[] {}); container.Compose(batch); object action = exports.First().Instance.action; Assert Assert.NotNull(action); Assert.IsAssignableFrom<IActOnItem>(action);}
    35. 35. Testes unitáriospublic class MakeSureIDoNotScrewUpHashingTests : TestClass{ [Fact] public void DidIScrewUpHashingInNewVersion() { var correctHash = GetSha1("converter", "id", "sourceid"); var newHash = new DocumentId("converter", "id", "sourceid", "learningid").GetId(); Assert.Equal(correctHash, newHash); } // Previous algorithm: private string GetSha1(string converterId, string Id, string SourceId) { var sha1 = SHA1.Create(); sha1.Initialize(); return BitConverter.ToString( sha1.ComputeHash(Encoding.UTF8.GetBytes(converterId) .Concat(Encoding.UTF8.GetBytes(Id)) .Concat(Encoding.UTF8.GetBytes(SourceId)) .ToArray())) .Replace("-", ""); }}
    36. 36. Testes unitários Red GreenRefactor
    37. 37. Testes unitários automáticos• A correrem sempre em background – (eu falei disto na minha apresentação de integração continua)• Não servem só para testar código – Também podem testar (supostas invariantes)• Já me salvaram o couro várias vezes – Novo requisito do cliente num projecto antigo – Especificamos novo comportamento com testes – Implementamos requisito e testes passam – Mas testes antigos falham – Eu não me ia lembrar de verificar isso • Mas a máquina de integração contínua lembra-se
    38. 38. Testes unitários automáticos• Se repetimos, vemos se podemos automatizar – Computador não se cansa nem se engana por estar com sono – Computador não se chateia por fazer a mesma coisa várias vezes – Bruno pode ir beber descafeinado enquanto Computador faz coisas sozinho
    39. 39. Testes unitários automáticosSetup Desenvolvimento Produção • Ir buscar • Templates • Deployment dependências • Sanity checks • Updates • Configurar BD • Testing • Montar ambiente
    40. 40. Como é que Automatização me ajuda a dormir melhor?• Computadores a verificar comportamento enquanto durmo• Posso actualizar sistemas enquanto durmo• Posso passar tarefas para um colega mais facilmente – Corre “.psake.ps1 update-whole-world” e já está
    41. 41. EpílogoNão são as ferramentasNão são as metodologias São as pessoas
    42. 42. Questões?
    43. 43. Patrocinadores "GOLD"
    44. 44. Próximas reuniões presenciais• 14/04/2012 – Abril• 21/04/2012 – Abril (Lisboa)• 12/05/2012 – Maio (Coimbra)• 26/05/2012 – Maio (Lisboa)Reserva estes dias na agenda! :)
    45. 45. Obrigado!Bruno Lopesbrunomlopes@gmail.comhttp://www.brunomlopes.comhttp://twitter.com/brunomlopes

    ×