title: Pytest where to store expected data
body: <p>Testing function I need to pass parameters and see the output matches the expected output.   </p>
  
  <p>It is easy when function's response is just a small array or a one-line string which can be defined inside the test function, but suppose function I test modifies a config file which can be huge. Or the resulting array is something 4 lines long if I define it explicitly. Where do I store that so my tests remain clean and easy to maintain?</p>
  
  <p>Right now if that is string I just put a file near the <code>.py</code> test and do <code>open()</code> it inside the test:</p>
  
  <pre><code>def test_if_it_works():
      with open('expected_asnwer_from_some_function.txt') as res_file:
          expected_data = res_file.read()
      input_data = ... # Maybe loaded from a file as well
      assert expected_data == if_it_works(input_data)
  </code></pre>
  
  <p>I see many problems with such approach, like the problem of maintaining this file up to date. It looks bad as well.
  I can make things probably better moving this to a fixture:</p>
  
  <pre><code>@pytest.fixture
  def expected_data()
      with open('expected_asnwer_from_some_function.txt') as res_file:
          expected_data = res_file.read()
      return expected_data
  
  @pytest.fixture
  def input_data()
      return '1,2,3,4'
  
  def test_if_it_works(input_data, expected_data):
      assert expected_data == if_it_works(input_data)
  </code></pre>
  
  <p>That just moves the problem to another place and usually I need to test if function works in case of empty input, input with a single item or multiple items, so I should create one big fixture including all three cases or multiple fixtures. In the end code gets quite messy.</p>
  
  <p>If a function expects a complicated dictionary as an input or gives back the dictionary of the same huge size test code becomes ugly:</p>
  
  <pre><code> @pytest.fixture
   def input_data():
       # It's just an example
       return {['one_value': 3, 'one_value': 3, 'one_value': 3,
       'anotherky': 3, 'somedata': 'somestring'], 
        ['login': 3, 'ip_address': 32, 'value': 53, 
        'one_value': 3], ['one_vae': 3, 'password': 13, 'lue': 3]}
  </code></pre>
  
  <p>It's quite hard to read tests with such fixtures and keep them up to date.</p>
  
  <h3>Update</h3>
  
  <p>After searching a while I found a library which solved a part of a problem when instead of big config files I had large HTML responses. It's <a href="https://github.com/sigmavirus24/betamax" rel="noreferrer">betamax</a>.</p>
  
  <p>For easier usage I created a fixture:</p>
  
  <pre><code>from betamax import Betamax
  
  @pytest.fixture
  def session(request):
      session = requests.Session()
      recorder = Betamax(session)
      recorder.use_cassette(os.path.join(os.path.dirname(__file__), 'fixtures', request.function.__name__)
      recorder.start()
      request.addfinalizer(recorder.stop)
      return session
  </code></pre>
  
  <p>So now in my tests I just use the <code>session</code> fixture and every request I make is being serialized automatically to the <code>fixtures/test_name.json</code> file so the next time I execute the test instead of doing a real HTTP request library loads it from the filesystem:</p>
  
  <pre><code>def test_if_response_is_ok(session):
     r = session.get("http://google.com")
  </code></pre>
  
  <p>It's quite handy because in order to keep these fixtures up to date I just need to clean the <code>fixtures</code> folder and rerun my tests.</p>