Pular para o conteúdo

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

Dext Unit Testing Header

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.

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 / ConceitoEcossistema .NETEquivalente no Dext TestingVantagem 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çõesfluent.Should().Be(...) (Fluent Assertions)Should(Value).Be(...)Sintaxe altamente fluente com encadeamento.
Mockingnew Mock<T>() (Moq)Mock<T>.CreateGerenciamento de ciclo de vida automático (Records em vez de Classes), eliminando vazamento de memória em testes.
Auto-MockingAutoMocker (Moq.AutoMocker)TAutoMockerInstanciaçã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 TestingSnapshooter / VerifyMatchSnapshotNativo, salvando automaticamente estruturas complexas como JSON em uma pasta de snapshots.
Cobertura de CódigoCoverlet / dotnet-coveragedext.exe --coverageNativo via CLI (relatórios HTML/XML) e em breve integrado diretamente à UI do Test Explorer na IDE.
IDE RunnerTest 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.

Vamos explorar detalhadamente como usar cada recurso do Dext com exemplos práticos de código.

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.
  • [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.
  • [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 teste N vezes 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.

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 / .AndAlso
Should(Name).StartWith('Jo').AndAlso.EndWith('ao').And.NotBe('John');
// Valores numéricos
Should(Count).BeGreaterThan(0);
Should(Value).BeInRange(1, 100);
// Asserções para GUID e UUID nativos do Dext
Should(RecordGuid).NotBeEmpty;
// Listas e Coleções
Should(UserList).HaveCountLessThan(10);
Should(UserList).Contain(AdminUser);
Should(UserList).BeEquivalentTo(ExpectedList); // Compara itens ignorando a ordem
// Tratamento de Exceções elegante
Should(procedure
begin
FService.CalculateDiscount(-10.0, False, ''); // Lança exceção se o valor for negativo
end).Throw<EArgumentOutOfRangeException>();

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');

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');

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;

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.

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;

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:

Terminal window
dext test --update-snapshots

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:

Terminal window
dext test --coverage

Essa 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).

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 := 0
else
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:”
  1. 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.
  2. 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.
  3. 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.

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 .res integrado 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.


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.

Dext Test Explorer
A interface do Dext Test Explorer integrada no RAD Studio.

  1. 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.
  2. Á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.
  3. 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).
  4. 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.
  5. 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.
  6. 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.
  7. Console Log Integrado: Aba dedicada para visualização direta do Stdout e logs gerados durante as execuções dos testes.
  8. 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.
  9. 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.
  10. 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.

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.

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.

Experimente o Dext Testing hoje mesmo e revolucione o fluxo de entrega da sua equipe!