<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcus Tenório</title>
    <description>The latest articles on DEV Community by Marcus Tenório (@mvtenorio).</description>
    <link>https://dev.to/mvtenorio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F251155%2F97f77220-3031-477a-b5a5-18807fa1afcb.jpeg</url>
      <title>DEV Community: Marcus Tenório</title>
      <link>https://dev.to/mvtenorio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mvtenorio"/>
    <language>en</language>
    <item>
      <title>[PT-BR] Utilizando fixtures do pytest para melhorar seus testes</title>
      <dc:creator>Marcus Tenório</dc:creator>
      <pubDate>Thu, 03 Jun 2021 22:27:49 +0000</pubDate>
      <link>https://dev.to/mvtenorio/pt-br-utilizando-fixtures-do-pytest-para-melhorar-seus-testes-4fp</link>
      <guid>https://dev.to/mvtenorio/pt-br-utilizando-fixtures-do-pytest-para-melhorar-seus-testes-4fp</guid>
      <description>&lt;p&gt;Quando desenvolvemos testes, é comum precisarmos de preparar algum cenário antes de fazermos o &lt;em&gt;assert&lt;/em&gt;. Isso pode ser feito de diversas maneiras, e as &lt;em&gt;fixtures&lt;/em&gt; do &lt;em&gt;pytest&lt;/em&gt; são uma das melhores soluções para esse problema. Para demonstrar como utilizar e quais vantagens as fixtures nos proporcionam, é importante definir as etapas de um teste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;preparação (&lt;em&gt;setup&lt;/em&gt;)&lt;/strong&gt;: nesta etapa, criamos todas as pré condições para executarmos nosso teste. As fixtures do pytest auxiliam aqui. Nos tradicionais &lt;em&gt;frameworks&lt;/em&gt; de teste da família &lt;a href="https://en.wikipedia.org/wiki/XUnit"&gt;&lt;em&gt;xUnit&lt;/em&gt;&lt;/a&gt; (incluindo &lt;em&gt;unittest&lt;/em&gt;) isso é geralmente feito no método &lt;code&gt;setUp()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ação (&lt;em&gt;act&lt;/em&gt;)&lt;/strong&gt;: execução de um método ou função que queremos testar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;verificação (&lt;em&gt;assert&lt;/em&gt;)&lt;/strong&gt;: aqui é, de fato, onde o teste ocorre. Verificamos se o resultado da ação é o que queríamos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;finalização (&lt;em&gt;cleanup&lt;/em&gt; ou &lt;em&gt;teardown&lt;/em&gt;)&lt;/strong&gt;: quando precisamos criar algum recurso para execução de um teste (criação de uma tabela de banco de dados, por exemplo), também precisamos garantir que isso seja desfeito para que não interfira nos próximos testes. As fixtures também auxiliam aqui. No &lt;em&gt;unittest&lt;/em&gt; isso é feito no método &lt;code&gt;tearDown()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preparação
&lt;/h2&gt;

&lt;p&gt;Para demonstrar o uso das fixtures, vamos nos aprofundar em um exemplo que necessita da etapa de preparação. Vamos assumir um cenário onde temos uma função &lt;code&gt;busca_pessoa&lt;/code&gt; que recebe um &lt;code&gt;nome&lt;/code&gt; e busca um registro de pessoa em um banco de dados. Um possível teste para essa função ficaria assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Para buscarmos uma pessoa, é necessário termos um
&lt;/span&gt;    &lt;span class="c1"&gt;# registro de pessoa no banco.
&lt;/span&gt;    &lt;span class="c1"&gt;# Essa é a etapa de preparação.
&lt;/span&gt;
    &lt;span class="c1"&gt;# Primeiro, precisamos criar a tabela de pessoas.
&lt;/span&gt;    &lt;span class="c1"&gt;# Vamos assumir que temos uma função para isso.
&lt;/span&gt;    &lt;span class="c1"&gt;# O conteúdo dessa função não é importante para o nosso
&lt;/span&gt;    &lt;span class="c1"&gt;# teste.
&lt;/span&gt;    &lt;span class="n"&gt;cria_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Também precisamos de uma session do banco.
&lt;/span&gt;    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# E criamos a pessoa, utilizando a session.
&lt;/span&gt;    &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Finalizada a preparação, executamos nossa ação e
&lt;/span&gt;    &lt;span class="c1"&gt;# guardamos o resultado em uma variável.
&lt;/span&gt;    &lt;span class="n"&gt;pessoa_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# E verificamos se o resultado é o esperado.
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pessoa não encontrada"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;

    &lt;span class="c1"&gt;# Por último, precisamos fechar a session e desfazer a
&lt;/span&gt;    &lt;span class="c1"&gt;# criação da tabela.
&lt;/span&gt;    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Assim como a função cria_tabela, o conteúdo da função
&lt;/span&gt;    &lt;span class="c1"&gt;# destroi_tabela não é relevante para o teste.
&lt;/span&gt;    &lt;span class="n"&gt;destroi_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse é um teste bem simples comparado aos testes que precisamos escrever no dia a dia, mas, repare que as etapas de ação e verificação (as mais importantes), são apenas três linhas, enquanto as outras etapas ocupam um espaço mais significativo no teste. Não queremos ter que repetir toda a preparação e finalização toda vez que precisarmos criar um teste parecido. Podemos simplificar tudo isso com fixtures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pytest&lt;/span&gt;

&lt;span class="c1"&gt;# Uma fixture é apenas uma função normal, marcada com o
# decorator @pytest.fixture.
&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;cria_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;

&lt;span class="c1"&gt;# Declaramos um parâmetro session, que receberá o retorno da
# fixture session.
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# ação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# verificação
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pessoa não encontrada"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;

    &lt;span class="c1"&gt;# finalização
&lt;/span&gt;    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;destroi_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, reduzimos o trecho de preparação dentro do nosso teste e podemos reutilizar a &lt;em&gt;session&lt;/em&gt; em outros testes, mas ainda estamos fechando a session e desfazendo a tabela dentro do teste. Podemos mover esse código para dentro da fixture, utilizando a &lt;em&gt;keyword&lt;/em&gt; &lt;code&gt;yield&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;cria_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Agora trasformamos a fixture em um generator.
&lt;/span&gt;    &lt;span class="c1"&gt;# Com isso, o pytest passa o valor de session para o
&lt;/span&gt;    &lt;span class="c1"&gt;# nosso teste e continua para a etapa de finalização
&lt;/span&gt;    &lt;span class="c1"&gt;# após o teste ser concluído.
&lt;/span&gt;    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;

    &lt;span class="c1"&gt;# finalização
&lt;/span&gt;    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;destroi_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# ação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# verificação
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pessoa não encontrada"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A utilização de &lt;em&gt;generators&lt;/em&gt; é uma excelente forma de finalizar recursos criados dentro da fixture. Porém, ainda podemos ter problemas caso a fixture lance uma exceção e, em algumas situações, é possível que recursos não sejam finalizados. Para que isso não ocorra, é &lt;a href="https://docs.pytest.org/en/stable/fixture.html#safe-teardowns"&gt;recomendado&lt;/a&gt; limitar a quantidade de ações que podem lançar exceções dentro de uma fixture. Na função &lt;code&gt;session&lt;/code&gt;, temos duas responsabilidades: criar as tabelas e instanciar a sessão. Podemos separar essas duas responsabilidades da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tabela&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;cria_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Como não produzimos nenhum valor aqui, a palavra yield
&lt;/span&gt;    &lt;span class="c1"&gt;# serve apenas para pausar a função e passar o controle
&lt;/span&gt;    &lt;span class="c1"&gt;# para a função session.
&lt;/span&gt;    &lt;span class="k"&gt;yield&lt;/span&gt;

    &lt;span class="n"&gt;destroi_tabela&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Declaramos a dependência da fixture tabela.
&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tabela&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vimos que uma fixture pode depender de outra. Podemos reduzir ainda mais a etapa de preparação dentro do teste, criando uma terceira fixture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Aqui, a fixture maria utiliza a fixture session.
&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;maria&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pessoa&lt;/span&gt;

&lt;span class="c1"&gt;# Agora nosso teste só precisa utilizar a fixture maria.
# Note que, como não precisamos do retorno, a fixture é
# declarada mas o parâmetro maria não é utilizado.
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maria&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# ação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# verificação
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pessoa não encontrada"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nosso teste agora já está bem menor e podemos reaproveitar as fixtures em outros testes. Uma outra melhoria que podemos fazer seria transformar a fixture &lt;code&gt;maria&lt;/code&gt;, utilizando o padrão &lt;a href="https://docs.pytest.org/en/stable/fixture.html#factories-as-fixtures"&gt;&lt;em&gt;factories como fixtures&lt;/em&gt;&lt;/a&gt;. Dessa forma, podemos reaproveitar o código para criar novos objetos com parâmetros diferentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...
&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Dentro da fixture, criamos uma função factory, que
&lt;/span&gt;    &lt;span class="c1"&gt;# recebe os parâmetros desejados e cria o objeto.
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pessoa&lt;/span&gt;

    &lt;span class="c1"&gt;# A fixture retorna a função factory.
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_cria_pessoa&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ação
&lt;/span&gt;    &lt;span class="n"&gt;pessoa_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# verificação
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pessoa não encontrada"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;pessoa_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora nosso teste ficou muito melhor! O grande trabalho de preparação foi abstraído para as fixtures, ficando como responsabilidade do teste apenas informar os parâmetros para criação do objeto pessoa, realizar uma ação e verificar o resultado.&lt;/p&gt;

&lt;p&gt;Com isso, a sequência de dependências das nossas fixtures fica da seguinte forma:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test_busca_pessoa() -&amp;gt; cria_pessoa() -&amp;gt; session() -&amp;gt; tabela()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Com a criação de diferentes fixtures, cada uma com sua responsabilidade,  fica fácil reaproveita-las em outros testes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_busca_todas_as_pessoas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# preparação
&lt;/span&gt;    &lt;span class="n"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cria_pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gabriel"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ação
&lt;/span&gt;    &lt;span class="n"&gt;pessoas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;busca_pessoas&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# verificação
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Não é segredo para ninguém que testes são uma excelente ferramenta para garantir a qualidade do nosso código. Para isso, é essencial que, não apenas eles existam e estejam funcionando, mas também que eles sejam legíveis e que seja fácil criar novos testes. Afinal de contas, os testes também fazem parte da base de código de um projeto e merecem total atenção. As fixtures do pytest são uma ótima maneira de simplificar as etapas de preparação e finalização dos testes e, consequentemente, melhorar a qualidade do código.&lt;/p&gt;

&lt;p&gt;Essa é apenas uma parte do que é possível fazer utilizando fixtures. O pytest oferece uma série de fixtures por padrão, que podem ser muito úteis para diversas situações. Para saber mais, recomendo uma boa leitura da &lt;a href="https://docs.pytest.org/en/stable/fixture.html"&gt;documentação do pytest&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
      <category>codequality</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
