quarta-feira, novembro 19, 2008

Melhorando a qualidade e a testabilidade de um sistema com técnicas para quebra de dependências

Em código de sistemas legados (e mesmo os que não deveriam ser tão legados assim!) encontramos módulos, classes ou métodos muito acoplados entre si e difíceis de serem testados unitariamente. Como os grandes papas do desenvolvimento de software explicam, esse tipo de dificuldade de testar possui forte ligação com um design ou arquitetura ruim.

Portanto: Código com alto nível de testabilidade é código bem projetado e código difícil de testar é mal projetado.

Usando técnicas (como refactoring, Test-Driven Development e Design Emergente) e design patterns apropriados podemos evitar um projeto ruim. Mas como melhorar a testabilidade de classes orientadas a objeto que não foram implementadas dessa forma? Para isso podemos usar algumas técnicas e refatorações (refactorings) apropriados. Isso facilitará os testes unitários de classes críticas de seu sistema e ainda, por tabela, melhorará o design de parte de seu sistema.

Para ajudar no entendimento das técnicas, vamos começar pelo exemplo simples de código Java abaixo:

public class TaxaDAO {
public double fetchRate(){
double rate = 0.0;
// Código para acessar o banco de dados e selecionar a taxa de uma tabela.
return rate;
}
}

public class BusinessRule {
private double commissionRate;
private TaxaDAO myTaxaDAO;

public BusinessRule(){
myTaxaDAO = new TaxaDAO();
this.commissionRate = 10.0;
}
public float getRate(){
double baseRate = myTaxaDAO.fetchRate();
return baseRate + (baseRate * commissionRate);
}
}

Neste exemplo, a classe BusinessRule possui comportamento testável e é importante testar o método getRate(). Porém, este depende diretamente de TaxaDAO. Podemos dizer que TaxaDAO é um objeto efêmero. Ele é efêmero porque possui um estado imprevisível. O valor de retorno do método fetchRate() irá variar de acordo com o conteúdo que está no banco de dados naquele momento específico. E essa imprevisibilidade afeta a testabilidade de qualquer objeto que use TaxaDAO. Além disso, não é boa prática criar testes unitários que dependam de operações de custo alto e tempo longo (conectar e acessar um banco de dados é uma delas).

Uma solução para esse problema seria criar uma versão de TaxaDAO que não entra em contado com a base de dados, retornando um valor conhecido sempre. De acordo com Koskela, dependendo do grau de complexidade este objeto alternativo pode ser conhecido como um stub, um fake ou um mock.

Mas ainda temos um problema. Como podemos fazer o objeto BusinessRule usar a versão substituta de TaxaDAO? Da forma como o design do código de produção está, isso é inviável. Aí podemos usar a primeira técnica de refactoring que nos ajudará nessa tarefa gloriosa: a refatoração Extract Interface. No clássico livro original de MartinFowler, a motivação para o uso de Extract Interface é quando várias classes possuem responsabilidades similares. Mas Michael Feathers nos explica que essa refatoração também é uma excelente técnica para quebrar as dependências entre módulos.

Vamos então para esta que é uma refatoração simples e que aplicaremos na classe TaxaDAO (você poderia fazê-la manualmente ou então usar o recurso de uma IDE que suporte refatorações. A última opção é melhor porque economiza seu tempo e seu cérebro... he, he).

public interface ITaxaDAO {
double fetchRate();
}

public class TaxaDAO implements ITaxaDAO {
public double fetchRate(){
double rate = 0.0;
// Código para acessar o banco de dados e selecionar a taxa de uma tabela.
return rate;
}
}

Extremamente simples, não é? Pois é, muitos refactorings são simples de fazer, outros nem tanto. O importante é que precisamos conhecê-los a fundo para sermos bom desenvolvedores de software! Mas voltando ao nosso exemplo depois da divagação...

Ainda não resolvemos o problema da dependência, pois precisamos modificar a classe BusinessRule. Temos duas possibilidades para resolver a quebra de dependência. Vamos mostrar primeiro a técnica de endo-testing.

Para fazer o endo-testing funcionar devemos primeiro aplicar outro refactoring na classe BusinessRule. É a refatoração Extract and override factory method. TEmos que também modificar a classe para utilizar a interface ITaxaDAO ao invés do objeto concreto TaxaDAO.

public class BusinessRule {
private double commissionRate;
private ITaxaDAO myTaxaDAO;

public BusinessRule(){
myTaxaDAO = makeTaxaDAO();
this.commissionRate = 10.0;
}

protected ITaxaDAO makeTaxaDAO(){
return new TaxaDAO();
}

public float getRate(){
double baseRate = myTaxaDAO.fetchRate();
return baseRate + (baseRate * commissionRate);
}
}

E voilá! Criamos um método chamado makeTaxaDAO() que cria o objeto concreto. O construtor agora faz referência apenas à interface ITaxaDAO. De acordo com Feathers, criação "hard-coded" de objetos diretamente no construtor é ruim quando queremos colocar uma classe sob teste. A refatoração Extract and override factory metgod é extremamente poderosa e simples para nos ajudar.

Mas ainda não terminamos. Como realizar essas refatorações nos ajuda a testar o código? Vamos mostrar agora como seria o código do teste unitário da classe BusinessRule, utilizando a técnica de mocks.

public class BusinessRuleTest extends TestCase {
private BusinessRule testBR;
private MockControl control;
private ITaxaDAO mockDAO;

public void setUp(){
control = EasyMock.controlFor(ITaxaDAO.class);
mockDAO = (ITaxaDAO)control.getMock();
testBR = new BusinessRule(){
protected ITaxaDAO makeTaxaDao(){
return mockDAO();
};
}
public void testGetRate(){
mockDAO.fetchRate();
control.setReturnValue(50.00);
control.activate();

assertEquals("Testando getRate()", 50 * .10,
testBR.getRate())
}
}

Que maluquices fizemos no código do teste unitário? Bom, não vou entrar em detalhes sobre o mock (espere os próximos capítulos!). Mas precisamos explicar o que acontece na criação de um novo objeto BusinessRule, para entender a sacada do endo-testing. O que fizemos na criação de BusinessRule foi criar uma inner class anônima que extende BusinessRule, mas que sobrescreve (overriding) o método makeTaxaDAO() para que ele retorne o mock do DAO ao invés do TaxaDAO concreto! Dessa forma, conseguimos resolver o problema da efemeralidade do objeto que acessa o banco de dados e ainda deixamos o design mais testável e orientado a serviços.

Mas esperem! Ainda não terminou :-). Eu comentei que há duas possibilidades para deixar a classe BusinessRule mais testável. Vamos mostrar a segunda técnica agora, com o uso de Dependency Injection. Algumas pessoas não gostam muito de fazer isso. Uma delas é o Scott Bain, autor do grande livro Emergent Design. Ele é fã do endo-testing. Mas, para quem vai usar um container de Inversão de Controle, nada melhor que usar essa segunda técnica. A injeção de dependências nada mais é que uma forma de definir uma classe de modo que ela receba uma dependência externa e não a acople diretamente no código. Vamos a um exemplo disso antes de voltar ao nosso código.

public interface IFoo
{
void bar();
void baz();
}

public class DatabaseFoo implements IFoo
{
void bar()
{
Database.selectBar().execute();
}

void baz()
{
Database.selectBaz().run();
}
}

A classe DatabaseFoo implementa a interface IFoo no código acima. Agora como uma classe poderia usar o objeto DatabaseFoo? O modo típico seria assim:

public class ImportantClass {
IFoo foo;

public ImportantClass()
{
this.foo = new DatabaseFoo();
}

void doReallyImportantStuff()
{
this.foo.bar();
}
}

Fazendo desta forma acima na classe ImportantClass, nós simplesmente detonamos a idéia de interfaces, já que estamos acoplando nosso código diretamente a DatabaseFoo. Como podemos resolver o problema? Injetando a dependência! Abaixo temos o construtor modificado para receber a interface IFoo como parâmetro.

public ImportantClass(IFoo foo)
{
this.foo = foo;
}

Essa é a famosa constructor-based injection. Poderia ser ainda field-based ou setter-based. Mas para o nosso exemplo a injeção via construtor já basta. Vamos retornar então ao nosso código e refatorá-lo para aceitar a injeção de dependência.

public class BusinessRule {
private double commissionRate;
private ITaxaDAO myTaxaDAO;

public BusinessRule(ITaxaDAO umTaxaDAO){
myTaxaDAO = umTaxaDAO();
this.commissionRate = 10.0;
}

public float getRate(){
double baseRate = myTaxaDAO.fetchRate();
return baseRate + (baseRate * commissionRate);
}
}

Perceba que usando essa técnica não precisamos de um factory method. O que fazemos é injetar um objeto que implemente ITaxaDAO diretamente via construtor. Vamos ver então como ficaria o teste de BusinessRule que utiliza injeção de dependência.

public class BusinessRuleTest extends TestCase {
private BusinessRule testBR;
private MockControl control;
private ITaxaDAO mockDAO;

public void setUp(){
control = EasyMock.controlFor(ITaxaDAO.class);
mockDAO = (ITaxaDAO)control.getMock();
testBR = new BusinessRule(mockDAO);
}
public void testGetRate(){
mockDAO.fetchRate();
control.setReturnValue(50.00);
control.activate();

assertEquals("Testando getRate()", 50 * .10,
testBR.getRate())
}
}

Note que agora nosso teste unitário não precisa mais de uma inner class anônima. O que fazemos é injetar diretamente o nosso Mock (lembre que ele implementa a mesma interface ITaxaDAO) através do construtor do objeto BusinessRule!

Alguém pode perguntar então: Legal, no teste unitário é perfeito, mas... e no código de produção? Como faremos a ligação, o acoplamento entre BusinessRule e TaxaDAO? É aí que entram os famosos frameworks de Inversão de Controle (IoC - Inversion of Control) como Spring, Google Guice, NInject, Unity e etc. Eles é que fazem a amarração e injetam as dependências necessárias. Mas esse artigo está muito longo, e não vou entrar em detalhes sobre esse assunto :-) .

Vamos concluir então: um sistema com boa testabilidade costuma ser um sistema mais bem projetado e arquitetado. Conforme detalhado por Meszaros, quando você utiliza técnicas como o Test-Driven Development você naturalmente acaba projetando para testabilidade (design for testability). Mesmo em sistemas legados, com algumas refatorações, podemos melhorar enormemente a testabilidade do sistema e, consequentemente, aumentar sua qualidade interna e externa.

Referências:

Michael Feathers - Working Effectively with Legacy Code
Gerard Meszaros - xUnit Test Patterns
Martin Fowler - Refactoring: Improving the Design of Existing Code
Scott Bain - Emergent Design
Lasse Koskela - Test-Driven: Practical TDD an Acceptance TDD for Java Developers
Artigo na IBM DeveloperWorks - Unit Testing with Mock Objects
Artigo na Wikipedia - Dependency Injection

terça-feira, novembro 18, 2008

Declínio e Queda do Movimento Ágil?

Muita discussão aconteceu em torno de um segundo assunto nas listas e blogs de desenvolvimento ágil. O tópico se originou a partir do artigo de James Shore The Decline and Fall of Agile. Antes de dar minha opinião propriamente dita é interessante lembrar do livro de Edward Yourdon intitulado The Decline and Fall of the american programmer. Yourdon previu no livro que organizações de software e desenvolvedores americanos perderiam completamente seus negócios e empregos para desenvolvedores de outros países. É claro que isso não aconteceu e Yourdon até escreveu uma retratação de suas previsões no livro Rise and Ressurrection of the american programmer.

Poucos devem ter percebibo a semelhança do título do artigo de James Shore e do livro de Yourdon. Menos pessoas ainda devem fazer a alusão ao clássico livro de História de Edward Gibbon intitulado The History of the decline and fall of the roman empire. A grande diferença é que Gibbon escreveu seu livro posteriormente aos fatos relatados (por isso é História), enquanto Yourdon e Shore escreveramm como previsões (por isso é Futurologia). Esse comentário é só para lembrar que até grandes mestres e profundos conhecedores em determinados campos podem errar.

Mas vamos passar agora aos argumentos de Shore.

De acordo com ele, centenas de empresas estão aplicando mal o desenvolvimento ágil. Muitas estão falhando em atingir seus objetivos de iteração, estão tendo muito débito técnico e não conseguem testar suas aplicações. Segundo Shore, o problema está em que essas organizações e equipes usam apenas o que é mais fácil no Scrum (iterações e scrums) e ignoram as práticas de engenharia (como Test-Driven Development, Refactoring, Pair Programming, Testes de aceitação automatizados, Integração Contínua, etc). Concordo 100% com ele nesse sentido: equipes ágeis precisam adotar práticas de engenharia ágeis para realmente ter uma produtividade e qualidade acima dos padrões de mercado.

Shore acredita que, em parte, o problema desses acontecimentos tem a ver com o Scrum. Como o Scrum não possui práticas de engenharia em seu processo, isso levaria as pessoas a achar que TDD, Refactoring, Design emergente e outras não são importantes. Nesse ponto é que discordo com Shore. Como o próprio Ken Schwaber costuma dizer sobre Scrum: no início de sua adoção por uma empresa o que o Scrum fará é mostrar todos os problemas da sua equipe e da sua empresa. Scrum vai jogar toda a sujeira no ventilador e vai mostrá-la para todos os níveis hierárquicos. E isso é fundamental para entendermos o que queria Scwaber quando idealizou o Scrum. Talvez o problema é que isso seja pouco ou escassamente comentado por Scrum Trainers e por alguns consultores Scrum. É uma parte essencial do que prega o Scrum.

O Scrum força você a fazer entregas curtas de resultados em pequenos espaços de tempo. No início, isso levantará à tona dezenas ou centenas de problemas que a organização tem para alcançar essas metas curtas. E é a partir daí que as reuniões de retrospectiva no final de cada iteração e os próprios daily scrums mostram seu valor. Os problemas vão aparecer diariamente e a equipe, com o apoio da empresa, terá que atuar para resolvê-los. Nesse ponto é que um bom mentor de Agile deve entrar para ir aplicando, mentorizando e convencendo aos poucos sobre o uso de práticas técnicas de engenharia. Essa é a grande sacada do Scrum que talvez seja pouco esclarecida.

Seria ideal que as equipes já aderissem desde o início a um processo ágil recheado com práticas técnicas como o Extreme Programming, o Feature Driven Development ou ao OpenUP. O problema é que a maioria das pessoas aqui no Brasil já têm dificuldade de fazer e entender um simples planejamento iterativo, quanto mais desenvolver testes antes de código e refatorar continuamente seu trabalho.

Eu diria que o Scrum é apenas a porta de entrada para a agilidade. Uma equipe que não evoluir além disso, com certeza irá fracassar como o James Shore brilhantemente mostrou. Mas, ao mesmo tempo, adotar de cara um processo ágil mais completo também pode levar essas equipes a abandonar rapidamente suas tentativas, pois se eles não conseguirem usar acharão que agilidade não é para eles.

Portanto, para terminar falando de História novamente, vou parafrasear duas vezes Churchill para falar de Scrum:

- Scrum é a pior forma de metodologia, exceto por todas as outras que já foram tentadas de tempos em tempos...

- Não, Scrum não é o fim. Não é nem mesmo o começo do fim. Mas, provavelmente, é o fim do começo...

segunda-feira, novembro 17, 2008

Qualidade de software na prática com Behavior Driven Development e Acceptance Test Driven Development

Em um artigo anterior sobre qualidade interna e externa de software abordei a importância da testabilidade para a qualidade de um sistema. Reforçando a mensagem: quando você aumenta a testabilidade do software você diretamente melhora a sua arquitetura e o seu design. Desenvolver sem testes unitários automatizados e sem testes de aceitação é simplesmente já construir código legado desde o momento zero!

No artigo eu comentei sobre estratégias para melhorar a qualidade e a manutenibilidade, entrando brevemente no como fazer. Neste artigo vou falar mais do como fazer, tratando sobre técnicas de desenvolvimento de software modernas e ferramentas para apoiá-las: O Behavior driven development (desenvolvimento dirigido por comportamentos) e o Acceptance test driven development (desenvolvimento dirigido por testes de aceitação).

O behavior driven development foi inicalmente descrito por Dan North em seu artigo Introducing BDD. O BDD é similar ao Test Driven Development (TDD), mas é distinto em alguns pontos sutis, porém cruciais. Pelas convenções de TDD os métodos e classes de testes recebem nomes baseados nas classes de produção. BDD reorienta o foco para comportamentos do sistema. O BDD usa um template para se pensar no comportamento e nos testes do código:

Dado (Given) um contexto inicial

Quando (When) um evento ocorre

Então (Then) assegure alguns resultados.

O exemplo do artigo do Dan North é bem ilustrativo. Suponha a seguinte estória do usuário (user story):

Como um cliente, eu desejo sacar dinheiro da ATM, de modo que eu não precise gastar tempo na fila.

Como podemos saber quando essa estória está pronta (conceito de ‘done’)? Há vários cenários a se considerar. Alguns exemplos: conta tem crédito, a conta não tem mais limite de crédito. Usando o template acima o cenário 1 seria esse:

Cenário 1: Conta tem crédito

Dado que a conta possui crédito

E o cartão é válido

E a dispensadora contém dinheiro

Quando o cliente requisitar dinheiro

Então assegure que a conta seja debitada

E assegure que o dinheiro é dispensado

E assegura que o cartão é retornado.

O que isso muda em nossos testes unitários? Muda porque podemos usar uma ferramenta como o JBehave para desenvolver os testes no formato Dado / Quando / Então (Given / When / Then). O teste unitário fica voltado para os comportamentos e não mais para testar simplesmente métodos.

Porém, para equipes experientes e já acostumadas com TDD talvez essa mudança seja impactante. Para equipes novas seja mais complexo que um teste unitário simples. Por isso, a meu ver, o maior ganho do Behavior Driven Development está quando ele é unido com a técnica de Acceptance Test Driven Development (ATDD).

Segundo Koskela, em seu livro “Test Driven: Practical TDD and Acceptance TDD for Java Developers”, o TDD puro ajuda os desenvolvedores de software a produzir código de maior qualidade e manutenibilidade. O problema é que clientes raramente estão interessados em código. Eles querem sistemas que os tornem mais produtivos e gerem retornos sobre os investimentos. O ATDD ajuda a coordenar projetos de software de forma a entregar o que o cliente deseja.

Os testes de aceitação são especificações do comportamento e funcionalidade desejados para um sistema. Eles nos informam como, para uma determinada estória de usuário ou caso de uso, o sistema trata determinadas condições e entradas. Novamente conforme Koskela, um bom teste de aceitação deve ser:

- Propriedade dos clientes

- Escrito em conjunto com clientes, desenvolvedores e analistas de testes

- Sobre o O Que e não sobre o Como.

- Expresso na linguagem do domínio do problema

- Conciso, preciso e sem ambigüidades.

Até aqui fizemos uma descrição de um teste de aceitação que poderia simplesmente estar dentro de um documento Word ou planilha Excel. Então qual é a diferença do teste de aceitação tradicional para o teste de aceitação “clássico”? Primeiro é que no ATDD o teste deve ser automatizado. Esse é um ponto essencial para realizar testes regressivos contínuos. Em segundo lugar, os testes de aceitação são escritos ANTES da funcionalidade. Mas como? Seguindo os passos abaixo:

- Pegar uma estória ou fluxo de caso de uso

- Escrever os testes de aceitação na linguagem do domínio do cliente

- Automatizar os testes de aceitação

- Implementar funcionalidade.

É claro que ferramentas direcionadas para o ATDD ajudariam. Temos diversas open source no mercado como, por exemplo:

- Fitnesse

- Selenium

- Exactor

- TextTest

E por fim, a mais interessante e que vou comentar mais um pouco: Concordion.

O que você acharia se tivesse uma ferramenta que pudesse ler uma especificação de um caso de uso, de uma estória ou de um teste de aceitação escrito em linguagem comum e executasse esses passos em seu sistema automaticamente? Pois é, essa ferramenta existe, é open source e seu nome é Concordion. Ela é um framework que permite transformar uma descrição de requisitos em português em um teste automatizado, algo conhecido como especificação ativa. Portanto, uma especificação que se torna ainda mais útil porque a partir dela podemos executar testes automatizados!!!

Como ela funciona? Basicamente se escreve a especificação em um HTML simples, com comandos escondidos que definem o comportamento dos testes. A instrumentação dessa especificação é feita por uma classe Java que acompanha cada especificação e age como intermediário entre a especificação e o sistema sob teste.

Para alguns exemplos simples e interessantes basta estudar o tutorial do Concordion.


Outro ponto interessante do Concordion é que você pode exercer diretamente código da camada da aplicação ou de negócio ou então usar uma API que navega páginas Web. O site do Concordion recomenda o uso do WebDriver.


Por enquanto é só. Espero que tenha ajudado a esclarecer a importância do BDD e do ATDD para uma melhor qualidade e arquitetura de software. Não fiquem acanhados de tirar dúvidas ou colocar comentários. Basta escrevê-las aqui!


quinta-feira, novembro 13, 2008

CMMI e Agile: O Retorno

Já tratei sobre o assunto de CMMI e Agile em outro artigo, em que comentava minhas impressões sobre o tópico. Resumindo eu dizia que: Você pode fazer um processo ágil ficar aderente ao CMMI, porém terá um grande overhead (sobrecarga) de custo e prazo em cada um de seus projetos para conseguir isso. Escrevi isso baseado no excelente estudo do David Anderson sobre o tema, quando ele criou o MSF for CMMI.

Agora o SEI publicou um technical report sobre o assunto intitulado CMMI or Agile: Why not embrace both! E esse assunto deu o que falar nas comunidades e listas de discussão dos agilistas!

Uma das conclusões interessantes do relatório diz: "O Problema percebido entre Agile e CMMI não parte do Agile e CMMI serem inconsistentes inerentemente, mas de uma combinação de falsas percepções e experiências com algumas organizações que impõem processos padrões super pesados e restritivos em todos os projetos como parte do uso do CMMI".

É citado também o grandioso livro Peopleware de Tom DeMarco e Timothy Lister. Os autores afirmam que muitas organizações que passaram pelo CMMI acabaram se tornando avessas a riscos e conservadoras.

Mas, o objetivo final do relatório é tentar minimizar os conflitos entre os dois campos, reconhecer o valor de cada paradigma, eliminar erros e preconceitos mútuos.

O artigo também comenta um ponto que considero crucial. Em todas as discissões sobre o modelo CMMI é inevitável falar sobre a questão da avaliação (erroneamente chamada no mercado de certificação). O artigo reforça que é possível usar práticas alternativas para se atingir um objetivo do modelo. O problema é que vemos que mesmo os auditores oficiais treinados pelo SEI no SCAMPI(o guia de avaliação do CMMI) possuem dificuldade em aceitar ainda esses conceitos. Por ser um modelo, pode existir uma gama de interpretações diferentes no momento de uma validação via auditoria, especialmente devido à necessidade que o SCAMPI impõe em relação à existência de evidências diretas e indiretas da realização de práticas.

Do meu ponto de vista, o problemas não é o modelo CMMI em si, mas o SCAMPI e como é feita a avaliação. Quando se entra na busca do "selinho" é que ocorrem grande parte dos problemas, conforme já descrito no excelente livro "Measuring and Managing Performance in Organizations".

O método de avaliação SCAMPI tende a levar a uma busca frenética por evidências diretas e indiretas, já que os avaliadores oficiais do SEI possuem essa tendência (e sei disso por experiência própria, já que participei em SCAMPIs A e B). Se o SEI mudasse a forma como é feita a avaliação formal e como ela treina seus avaliadores (algo recomendado nesse novo technical report) talvez fosse útil uma organização agile tirar uma avaliação CMMI por motivos de negócio (entrar em licitações, etc). Agora, como está hoje definido o SCAMPI, se torna inevitavelmente necessário adaptar o processo ágil para que ele tenha chances de passar por uma avaliação. Pelo exemplo do próprio MSF for CMMI (discutido em meu artigo anterior) dá pra notar que é um overhead razoável para se adaptar e "passar" em um SCAMPI.

Acho que o primeiro passo concreto que o SEI poderia dar para se aproximar mais dos processos ágeis, seria adaptar o SCAMPI e definir melhor práticas alternativas no modelo CMMI.

Vamos ver o que o futuro reserva em relação a esse assunto!

quinta-feira, novembro 06, 2008

IBM Rational Team Concert 1.0.1 e versão para System z

Duas novidades saídas do forno na plataforma Jazz e na linha de produtos IBM Rational Team Concert.

A primeira é o lançamento da versão 1.0.1 do Rational Team Concert. Nós temos a tendência a achar que uma versão 1.0.1 é basicamente patch para correção de defeitos. Porém, o time do RTC desenvolveu nessa versão diversas funcionalidades e recursos novos como:

- Novos relatórios: estatísticas de Story points, Itens de trabalho fechados por iteração, atividade nos itens dia a dia.
- Licença flutuante para o RTC. Uma novidade interessante que pode ajudar a reduzir o investimento inicial necessário!
- Suporte ao banco de dados SQL Server.
- Melhorias no processo Scrum.
- Diagrama de fluxos do controle de versões.
- Suporte para localização de templates de processos (facilita a tradução).
- Outras estatísticas diversas.

A segunda novidade (e essa é para o pessoal da "velha guarda" do mainframe!!!) é o lançamento do Rational Team Concert for System z. Em dezembro, já teremos a primeira versão. Ela permitirá a instalação do servidor do RTC no System z. Mas a melhor notícia é que em 2009 o RTC para System z irá se integrar com a ferramenta Rational Developer for System z.

O Rational Developer for System z é uma ferramenta que permite que programadores COBOL, PL/I e EGL utilizem o Eclipse como plataforma de desenvolvimento de aplicações mainframe, trabalhando no mesmo ambiente líder de mercado dos programadores Java (o Eclipse). Essa ferramenta já se encontra disponível.

Qual o impacto então da integração do RTC com a ferramenta de desenvolvimento COBOL baseada no Eclipse? O impacto é que finalmente programadores mainframe podem usar as mesmas ferramentas e processos que programadores Java, .NET e etc. Isto é, controle de versões baseado em atividades, incidências e tarefas associadas com o código-fonte, integração contínua para COBOL, uso de processos ágeis como Scrum e OpenUP. Realmente uma revolução no processo de trabalho e uma melhoria de qualidade e produtividade para o mundo do mainframe! Programadores COBOL que costumavam reclamar que as ferramentas e soluções de ALM (Application Lifecycle Management) não funcionam muito bem para o mundo mainframe e COBOL (e que gostariam de ter algo assim), logo terão a oportunidade de se beneficiar desse lançamento.

Aguardem pelas notícias de lançamento e artigos mostrando o uso do RTC com o RDz para desenvolvimento COBOL!!!


Veja as Estatísticas