DEV Community

Cover image for [pt-BR] Comece pelo teste
Enrique Marques Junior
Enrique Marques Junior

Posted on • Edited on

[pt-BR] Comece pelo teste

Linguagem: Dart


Em todas as profissões se testa, e isso tem total relação com o grau de qualidade que um produto pode ter para poder ser oferecido. Inclusive, em algumas áreas os testes são obrigatórios e a qualidade controlada por órgãos (ex: Inmetro).

Vamos entender em seguida como funcionam os testes de software e como os testes podem nos ajudar a praticar a linguagem e aumentar a qualidade da entrega.


Tipos de teste de software

Tipos de teste de software

Existem muitas categorias de teste, cada um com suas vantagens, desvantagens e objetivos. Vou abordar neste post os tipos de testes recomendados na documentação do Dart:

Os testes unitários tem a responsabilidade de garantir a integridade dos nossos métodos. Um teste unitário deve ser rápido e barato de executar.

Os testes de componentes são responsáveis pela parte de 'interfaces' e interações que um componente pode receber. Normalmente garante a exibição de elementos e mudanças de estados.

Os testes de integração testam a aplicação de uma visão mais completa, navegando e simulando comportamentos dos componentes em conjunto. Verifica o comportamento da aplicação e também pode ser utilizado para medir desempenho.


Testes

(ref: https://flutter.dev/docs/testing)


Seguindo esta ordem, considere o seguinte: maior quantidade de testes unitários, seguido por testes de componentes e de integração.

Entrega

Quando você entrega seu trabalho testado para os outros profissionais revisarem (ex: 'code review'), isso economiza muito tempo das pessoas e o seu.

Com testes sua entrega sobe de nível e evita retorno de tarefas para correções (bugs).

Sem testes, além de ficar preocupado (despreocupado é pior), você terá a necessidade de alcançar mais rápido seus objetivos para não ser atropelado por falhas e anomalias em códigos sem testes.


TDD

Para escrever o primeiro teste e entender a vantagem de se testar, vamos utilizar uma técnica chamada TDD (ou desenvolvimento orientado a testes). O TDD, em resumo, é guiar seu desenvolvimento através de testes (vale pesquisar mais sobre o assunto).

Para chegarmos no resultado esperado, seguindo TDD, precisamos passar por três etapas principais:

  • Escrever o teste e vê-lo falhar 🔴
  • Desenvolver o método e ver o teste passar 🟢
  • Melhorar o método com a garantia dos testes 🤓

Repeat!

Primeiro teste

Em uma aplicação Flutter a primeira coisa que eu penso em testar é a 'main'. Será que tem o que testar lá?

Tem sim! Podemos executar funções antes do 'bootstrap' do nosso aplicativo e isso pode ser testado.

Considere o seguinte: precisamos que uma função seja executada antes do runApp do Flutter. Poderíamos ter colocado direto na 'main', mas alguém poderia alterar ou remover essa função e ela deixaria de ter o comportamento esperado.

A vantagem de um teste desse é justamente dele falhar se alguém alterar o código ou remover por engano. Outra vantagem é a descrição dos testes, que ajudam novos colaboradores a entender os casos de uso do código na aplicação.


Para entender as etapas deste primeiro teste é legal dar uma lida na documentação do Dart e no pacote mockito:

O que será testado:

A ideia é testar a execução do runner da aplicação com a condição de executar uma função antes com as configurações de inicialização do projeto.

O teste:

Antes de começar a escrever o teste em si, precisamos criar as classes de Mock para que apenas o método run seja executado no teste.

Dentro do teste executamos o método run (é o método que estamos testando) e o verifyInOrder para verificar a execução na ordem correta.

Ficou assim:

// imports...
// bootstrap file import

class FunctionsMock extends Mock {
  void runApp(dynamic widget) {}
  void before() {}
}

class ComponentMock extends Mock {}

void main() {
  test('App bootstrap method', () async {
    final fMock = FunctionsMock();
    final appMock = ComponentMock();

    await Bootstrap(appMock, fMock.before).run(fMock.runApp);
    verifyInOrder([fMock.before(), fMock.runApp(appMock)]);
  });
}

Enter fullscreen mode Exit fullscreen mode

tests/bootstrap_test.dart


Chegou a hora de executar o teste e ver falhar:

$ flutter test
Enter fullscreen mode Exit fullscreen mode
00:04 +0 -1: loading test/bootstrap_test.dart [E]
  Failed to load "test/bootstrap_test.dart":
  Unable to spawn isolate: test/bootstrap_test.dart:17:11: Error: Method not found: 'Bootstrap'.
      await Bootstrap(appMock, fMock.before).run(fMock.runApp);
            ^^^^^^^^^^^^
00:04 +0 -1: Some tests failed.
Enter fullscreen mode Exit fullscreen mode

Escrevendo o método

Vamos criar uma classe Bootstrap que recebe um Widget e uma função before no construtor.

O método run recebe um runApp (do Flutter) e executa a função before antes do runner com a nossa app (Widget).

// imports...

class Bootstrap {
  final Widget app;
  final Function before;

  Bootstrap(this.app, this.before);

  Future<void> run(Function(Widget) runner) async {
    await before();
    await runner(app);
  }
}

Enter fullscreen mode Exit fullscreen mode

lib/bootstrap.dart


Utilizando a classe:

// imports...

void main() {
  Bootstrap(MyApp(), () { ... }).run(runApp);
}

// MyApp Widget Implementation
Enter fullscreen mode Exit fullscreen mode

lib/main.dart


Seguindo esta ordem, escrevendo o teste primeiro, podemos definir o que esperamos do método. Executando o teste esperamos sempre que ele falhe e está falha vai guiar o desenvolvimento do método. Faça o teste passar!

$ flutter test
Enter fullscreen mode Exit fullscreen mode
00:02 +1: All tests passed!
Enter fullscreen mode Exit fullscreen mode

Note que não testamos o método before, isso deverá ser feito em outra descrição de teste.

Agora sua implementação começa a ficar mais segura e em caso de mudanças seu teste vai quebrar para a felicidade de todos.

A ideia de aprender com os testes é que nos arquivos de testes vamos precisar lidar com a classe/método fora da sua aplicação e isso nos leva a melhorar essas classes/métodos, além de utilizar outras partes da linguagem.


É apenas o começo

No caso do Flutter você pode seguir para os testes de componentes (widgets). Para todos os casos, vale a leitura de toda documentação do Dart sobre testes.

Espero voltar com os próximos passos, mas não espere por mim, gogogo!

Top comments (0)