O Guia Definitivo de Testes Unitários com Dext: Qualidade, Abstração e a Revolução do Dext Test Explorer

A engenharia de software moderna exige confiabilidade. No entanto, por décadas, a escrita de testes em Delphi exigiu um esforço hercúleo de configuração interna. Embora a comunidade possua excelentes iniciativas inspiradas no .NET — que pavimentaram o caminho até aqui —, o desenvolvedor ainda precisava costurar manualmente diferentes bibliotecas de asserção, motores de mock e runners para obter um ambiente completo. Esse atrito de integração e a falta de uma experiência unificada em tempo de design acabavam afastando muitas equipes do hábito de testar.
O Dext Testing Framework foi desenvolvido especificamente para romper essa barreira. Inspirado nas melhores práticas e bibliotecas consolidadas do ecossistema .NET (como MSTest 2, NUnit, xUnit, Moq e Fluent Assertions), o Dext traz para o Delphi uma suíte de testes unificada, robusta, com um núcleo totalmente livre de dependências externas e com performance excepcional.
Neste guia completo, exploraremos a fundo os conceitos de design por trás do framework, detalharemos cada uma das suas features e apresentaremos o novo Expert para IDE Dext Test Explorer, a ferramenta visual definitiva para a produtividade do desenvolvedor no RAD Studio.
1. O Manifesto Dext: Qualidade, Isolamento e Abstração
Seção intitulada “1. O Manifesto Dext: Qualidade, Isolamento e Abstração”Escrever testes não se resume a verificar se 1 + 1 = 2. O verdadeiro teste unitário é uma ferramenta de design de software. Ele força o desenvolvedor a escrever código desacoplado e aderente aos princípios do SOLID.
O Paradigma do SUT (System Under Test) e Isolamento
Seção intitulada “O Paradigma do SUT (System Under Test) e Isolamento”Em um teste unitário puro, testamos uma única classe (o SUT - System Under Test) de forma totalmente isolada. Qualquer dependência externa (banco de dados, chamadas de rede ou serviços) deve ser isolada utilizando Mocks, Stubs ou Fakes.
- Isolamento Garantido: Se o teste falhar, você sabe exatamente qual unidade de código falhou. Não há falsos negativos causados por rede instável ou registros ausentes no banco de dados.
- Abstração e Flexibilidade de Acoplamento: Para permitir o isolamento, o SUT idealmente deve consumir abstrações (interfaces). O Dext torna o mocking dessas interfaces tão natural quanto declarar uma variável. No entanto, ciente de que sistemas legados ou arquiteturas existentes nem sempre podem ser refatorados para interfaces imediatamente, o Dext Testing vai além e oferece suporte nativo a mocks de classes concretas (sobrepondo métodos virtuais). Isso garante flexibilidade total para isolar dependências mesmo sob estruturas de acoplamento mais rígidas.
2. A Ponte para o .NET: Uma Stack Consolidada
Seção intitulada “2. A Ponte para o .NET: Uma Stack Consolidada”No ecossistema .NET, os desenvolvedores usam uma combinação de bibliotecas para obter uma experiência completa de testes:
- xUnit / NUnit: Para o runner de testes e estruturação de fixtures.
- Moq / NSubstitute: Para mockar dependências e verificar chamadas.
- Fluent Assertions: Para asserções legíveis e expressivas.
No Delphi clássico, obter esse resultado exigiria instalar o DUnitX, integrar o Delphi-Mocks e buscar bibliotecas de asserções fluentes de terceiros — o que frequentemente gera conflitos de compatibilidade, acoplamento de dependências pesadas e uma experiência de desenvolvimento inconsistente.
O Dext Testing unifica toda essa stack de forma nativa. Ao consolidar o equivalente a múltiplos frameworks distintos do ecossistema .NET (como runners, bibliotecas de mock, asserções fluentes e motores de snapshot) em uma única solução coesa, eliminamos completamente o atrito clássico de tentar integrar pacotes de diferentes autores.
Todas as funcionalidades do Dext Testing foram projetadas desde o primeiro dia para trabalhar em perfeita harmonia e de forma totalmente integrada. Isso significa que a declaração do teste com atributos, a criação do mock, as asserções com Should e a exportação de relatórios compartilham a mesma infraestrutura interna e convenções. Não há necessidade de adaptadores (adapters), soluções de contorno ou configurações complexas. Essa sinergia nativa simplifica a curva de aprendizado, garante máxima eficiência em tempo de execução e otimização de compilação, além de permitir uma evolução natural e integrada de toda a suíte de testes.
Veja como os recursos do Dext se comparam aos gigantes do .NET:
| Recurso / Conceito | Ecossistema .NET | Equivalente no Dext Testing | Vantagem Dext |
|---|---|---|---|
| Definição de Fixtures | [TestClass] (MSTest) / [TestFixture] (NUnit) | [TestClass], [TestFixture] | Permite criar classes de teste PODO puras, eliminando a obrigatoriedade de herança (como o clássico TTestCase do DUnit). |
| Asserções | fluent.Should().Be(...) (Fluent Assertions) | Should(Value).Be(...) | Sintaxe altamente fluente com encadeamento. |
| Mocking | new Mock<T>() (Moq) | Mock<T>.Create | Gerenciamento de ciclo de vida automático (Records em vez de Classes), eliminando vazamento de memória em testes. |
| Auto-Mocking | AutoMocker (Moq.AutoMocker) | TAutoMocker | Instanciação automática do SUT resolvendo construtores com Mocks pré-configurados. |
| Data-Driven Tests | [Theory] (xUnit) / [TestCase] (NUnit) | [Test], [TestCase], [TestCaseSource] | Testes parametrizados nativos que suportam fuzzing com [Random], [Range] e [Values]. |
| Snapshot Testing | Snapshooter / Verify | MatchSnapshot | Nativo, salvando automaticamente estruturas complexas como JSON em uma pasta de snapshots. |
| Cobertura de Código | Coverlet / dotnet-coverage | dext.exe --coverage | Nativo via CLI (relatórios HTML/XML) e em breve integrado diretamente à UI do Test Explorer na IDE. |
| IDE Runner | Test Explorer (Visual Studio) | Dext Test Explorer (RAD Studio Expert) | Integração perfeita com RAD Studio, oferecendo árvore interativa, agrupamentos, inspector de erros e exportações. |
3. Guia de Referência Técnica de Features
Seção intitulada “3. Guia de Referência Técnica de Features”Vamos explorar detalhadamente como usar cada recurso do Dext com exemplos práticos de código.
3.1. RTTI-Based Runner (PODO Test Fixtures)
Seção intitulada “3.1. RTTI-Based Runner (PODO Test Fixtures)”Diga adeus à necessidade de herdar suas classes de teste de TTestCase ou TDephiTestCase. No Dext, qualquer classe Delphi comum (PODO - Plain Old Delphi Object) pode conter testes, desde que devidamente decorada com atributos.
unit Dext.Core.UnitTests;
interface
uses Dext.Testing;
type [TestFixture] [Category('Business')] TDiscountServiceTests = class private FService: IDiscountService; public [Setup] procedure Setup;
[TearDown] procedure Cleanup;
[Test] [Description('Valida se cliente padrão sem cupom não recebe desconto')] procedure TestNoDiscountForStandardUser;
[Test] // Parâmetros: Subtotal, IsVip, Cupom, DescontoEsperado [TestCase(100.0, False, '', 0.0)] [TestCase(100.0, True, '', 10.0)] [TestCase(200.0, False, 'BLACKFRIDAY', 30.0)] procedure TestDiscountRules(const Subtotal: Double; const IsVip: Boolean; const Coupon: string; const ExpectedDiscount: Double); end;
implementation
procedure TDiscountServiceTests.Setup;begin FService := TDiscountService.Create;end;
procedure TDiscountServiceTests.Cleanup;begin FService := nil;end;
procedure TDiscountServiceTests.TestNoDiscountForStandardUser;begin var Discount := FService.CalculateDiscount(50.0, False, ''); Should(Discount).Be(0.0);end;
procedure TDiscountServiceTests.TestDiscountRules(const Subtotal: Double; const IsVip: Boolean; const Coupon: string; const ExpectedDiscount: Double);begin var Discount := FService.CalculateDiscount(Subtotal, IsVip, Coupon); Should(Discount).Be(ExpectedDiscount);end;
end.Atributos de Ciclo de Vida do Runner:
Seção intitulada “Atributos de Ciclo de Vida do Runner:”[Setup]: Executado antes de cada teste da classe.[TearDown]: Executado após cada teste da classe.[BeforeAll]/[ClassInitialize]: Executado uma única vez antes de qualquer teste da classe rodar.[AfterAll]/[ClassCleanup]: Executado uma única vez após todos os testes da classe finalizarem.[AssemblyInitialize]: Executado uma vez na inicialização do Runner de testes.[AssemblyCleanup]: Executado uma vez no encerramento do Runner.
Controle de Execução e Resiliência:
Seção intitulada “Controle de Execução e Resiliência:”[Ignore('Motivo')]: Pula o teste fornecendo uma explicação que aparece nos relatórios e na IDE.[Timeout(Milliseconds)]: Cancela e falha o teste se a execução exceder o tempo limite especificado.[Repeat(N)]: Executa o testeNvezes consecutivas. Excelente para detectar flaky tests (testes instáveis) e condições de corrida (race conditions).[MaxTime(Milliseconds)]: O teste passa se a lógica estiver correta, mas gera um aviso nos relatórios se demorar mais do que o limite permitido (útil para detectar regressões de performance).[Explicit]: O teste só roda se for explicitamente selecionado pelo usuário (útil para testes de integração lentos).[Platform('Win64')]: Limita a execução do teste a arquiteturas específicas.
3.2. Fluent Assertions (Should Syntax)
Seção intitulada “3.2. Fluent Assertions (Should Syntax)”As asserções fluentes do Dext aumentam significativamente a legibilidade dos testes. A estrutura do código se assemelha a uma frase em inglês, facilitando a revisão de código.
// Encadeamento fluente com .And / .AndAlsoShould(Name).StartWith('Jo').AndAlso.EndWith('ao').And.NotBe('John');
// Valores numéricosShould(Count).BeGreaterThan(0);Should(Value).BeInRange(1, 100);
// Asserções para GUID e UUID nativos do DextShould(RecordGuid).NotBeEmpty;
// Listas e ColeçõesShould(UserList).HaveCountLessThan(10);Should(UserList).Contain(AdminUser);Should(UserList).BeEquivalentTo(ExpectedList); // Compara itens ignorando a ordem
// Tratamento de Exceções eleganteShould(procedure begin FService.CalculateDiscount(-10.0, False, ''); // Lança exceção se o valor for negativo end).Throw<EArgumentOutOfRangeException>();Soft Assertions (Assert.Multiple)
Seção intitulada “Soft Assertions (Assert.Multiple)”Por padrão, um erro em uma asserção interrompe a execução do teste imediatamente. Com o Assert.Multiple, você pode agrupar várias asserções. O Runner executará todas elas e reportará detalhadamente quais falharam no final do bloco.
Assert.Multiple(procedure begin Should(User.Name).Be('Maria'); Should(User.Age).Be(28); Should(User.Email).Contain('@company.com'); end);Property Accessors (WhichString, WhichInteger, etc.)
Seção intitulada “Property Accessors (WhichString, WhichInteger, etc.)”Permite acessar propriedades de sub-objetos de forma segura e fluente sem precisar quebrar a cadeia de asserções:
Should(Order) .NotBeNil .HaveProperty('Customer').WhichObject .HaveProperty('Name').WhichString .StartWith('Enterprise');Smart Entities (Evitando Strings Mágicas)
Seção intitulada “Smart Entities (Evitando Strings Mágicas)”Para evitar o uso de strings mágicas ao testar propriedades de objetos, o Dext fornece Prototype.Entity<T> para extrair metadados fortemente tipados das propriedades:
var u := Prototype.Entity<TUser>;Should(CurrentUser).HaveValue(u.Email, 'suporte@dext.dev');3.3. O Poderoso Mocking Engine
Seção intitulada “3.3. O Poderoso Mocking Engine”Diferente do .NET, o Delphi não possui árvores de expressão (Expression Trees) nativas. Para resolver isso com elegância e tipagem forte, o Dext implementa uma arquitetura baseada em Proxy-Recording (Setup...When.MethodCall).
[!IMPORTANT] O
Mock<T>do Dext é implementado como um Record Genérico. Isso significa que ele vive no escopo da pilha e não requer liberação manual (.Free). A instância da interface mockada é destruída automaticamente de acordo com as regras de contagem de referência do Delphi.
💡 O Ciclo de Vida Gerenciado do Mock
Frameworks de teste tradicionais costumam exigir atenção redobrada no gerenciamento de memória das instâncias de mock. O Dext resolve essa dor ao implementar o Mock
utilizando Managed Records e contagem de referência nativa. O Mock nasce e morre respeitando o escopo do método de teste alocado na stack, eliminando a necessidade de blocos try..finally manuais apenas para liberar a infraestrutura de testes. É a sofisticação da engenharia Object Pascal moderno trabalhando para deixar o código limpo.
uses Dext.Mocks;
type {$M+} // Obrigatório para habilitar RTTI estendida na interface IPaymentService = interface ['{8F4E6B20-562F-4DFA-A39B-C53805D7AAEC}'] function ProcessPayment(const CardNum: string; const Amount: Double): Boolean; function GetTransactionCount: Integer; end; {$M-}
procedure TOrderTests.TestOrderPayment;begin // 1. Criação do Mock var MockPayment := Mock<IPaymentService>.Create;
// 2. Setup do comportamento (Retorna true para qualquer número de cartão e valor) MockPayment.Setup .Returns(True) .When .ProcessPayment(Arg.Any<string>, Arg.Any<Double>);
// 3. Setup de sequência (retorna valores diferentes a cada chamada subsequente) MockPayment.Setup .ReturnsInSequence([1, 2, 3]) .When .GetTransactionCount;
// 4. Executando o SUT com o mock injetado (.Instance fornece a interface física) var OrderProcessor := TOrderProcessor.Create(MockPayment.Instance); try var Success := OrderProcessor.Checkout('1234-5678', 150.00);
// Asserção Should(Success).BeTrue; finally OrderProcessor.Free; end;
// 5. Verificação de chamadas (Asserts comportamentais) MockPayment.Received(Times.Once).ProcessPayment('1234-5678', 150.00); MockPayment.DidNotReceive.ProcessPayment(Arg.Is<string>(function(S: string): Boolean begin Result := S.StartsWith('0000'); // Garante que nenhum cartão inválido foi enviado end), Arg.Any<Double>);
// Garante que não houve chamadas inesperadas além das verificadas MockPayment.VerifyNoOtherCalls;end;Mocking de Classes (Classes Parciais/Spies)
Seção intitulada “Mocking de Classes (Classes Parciais/Spies)”O Dext também permite mockar métodos virtuais de classes concretas e configurar comportamento parcial (redirecionar chamadas não configuradas para a classe base):
var MockRepo := Mock<TUserRepository>.Create;MockRepo.CallsBaseForUnconfiguredMembers := True; // Comportamento de Spy
MockRepo.Setup.Returns(MockedUser).When.FindById(99);// FindById(99) retorna MockedUser. Outros IDs invocarão a lógica real de TUserRepository.3.4. Auto-Mocking Container (TAutoMocker)
Seção intitulada “3.4. Auto-Mocking Container (TAutoMocker)”Gerenciar dependências manualmente em testes complexos pode gerar uma quantidade massiva de código de inicialização (boilerplate). O TAutoMocker automatiza isso inspecionando os construtores da classe sob teste, criando os mocks necessários e injetando-os automaticamente.
procedure TUserTests.TestUserRegistration;begin var Mocker := TAutoMocker.Create;
// O AutoMocker cria o mock de IUserRepository e IEmailService silenciosamente // e injeta nos parâmetros do construtor de TUserService var UserService := Mocker.CreateInstance<TUserService>; try // Podemos obter o mock criado e configurar comportamento Mocker.GetMock<IUserRepository>.Setup .Returns(True) .When .Save(Arg.Any<TUser>);
UserService.Register('John Doe', 'john@dext.dev');
// Verifica se o e-mail de boas-vindas foi enviado Mocker.GetMock<IEmailService>.Received(Times.Once).SendWelcomeEmail('john@dext.dev'); finally UserService.Free; Mocker.Free; end;end;3.5. Snapshot Testing (MatchSnapshot)
Seção intitulada “3.5. Snapshot Testing (MatchSnapshot)”Ao testar respostas complexas (como payloads JSON grandes gerados por um serviço de serialização), asserções manuais podem se tornar impraticáveis. O Snapshot Testing salva o estado completo do objeto em um arquivo JSON de referência e valida execuções futuras contra ele.
[Test]procedure TestComplexReportGeneration;begin var Report := FReportService.Generate(2026, 'Vendas');
Report.MatchSnapshot(procedure(Options: TSnapshotOptions) begin // Ignora campos gerados dinamicamente como carimbos de data/hora ou IDs aleatórios Options.IgnorePaths([ '$.Metadata.GeneratedAt', '$.Metadata.TraceId' ]); end);end;Para atualizar os arquivos de referência quando uma mudança de comportamento for intencional, basta rodar o runner via CLI:
dext test --update-snapshots3.6. Cobertura de Código (Code Coverage)
Seção intitulada “3.6. Cobertura de Código (Code Coverage)”De que serve ter milhares de testes se eles cobrem apenas uma fração insignificante do sistema? A Cobertura de Código (Code Coverage) é a métrica que indica quais linhas de código do seu produto foram executadas durante a rodada de testes unitários.
Hoje, o Dext fornece suporte nativo a cobertura de código através de seu utilitário de CLI, o dext.exe.
Ao executar no terminal:
dext test --coverageEssa funcionalidade é viabilizada através da integração transparente do Dext com a ferramenta de código aberto da comunidade Delphi Code Coverage (https://github.com/DelphiCodeCoverage/DelphiCodeCoverage). O utilitário dext.exe automatiza todo o processo, inclusive oferecendo a opção de baixar a última release diretamente do repositório oficial da ferramenta caso ela não esteja presente na máquina.
O Dext coordena a execução da ferramenta e consolida a geração de relatórios de cobertura detalhados, exportáveis em formatos como HTML e XML (totalmente compatíveis com o SonarQube para compor os Quality Gates da pipeline).
🚀 Próximo Passo: Cobertura Integrada à IDE
Seção intitulada “🚀 Próximo Passo: Cobertura Integrada à IDE”Para elevar ainda mais a experiência em tempo de design (Design-Time DX), estamos integrando a Cobertura de Código diretamente à interface visual do Dext Test Explorer no RAD Studio.
Com essa integração, os desenvolvedores poderão rodar a análise de cobertura com um clique e visualizar o percentual de cobertura das classes diretamente na árvore de testes e o destaque colorido das linhas executadas e não executadas no próprio editor de código da IDE, eliminando a necessidade de exportações manuais ou checagens externas durante o desenvolvimento.
3.7. O Ecossistema de Integração Contínua (CI/CD) e Quality Gates
Seção intitulada “3.7. O Ecossistema de Integração Contínua (CI/CD) e Quality Gates”No desenvolvimento de software moderno, a qualidade não é delegada apenas ao final do ciclo de desenvolvimento. Ela é validada de forma contínua a cada commit. É aqui que entra o conceito de Quality Gates (Portões de Qualidade).
O que é um Quality Gate e por que ele salva negócios?
Seção intitulada “O que é um Quality Gate e por que ele salva negócios?”Um Quality Gate é um conjunto de condições e métricas automatizadas que um trecho de código deve satisfazer antes de ser integrado ao branch principal ou promovido para produção. Ele avalia:
- Execução bem-sucedida de 100% dos testes unitários e de integração.
- Cobertura mínima de código testado (ex: 80%).
- Ausência de vulnerabilidades de segurança e bugs críticos detectados por análise estática.
O Custo do Bug em Produção:
Segundo a clássica regra da Engenharia de Software, um bug encontrado durante a fase de codificação custa 1x. Se ele passar para a fase de testes manuais/QA, custa 10x. Se ele chegar a produção, o custo salta para 100x ou mais. Em sistemas ERP de missão crítica escritos em Delphi (que gerenciam faturamento, emissão fiscal, contabilidade e estoques), um bug crítico em produção pode paralisar as operações de centenas de clientes corporativos, acarretando em multas contratuais, perdas financeiras massivas e danos irreparáveis à reputação da software house.
Como o Dext habilita a Cultura de Qualidade em Delphi
Seção intitulada “Como o Dext habilita a Cultura de Qualidade em Delphi”Tradicionalmente, a comunidade Delphi enfrentava dificuldades para integrar testes de projetos legados a ferramentas de CI/CD por falta de formatos de relatórios compatíveis com os analisadores de mercado.
O Dext resolve isso de forma nativa ao atuar como um gerador de relatórios multiformato. Com a Fluent API do Dext, você configura exportadores que gravam os resultados dos testes nos padrões exigidos pelas principais ferramentas de DevSecOps do mercado:
if TTest.Configure .Verbose .RegisterFixtures([TDiscountServiceTests, TUsuarioServiceTests]) .ExportToJUnit('results-junit.xml') // Padrão do GitHub Actions, Jenkins e GitLab CI .ExportToXUnit('results-xunit.xml') // Padrão do ecossistema .NET .ExportToTRX('results.trx') // Formato nativo para integração perfeita com Azure DevOps .ExportToJson('report.json') // Útil para scripts de auditoria customizados .ExportToSonarQube('sonar-generic.xml') // Integração direta com os Quality Gates do SonarQube .ExportToHtml('dashboard.html') // Relatório estático autocontido com gráficos estatísticos .Run then ExitCode := 0else ExitCode := 1;Outros Recursos e Integração Prática com Ferramentas do Mercado:
Seção intitulada “Outros Recursos e Integração Prática com Ferramentas do Mercado:”- SonarQube: Ao gerar o arquivo
sonar-generic.xml, o scanner do SonarQube lê os resultados de sucesso, falha e skips do Dext, integrando esses dados diretamente nas regras de bloqueio do Pull Request na plataforma de Code Review. - Azure DevOps: O formato
.trxé o padrão oficial do ecossistema da Microsoft. Ao utilizá-lo, o painel do Azure Pipelines renderiza gráficos nativos ricos de progresso de testes, tempo gasto e histórico de estabilidade dos builds automaticamente. - GitHub Actions / GitLab CI / Jenkins: Utilizando o formato JUnit XML clássico, qualquer runner de build detecta as falhas no terminal, impede o deploy automático de código quebrado e envia alertas imediatos para a equipe.
3.8. Live Dashboard (Roadmap de Evolução)
Seção intitulada “3.8. Live Dashboard (Roadmap de Evolução)”O Dext Testing traz o suporte a um Live Dashboard baseado em um servidor HTTP embarcado e Server-Sent Events (SSE) para prover uma visualização rica e uma timeline em tempo real da execução dos testes.
[!NOTE] Status do Live Dashboard e Próximos Passos:
A versão inicial do dashboard está disponível, mas foi temporariamente comentada e desativada nas configurações padrão do instalador (TMS Smart Setup) para evitar conflitos de recursos compilation-time (vinculados ao arquivo.resintegrado a units compiladas em múltiplos projetos). Estamos trabalhando em uma nova versão que resolverá definitivamente essas limitações de empacotamento de recursos e adicionará recursos ainda mais avançados de telemetria de testes.
4. A Revolução do Dext Test Explorer
Seção intitulada “4. A Revolução do Dext Test Explorer”A maior novidade da última versão do Dext é o Dext Test Explorer, um Expert (plugin) nativo de alto nível integrado diretamente ao RAD Studio. Ele traz a experiência visual fluida do Test Explorer do Visual Studio diretamente para o ambiente Delphi, substituindo implementações clássicas por uma UI rica e moderna.

A interface do Dext Test Explorer integrada no RAD Studio.
Principais Funcionalidades do Test Explorer:
Seção intitulada “Principais Funcionalidades do Test Explorer:”- Suporte a Múltiplos Projetos de Teste (Project Group): O Dext Test Explorer permite gerenciar múltiplos projetos de testes unitários dentro do mesmo Grupo de Projetos (
.groupproj) carregado na IDE. O desenvolvedor seleciona qual projeto de testes deseja focar através de um combobox intuitivo no topo da interface. Isso permite trabalhar de forma isolada e modularizada. Em bases de código grandes (com centenas ou milhares de testes), evita-se a lentidão de recompilar e linkar um executável gigante a cada alteração, permitindo compilar e rodar apenas o projeto selecionado, reduzindo drasticamente o tempo de feedback. - Árvore de Testes Dinâmica com Parser Ultra-Rápido: Inspeciona o projeto de teste selecionado ativo, descobrindo automaticamente as Fixtures e Testes através de RTTI. O parser interno de carga foi extensivamente otimizado para performance instantânea: mesmo em projetos complexos com mais de 1000 casos de teste, o carregamento e mapeamento na árvore ocorrem de forma praticamente imediata na IDE. Em nossos benchmarks práticos (visíveis na interface real da IDE reproduzida abaixo), o motor do Dext executou uma suíte de 61 testes unitários complexos de serialização em menos de 1 segundo de tempo computacional puro (exatos 0,73s). A barra de status exibe também, com total transparência, o tempo total de ciclo (10,06s), que engloba o roundtrip completo da IDE: compilação, linkagem e a carga do processo. Ter esse nível de feedback visual sem precisar sair do editor de texto é o que mantém o desenvolvedor focado e produtivo. Permite filtrar e buscar testes em tempo real à medida que você digita.
- Modos de Agrupamento Flexíveis:
- Group by Code Structure: Organiza os testes seguindo a estrutura lógica de Units e Classes/Fixtures.
- Group by Test Status: Agrupa por Passed, Failed, Skipped e Idle (não executados).
- Layouts Customizáveis:
- Tabbed Layout: Permite organizar a interface em abas limpas.
- Split Layouts (Bottom/Right): Divide a tela para exibir os logs de console e a árvore de testes lado a lado com o editor de código.
- Aba Test Inspector: Exibe informações detalhadas do teste selecionado, incluindo nome completo, status de execução, duração precisa e a localização física exata (unit e linha). Um duplo clique no teste leva o cursor diretamente para o código correspondente no editor do RAD Studio.
- Aba de Configurações e Automação: Painel dedicado para personalizar a experiência de execução de testes:
- Custom Command Line Parameters: Permite passar parâmetros de linha de comando customizados para o runner dos testes (como filtros avançados
--filter mytest*ou modo--verbose). - Run tests automatically on Save: Roda a suíte de testes automaticamente sempre que um arquivo do projeto é salvo na IDE.
- Run tests automatically on Idle: Executa os testes de forma assíncrona quando a IDE detecta inatividade do desenvolvedor (Continuous Testing).
- Enable Dext Test Explorer: Chave global para habilitar ou desabilitar a integração ativa do plugin de forma rápida.
- Custom Command Line Parameters: Permite passar parâmetros de linha de comando customizados para o runner dos testes (como filtros avançados
- Console Log Integrado: Aba dedicada para visualização direta do
Stdoute logs gerados durante as execuções dos testes. - Barra de Status Analítica: Estatísticas agregadas na parte inferior exibindo: Total, Selecionados, Passed, Failed, Skipped, Tempo de Execução dos testes e Tempo de Execução Global.
- Menu Visual de Exportação de Relatórios (
...):- Exportação instantânea com um clique para JUnit XML, xUnit XML, JSON, SonarQube XML e HTML Report.
- Cobertura de Código Integrada (Em Breve): Execução de análise de Code Coverage com um clique diretamente pelo Test Explorer, fornecendo relatórios visuais de percentual de cobertura e coloração de linhas executadas diretamente no editor de código da IDE.
4.1. Suporte Legado e Ecossistemas da Comunidade: DUnit, DUnit2 e DUnitX
Seção intitulada “4.1. Suporte Legado e Ecossistemas da Comunidade: DUnit, DUnit2 e DUnitX”Sabemos que migrar toda a base de testes de um sistema corporativo de uma vez para uma nova suíte é inviável. Ciente disso, o Dext Test Explorer nasceu preparado para respeitar e valorizar o ecossistema existente da comunidade Delphi.
O Expert traz suporte nativo inicial para executar testes legados e modernos escritos em:
- DUnit: O pioneiro e clássico framework baseado em JUnit.
- DUnit2: A evolução focada em melhorias estruturais do clássico DUnit.
- DUnitX: O framework de testes moderno mais adotado hoje, inspirado em conceitos do .NET.
Ao mapear a árvore de testes do seu Projeto ou Grupo de Projetos, o Dext Test Explorer descobre e executa perfeitamente essas suítes clássicas de forma transparente e assíncrona, exibindo os resultados no mesmo painel visual unificado. Nos colocamos totalmente à disposição de qualquer pessoa que queira experimentar e usar essas integrações em seus projetos; se encontrar algum problema, dificuldade ou comportamento inesperado, por favor nos avise para que possamos ajudar e evoluir a ferramenta juntos.
Homologado na Prática com Projetos Open Source
Seção intitulada “Homologado na Prática com Projetos Open Source”Para comprovar o poder e a maturidade da integração do Dext Test Explorer com ferramentas da comunidade, realizamos a execução e homologação completa de suítes de testes unitários de grandes projetos open source do ecossistema Delphi.
Os testes dessas suítes, rodando sob a estrutura do DUnitX, foram carregados e executados pelo Dext Test Explorer de forma direta, sem qualquer necessidade de adaptações ou de ferramentas intermediárias. O resultado foi um feedback visual instantâneo dos testes passando em tempo de design — demonstrando que o Dext não quer isolar o desenvolvedor, mas sim unir o ecossistema clássico a uma experiência visual moderna e profissional.
5. O Próximo Horizonte: Uma Visão para a Evolução da RTL e da IDE
Seção intitulada “5. O Próximo Horizonte: Uma Visão para a Evolução da RTL e da IDE”Mais do que entregar uma suíte pronta, o desenvolvimento do Dext Testing nos trouxe uma clareza profunda sobre o futuro do ecossistema Object Pascal. Para que a cultura de qualidade se torne o padrão absoluto na indústria Delphi, precisamos discutir como a testabilidade pode ser integrada de forma nativa e plugável no coração da plataforma.
A engenharia moderna ganharia uma tração sem precedentes se as ferramentas oficiais da RTL e do RAD Studio nascessem preparadas para o isolamento de código. Imagine o impacto de termos:
- Abstrações Testáveis Nativas: Mocks e stubs simplificados e plugáveis para componentes críticos como FireDAC, WebBroker, DataSnap e as novas engines de WebStencils. Testar uma regra de negócio que interage com uma requisição web ou uma transação de banco de dados não deveria exigir que o desenvolvedor crie pesadas camadas de contorno.
- Interfaces de I/O Desacopladas: Primitivas de leitura e escrita de arquivos e comunicação de rede que suportem injeção de dependência nativa na RTL, facilitando o isolamento do SUT (System Under Test).
- Uma Open Tools API (OTA) Focada em Continuous Testing: A infraestrutura de extensibilidade da IDE poderia evoluir para permitir que Experts executem suítes de teste de forma totalmente assíncrona e em background, marcando falhas ou linhas não cobertas de maneira suave e visual diretamente no gutter (a margem lateral) do editor de código. O desenvolvedor saberia que quebrou um teste no exato segundo em que salva o arquivo, sem que o foco da digitação ou a interface do RAD Studio sofram qualquer interrupção.
O Dext Testing prova que a linguagem está pronta para esse nível de sofisticação. O próximo passo lógico é unirmos forças como comunidade e plataforma para tornar esse fluxo de design a regra, e não a exceção.
6. Conclusão: Por que o Dext Leva o Delphi Além?
Seção intitulada “6. Conclusão: Por que o Dext Leva o Delphi Além?”Ao unificar conceitos avançados e oferecer uma ferramenta integrada de ponta como o Dext Test Explorer, o Dext demonstra que o Delphi é perfeitamente capaz de rodar testes unitários e de integração com a mesma facilidade, expressividade e velocidade de stacks como .NET, Java, Rust ou Node.js.
Escrever testes robustos usando abstração, isolamento e mocking estruturado não apenas protege o software contra bugs em produção, mas redefine a qualidade e a arquitetura geral dos projetos legados e novos no ecossistema Delphi.
Participe e Contribua!
Seção intitulada “Participe e Contribua!”O Dext Test Explorer já está sendo utilizado ativamente no dia a dia. Contudo, por ser uma ferramenta em constante evolução, ela pode conter bugs ou instabilidades temporárias. Se você encontrar qualquer problema, por favor reporte-o abrindo uma issue, e caso tenha sugestões de melhoria, sinta-se à vontade para enviar sua requisição.
- Repositório Oficial: GitHub - cesarliws/dext
- Documentação de Testes (PT-BR): Guia de Testes (PT)
- Documentação de Testes (EN): Testing Guide (EN)
- Instalação do Dext: Guia de Instalação
Experimente o Dext Testing hoje mesmo e revolucione o fluxo de entrega da sua equipe!