<?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: Ana Schwendler</title>
    <description>The latest articles on DEV Community by Ana Schwendler (@anaschwendler).</description>
    <link>https://dev.to/anaschwendler</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%2F359954%2F73239f1e-d95a-4d6e-a5b5-fadc2b3b2269.png</url>
      <title>DEV Community: Ana Schwendler</title>
      <link>https://dev.to/anaschwendler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anaschwendler"/>
    <language>en</language>
    <item>
      <title>Usando VCR para simular requisições</title>
      <dc:creator>Ana Schwendler</dc:creator>
      <pubDate>Fri, 26 Nov 2021 11:46:36 +0000</pubDate>
      <link>https://dev.to/anaschwendler/usando-vcr-para-simular-requisicoes-2eg1</link>
      <guid>https://dev.to/anaschwendler/usando-vcr-para-simular-requisicoes-2eg1</guid>
      <description>&lt;p&gt;Nos últimos meses, tenho trabalhado com muitas requisições externas de API. Como faço parte da equipe de logística da Marley Spoon, nosso desafio é garantir que nossas requisições sejam integradas a tempo e que tudo seja entregue da melhor forma possível.&lt;/p&gt;

&lt;p&gt;Parte dessa tarefa, como desenvolvedora de software, é garantir que o código que foi escrito seja bem testado e faça o que deve ser feito, de forma correta e eficiente. Nosso projeto tem muitas integrações com parceiros de logística. Quando fazemos uma integração esses outros sistemas, não queremos realizar requisições reais toda vez que executamos nossos testes. Essa ação não só gera apenas requisições desnecessárias, mas também pode gerar problemas com limites de requisições com API externas além de outros efeitos colaterais inconvenientes, como testes tomando mais tempo para rodar. Para evitar isso, fingimos fazer requisições reais e há uma ferramenta que ajuda a simular essas chamadas: ao registrar dados reais de uma requisição real, somos capazes de fazer o esboço(stub) de uma resposta de serviço web externo. O arquivo salvo é chamados de "fita cassete (cassette tape)" e o nome da ferramenta a que me refiro é &lt;a href="https://github.com/vcr/vcr"&gt;VCR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Neste post vou explicar como tenho aprendido a usá-lo e por que acho que é útil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT1R9RfuBqWvfo8oDe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT1R9RfuBqWvfo8oDe/giphy.gif" alt="Arnold recebendo CD" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é uma simulação de requisição de teste?
&lt;/h2&gt;

&lt;p&gt;Como este artigo não é sobre a técnica de simulação de requisições, vou apenas explicar brevemente e adicionar um link para um artigo útil sobre o assunto. &lt;a href="https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/"&gt;Neste artigo&lt;/a&gt;(em inglês) podemos observar que simulação de testes de requisição pode ser definido como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simular testes de requisição significa uma versão simulada de um serviço externo ou interno que pode substituir o real, ajudando seus testes a serem executados de forma mais rápida e confiável. Quando sua implementação interage com as propriedades de um objeto, em vez de sua função ou comportamento, uma imitação pode ser usada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;… e é exatamente para isso que usamos o VCR.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é VCR?
&lt;/h2&gt;

&lt;p&gt;De acordo com a &lt;a href="https://github.com/vcr/vcr"&gt;documentação&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Grave as interações HTTP do seu conjunto de testes e reproduza-as durante futuras execuções de teste para testes rápidos, determinísticos e precisos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Que significa que, quando você executar o teste pela primeira vez com a sintaxe do VCR, ele registrará o que aconteceu e, na próxima vez que você executar o teste novamente, terá a versão gravada pronta para substituir a solicitação real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como usar o VCR?
&lt;/h2&gt;

&lt;p&gt;Eu tenho um exemplo básico &lt;a href="https://github.com/anaschwendler/vcr_example"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basicamente, sempre que você quiser testar uma parte do código que requer uma requisição externa, você usa o método &lt;code&gt;.use_cassette&lt;/code&gt; para expor que você deseja que o VCR lide com isso como uma fita cassete. Se já houver dados com uma interação HTTP pré-gravada, o VCR o usará. Se não, o VCR &lt;strong&gt;cria automáticamente&lt;/strong&gt; uma "fita cassete" (dessa vez fazendo uma requisição real) baseado na requisição feita no teste.&lt;/p&gt;

&lt;p&gt;Mas ainda assim, se o que você quer realizar requisições reais todas as vezes que seus testes rodam, VCR também oferece diferente modos de gravação, que podem ser conferidos &lt;a href="https://relishapp.com/vcr/vcr/v/6-0-0/docs/record-modes"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rubygems'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'test/unit'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'vcr'&lt;/span&gt;

&lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cassette_library_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"fixtures/vcr_cassettes"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hook_into&lt;/span&gt; &lt;span class="ss"&gt;:webmock&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VCRTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestCase&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_example_dot_com&lt;/span&gt;
    &lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use_cassette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"synopsis"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'http://www.iana.org/domains/reserved'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;assert_match&lt;/span&gt; &lt;span class="sr"&gt;/Example domains/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos requisitando o uso de uma fita chamada &lt;code&gt;synopsis&lt;/code&gt;, que simula a requisição para a &lt;a href="http://www.iana.org/domains/reserved"&gt;iana.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se o teste estiver rodando pela primeira vez, VCR irá gerar um arquivo, armazenado em &lt;code&gt;fixtures/vcr_cassettes&lt;/code&gt;, que nesse exemplo se chamará &lt;code&gt;synopsis.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Após rodar o teste, o arquivo &lt;code&gt;fixtures/vcr_cassettes/synopsis.yml&lt;/code&gt; se parecerá com (eu removi algumas partes por que o arquivo é grande):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
http_interactions:
- request:
    method: get
    uri: http://www.iana.org/domains/reserved
    body:
      encoding: US-ASCII
      string: ''
    headers:
      Accept-Encoding:
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
      Accept:
      - "*/*"
      User-Agent:
      - Ruby
  response:
    status:
      code: 200
      message: OK
    headers:
      Date:
      - Fri, 18 Jun 2021 08:06:40 GMT
      Server:
      - Apache
      Vary:
      - Accept-Encoding
      Last-Modified:
      - Thu, 21 May 2020 22:41:39 GMT
      X-Frame-Options:
      - SAMEORIGIN
      Expires:
      - Fri, 18 Jun 2021 09:56:45 GMT
      Referrer-Policy:
      - origin-when-cross-origin
      X-Content-Type-Options:
      - nosniff
      Age:
      - '595'
      Content-Type:
      - text/html; charset=UTF-8
      Cache-Control:
      - public, max-age=21603
      Content-Security-Policy: /*cropped security policy*/
      Transfer-Encoding:
      - chunked
    body:
      encoding: ASCII-8BIT
      string: !binary |-
        /*cropped binary string*/
    http_version:
  recorded_at: Fri, 18 Jun 2021 08:06:40 GMT
recorded_with: VCR 5.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então, a partir de agora sua suíte de testes usará o arquivo salvo. Isso ainda vai fazer seus testes rodarem mais rápido, pois agora temos o arquivo armazenado e não precisamos fazer a requisição real a aplicação externa, o que sempre pode tomar muito mais tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos da vida real
&lt;/h2&gt;

&lt;p&gt;Um exemplo de projeto que usa VCR é esse cliente &lt;code&gt;site-search-ruby&lt;/code&gt; da elastic: &lt;a href="https://github.com/elastic/site-search-ruby"&gt;https://github.com/elastic/site-search-ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No contexto de &lt;code&gt;Search&lt;/code&gt;, quando procuramos todos os &lt;code&gt;DocumentTypes&lt;/code&gt; no mecanismo, eles usam um arquivo chamado &lt;code&gt;engine_search&lt;/code&gt; para simular uma requisição:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elastic/site-search-ruby/blob/master/spec/client_spec.rb"&gt;https://github.com/elastic/site-search-ruby/blob/master/spec/client_spec.rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse é o arquivo usado nesta instância: &lt;a href="https://github.com/elastic/site-search-ruby/blob/master/spec/fixtures/vcr/engine_search.yml"&gt;https://github.com/elastic/site-search-ruby/blob/master/spec/fixtures/vcr/engine_search.yml&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;VCR parece ser uma ferramenta bastante confiável para simular requisições para API externas. Mas nós ainda precisamos estar conscientes de que API podem sempre mudar, e quando isso acontece, precisamos gravar nossos testes novamente. Esse processo deve ser simples e fácil de reproduzir, então para mais ficar sobre o uso do VCR, eu recomendo &lt;a href="https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html"&gt;esse&lt;/a&gt; artigo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escondendo credenciais confidenciais em vcr_cassettes
&lt;/h3&gt;

&lt;p&gt;Há uma opção de configuração disponível para filtrar dados sensíveis que podem ser usados para evitar que sejam gravados nos arquivos de cassete, a documentação está &lt;a href="https://relishapp.com/vcr/vcr/v/5-0-0/docs/configuration/filter-sensitive-data"&gt;aqui&lt;/a&gt;. Isso é importante, por que não queremos credenciais secretas expostas publicamente nos nossos repositórios armazenados na internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vcr/vcr"&gt;https://github.com/vcr/vcr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elastic/site-search-ruby"&gt;https://github.com/elastic/site-search-ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/"&gt;https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html"&gt;https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>vcr</category>
      <category>testing</category>
    </item>
    <item>
      <title>Using VCR to Mock Your Requests</title>
      <dc:creator>Ana Schwendler</dc:creator>
      <pubDate>Fri, 18 Jun 2021 10:05:31 +0000</pubDate>
      <link>https://dev.to/marleyspoon/using-vcr-to-mock-your-requests-3127</link>
      <guid>https://dev.to/marleyspoon/using-vcr-to-mock-your-requests-3127</guid>
      <description>&lt;p&gt;In the past months, I've been working with a lot of external API requests. Since I'm part of the Marley Spoon’s logistics team, our challenge is to make sure our requests are done in time and everything is delivered in good shape.&lt;/p&gt;

&lt;p&gt;Part of this task, as a software developer, is making sure the code I write is well tested, and does what it is supposed to do. Our software has many integrations with our logistics partners. When integrating with their systems, we don't want to hit external APIs with real requests every time we run our tests. This not only generates unnecessary requests that can cause problems with API rate limits and other unwanted side-effects. It also makes them run slower. To avoid that, we pretend to make real requests and there is a tool that helps "faking" these calls: by recording real data from a real network request, we are able to stub a third party’s web service response. The saved data is called a "cassette tape" and the name of the tool I refer to is &lt;a href="https://github.com/vcr/vcr"&gt;VCR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post I'll explain how I've been learning to use it and why I think it is useful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT1R9RfuBqWvfo8oDe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT1R9RfuBqWvfo8oDe/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a mock test?
&lt;/h2&gt;

&lt;p&gt;Since this is not about the mocking technique, I'll just briefly introduce it and link to a useful article on the topic. In &lt;a href="https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/"&gt;this post&lt;/a&gt; we can see mock testing defined as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mocking means creating a fake version of an external or internal service that can stand in for the real one, helping your tests run more quickly and more reliably. When your implementation interacts with an object’s properties, rather than its function or behavior, a mock can be used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;… and that is exactly the reason why we use VCR.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is VCR?
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://github.com/vcr/vcr"&gt;their documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which means that when you first run your test with the VCR syntax, it will record what happened and next time you run the test again, you will have the recorded version ready to stand in for the real request.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use VCR?
&lt;/h2&gt;

&lt;p&gt;I have a basic example &lt;a href="https://github.com/anaschwendler/vcr_example"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So basically, whenever you want to test a part of code that requires an external web request, you use the  &lt;code&gt;.use_cassette&lt;/code&gt; method to state that you want VCR to deal with that with a cassette file. If there already is data with a pre-recorded HTTP interaction, VCR will use it. If not, VCR will &lt;strong&gt;automatically create&lt;/strong&gt; a cassette file (this time making a real request) based on the request made in the test.&lt;/p&gt;

&lt;p&gt;But still, if you are looking forward to making real requests, VCR also offers different record modes, which can be checked &lt;a href="https://relishapp.com/vcr/vcr/v/6-0-0/docs/record-modes"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rubygems'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'test/unit'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'vcr'&lt;/span&gt;

&lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cassette_library_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"fixtures/vcr_cassettes"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hook_into&lt;/span&gt; &lt;span class="ss"&gt;:webmock&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VCRTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Unit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TestCase&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_example_dot_com&lt;/span&gt;
    &lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use_cassette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"synopsis"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'http://www.iana.org/domains/reserved'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;assert_match&lt;/span&gt; &lt;span class="sr"&gt;/Example domains/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you are requesting to use a cassette called &lt;code&gt;synopsis&lt;/code&gt;, which mocks a request to &lt;a href="http://www.iana.org/domains/reserved"&gt;iana.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If this is running the first time, VCR will generate a "cassette" file, which will be stored at &lt;code&gt;fixtures/vcr_cassettes&lt;/code&gt;, which for the example will be called &lt;code&gt;synopsis.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is what &lt;code&gt;fixtures/vcr_cassettes/synopsis.yml&lt;/code&gt; looks like (I've removed some parts as it was too big):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
http_interactions:
- request:
    method: get
    uri: http://www.iana.org/domains/reserved
    body:
      encoding: US-ASCII
      string: ''
    headers:
      Accept-Encoding:
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
      Accept:
      - "*/*"
      User-Agent:
      - Ruby
  response:
    status:
      code: 200
      message: OK
    headers:
      Date:
      - Fri, 18 Jun 2021 08:06:40 GMT
      Server:
      - Apache
      Vary:
      - Accept-Encoding
      Last-Modified:
      - Thu, 21 May 2020 22:41:39 GMT
      X-Frame-Options:
      - SAMEORIGIN
      Expires:
      - Fri, 18 Jun 2021 09:56:45 GMT
      Referrer-Policy:
      - origin-when-cross-origin
      X-Content-Type-Options:
      - nosniff
      Age:
      - '595'
      Content-Type:
      - text/html; charset=UTF-8
      Cache-Control:
      - public, max-age=21603
      Content-Security-Policy: /*cropped security policy*/
      Transfer-Encoding:
      - chunked
    body:
      encoding: ASCII-8BIT
      string: !binary |-
        /*cropped binary string*/
    http_version:
  recorded_at: Fri, 18 Jun 2021 08:06:40 GMT
recorded_with: VCR 5.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From now on your test suite will use this cassette file. It will also run faster, as it has the file in place and doesn't need to make the request which can take more time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples in real life
&lt;/h2&gt;

&lt;p&gt;One example of project that uses VCR is this &lt;code&gt;site-search-ruby&lt;/code&gt; client from elastic: &lt;a href="https://github.com/elastic/site-search-ruby"&gt;https://github.com/elastic/site-search-ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In their context of &lt;code&gt;Search&lt;/code&gt;, when searching all DocumentTypes in the engine, they use a cassette called &lt;code&gt;engine_search&lt;/code&gt; to mock a request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elastic/site-search-ruby/blob/master/spec/client_spec.rb"&gt;https://github.com/elastic/site-search-ruby/blob/master/spec/client_spec.rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the cassette file that is used in this call: &lt;a href="https://github.com/elastic/site-search-ruby/blob/master/spec/fixtures/vcr/engine_search.yml"&gt;https://github.com/elastic/site-search-ruby/blob/master/spec/fixtures/vcr/engine_search.yml&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;VCR seems to be a very reliable tool to fake requests to APIs. But we still need to be aware that sometimes APIs can change and with that we need to record our tests again. This process should be simple and easy to reproduce, so for more tips regarding VCR use, I recommend &lt;a href="https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html"&gt;this&lt;/a&gt; blog post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hiding confidential credentials in vcr_cassettes
&lt;/h3&gt;

&lt;p&gt;There is a configuration option available to filter sensitive data that can be used to prevent it from being written to the cassette files, the documentation is &lt;a href="https://relishapp.com/vcr/vcr/v/5-0-0/docs/configuration/filter-sensitive-data"&gt;here&lt;/a&gt;. This is important, as you want to track your cassette YML files in your source control management tool. And secrets don’t belong there.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vcr/vcr"&gt;https://github.com/vcr/vcr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elastic/site-search-ruby"&gt;https://github.com/elastic/site-search-ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/"&gt;https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html"&gt;https://fabioperrella.github.io/10_tips_to_help_using_the_VCR_gem_in_your_ruby_test_suite.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks &lt;a href="https://github.com/memunaharuna"&gt;Memuna&lt;/a&gt; for reviewing it! 🎉&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>vcr</category>
      <category>testing</category>
    </item>
    <item>
      <title>Setting up tests for Django Plugins</title>
      <dc:creator>Ana Schwendler</dc:creator>
      <pubDate>Sat, 04 Apr 2020 11:31:05 +0000</pubDate>
      <link>https://dev.to/anaschwendler/setting-up-tests-for-django-plugins-5121</link>
      <guid>https://dev.to/anaschwendler/setting-up-tests-for-django-plugins-5121</guid>
      <description>&lt;p&gt;Did you have a good idea for a nice Django plugin? Don’t know how to set up tests for it without creating a whole Django app for your project? Here is the solution for you. This article is written after a &lt;a href="https://github.com/cuducos/django-public-admin/pull/11"&gt;pull request&lt;/a&gt; for &lt;a href="https://github.com/cuducos/django-public-admin"&gt;Django Public Admin&lt;/a&gt;, using &lt;a href="https://github.com/codingjoe/django-stdimage"&gt;django-stdimage&lt;/a&gt; as a base.&lt;/p&gt;

&lt;p&gt;Django Public Admin is a plugin that makes a public and read-only version of the Django Admin. It uses Poetry to manage packages and dependencies, &lt;code&gt;pytest&lt;/code&gt; to run tests in addition to &lt;code&gt;pytest-django&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Django
&lt;/h3&gt;

&lt;p&gt;Django is a web framework written in Python, and it’s designed for developers to write &lt;a href="https://docs.djangoproject.com/en/3.0/intro/reusable-apps/"&gt;reusable apps&lt;/a&gt; (apps in this context means application, which in this case is the project designed using Django):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Reusability is the way of life in Python. […] Django itself is also a normal Python package. This means that you can take existing Python packages or Django apps and compose them into your own web project. You only need to write the parts that make your project unique. The idea of these apps.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, we can wrap reusable parts of any Django app and use them in other Django apps we write. This is the idea and for that we also need tests. At the end of the day, we have a reusable bit of code without the accompanying Django application.&lt;/p&gt;

&lt;p&gt;So, how to test a part of a Django app without the full Django app? 🤔&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding what is missing
&lt;/h3&gt;

&lt;p&gt;With the environment already configured, the first issue that appeared was that when running the tests outside of a Django app was that it was complaining that our Django was &lt;code&gt;ImproperlyConfigured&lt;/code&gt; and that we need to set up the &lt;code&gt;DJANGO_SETTINGS_MODULE&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure&lt;span class="o"&gt;()&lt;/span&gt; before accessing settings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting up &lt;code&gt;tests/settings.py&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;After talking to &lt;a href="https://twitter.com/AnaPaulaGomess"&gt;Ana Paula Gomes&lt;/a&gt;, she pointed out that she already saw this being implemented in a nice way on another project, and what was being made was to create a &lt;code&gt;tests/settings.py&lt;/code&gt; file that will act as configuration for Django to run the tests. So for that, I created a file that looks like that:&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;os&lt;/span&gt;

&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;'django.contrib.admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'django.contrib.auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'django.contrib.contenttypes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'django.contrib.sessions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'django.contrib.sites'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'public_admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'tests'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'foobar'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does contain the &lt;a href="https://docs.djangoproject.com/en/3.0/ref/settings/"&gt;default Django configuration variables&lt;/a&gt; as below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;BASE_DIR&lt;/code&gt;: This is pointed to the Django project directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/3.0/ref/settings/#installed-apps"&gt;&lt;code&gt;INSTALLED_APPS&lt;/code&gt;&lt;/a&gt;: Which contains all the apps necessary to run your set up (don’t forget to add your project here &lt;code&gt;public_admin&lt;/code&gt; in our target project, and &lt;code&gt;tests&lt;/code&gt; ), and might vary depending on what you are testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/3.0/ref/settings/#secret-key"&gt;&lt;code&gt;SECRET_KEY&lt;/code&gt;&lt;/a&gt;: The &lt;code&gt;SECRET_KEY&lt;/code&gt; setting must not be empty.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up &lt;code&gt;setup.cfg&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;After configuring up the &lt;code&gt;settings.py&lt;/code&gt; we need to tell our application to use this file to run the tests, setting up the &lt;code&gt;DJANGO_SETTINGS_MODULE&lt;/code&gt; variable in a special file called &lt;code&gt;setup.cfg&lt;/code&gt;, in our case, we tell that when &lt;code&gt;[tool:pytest]&lt;/code&gt; is called we should use this settings environment, this might look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[tool:pytest]
DJANGO_SETTINGS_MODULE=tests.settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is it, now you can set up your tests for Django Plugins without creating an app for testing using &lt;code&gt;pytest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0HlGS7yQ9AUwlY52/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0HlGS7yQ9AUwlY52/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
