<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="186241" data-post-id="186241">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="halostatue" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/halostatue/120/2389_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  halostatue
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Depends on whether you’re using your schemas for all CRUD operations or mostly R operations. I have (some) schemas that are readonly. They still link like they should, but I <em>also</em> don’t always put all <code>belongs_to</code> or <code>has_many</code> relationships in all of my schema (because while the relationship exists and is enforced by the DB schema and the part of the schema I use for CRUD capabilities), not all schema are equal.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186241" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-186241" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186241"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="186419" data-post-id="186419">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="TheFirstAvenger" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/TheFirstAvenger/120/11950_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  TheFirstAvenger
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My .02 on fixtures vs factories:</p>
<p>My problem with Fixtures is that it buries the logic that you are testing. Repeatedly in my career I have jumped in to work on a fixture-using project, and without fail I end up wasting way too much time on what should be a simple task of fixing or updating a test, because the logic of what exactly is being tested was not clear in the test, it was buried implicitly in the fixture data.</p>
<p>For example, if you were to come across this test which is all of a sudden failing, which relies on fixtures, what would you do to fix it?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">test “returns confrazzled users” do
  assert [%{id: 1}, %{id: 3}] = Confrazzler.get_confrazzled_users()
end
</code></pre>
<p>From the test, it is unclear what is being tested, or why it is failing. You could look in the fixtures, but even then it most likely wouldn’t be clear what exactly is supposed to be testing. You would have to dig into the actual code to figure out what get_confrazzled_users actually does. In a recent project, the function being tested used a 100 line SQL statement. It was basically impossible to reverse engineer what exactly was being tested.</p>
<p>Now, if it were written with factories, you would instead see this code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">test “returns confrazzled users“ do
  %{id: id1} = insert(:user, frazzled: “con”)
  %{id: id2} = insert(:user, frazzled: “pro”)
  %{id: id3} = insert(:user, frazzled: “con”)

  assert [%{id: ida}, %{id: idb}] = Confrazzler.get_confrazzled_users()
  assert Enum.sort([ida, idb]) == Enum.sort([id1, id2])
end
</code></pre>
<p>In the factory test, the setup is clear and explicit, and part of the test. There is no digging in fixtures to figure out what the implicit assumptions are, or combing through 20 fields to try and figure out which field(s) are actually being tested in the current test, because the answer to that is clear in the setup inside the test. It is easy to understand that this test is testing that get_confrazzled_users returns users where their frazzled field is “con”.</p>
<p>In the fixture test, frazzled: “con” was set for id 1 and 3 in the fixture. That fact was known by the person who wrote the test initially, but it is hidden knowledge to everyone else reading it, and hidden to anyone who subsequently needs to update the fixtures.</p>
<p>Beyond the issue of fixtures burying logic, there have been plenty of issues I have caught because the factory was using randomly generated data and triggered an edge case I didn’t think of, which the static fixture never would have covered.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186419" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-186419" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186419"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="186437" data-post-id="186437">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yep, you pretty much summed my experience with Ruby on Rails testing (and occasionally with PHP and some Java). The only good usage of fixtures I ever found was to pre-seed the test DB with data since there are plenty of apps where proper testing requires non-empty DB (namely context outside of what you current test is testing).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186437" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-186437" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186437"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="186479" data-post-id="186479">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="TheFirstAvenger" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/TheFirstAvenger/120/11950_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  TheFirstAvenger
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dimitarvp" data-post="24" data-topic="33803">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>The only good usage of fixtures I ever found was to pre-seed the test DB with data since there are plenty of apps where proper testing requires non-empty DB (namely context outside of what you current test is testing).</p>
</blockquote>
</aside>
<p>I would argue that if data in a context outside of what your current test is testing is necessary to the test, then it isn’t actually outside of the context of what you are testing. If a test of context A requires 50 data points in context B, then that should be part of the setup for testing context A, because if someone goes and changes the global fixtures, and now all of a sudden there are only 49 matching items in the fixture, then test A will start failing when the developer didn’t change any code related to context A or it’s test, and they are now on the hook for figuring out how to fix that broken test which they know nothing about.</p>
<p>Furthermore, if Context A starts failing in production, and someone investigating it looks at the properly set up version of the test, then it will be immediately apparent that “this fails without 50 items in Context B”, and maybe that is the cause in production.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186479" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-186479" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186479"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="186484" data-post-id="186484">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="TheFirstAvenger" data-post="25" data-topic="33803">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thefirstavenger/48/11950_2.png" class="avatar"> TheFirstAvenger:</div>
<blockquote>
<p>I would argue that if data in a context outside of what your current test is testing is necessary to the test, then it isn’t actually outside of the context of what you are testing.</p>
</blockquote>
</aside>
<p>Sure, I am not contending that. But let’s include high developer velocity in the equation. In several teams I’ve been in, the people were happy to take some shortcuts for that cause.</p>
<p>I do personally prefer crystal-clear dependency graphs – especially for data – but often times it wasn’t up to me and my experience and past expertise have been disregarded as “pursuing academic excellence as opposed to being productive”.</p>
<p>I did eventually sneak a lot of such fixes behind the backs of the team and the manager for which I wasn’t congratulated, even if that resulted in eliminating 20+ intermittent CI/CD test errors. Oh well. <img src="https://forum.elixirforum.com/images/emoji/apple/man_shrugging.png?v=15" title=":man_shrugging:" class="emoji" alt=":man_shrugging:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186484" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-186484" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186484"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="186487" data-post-id="186487">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tfwright" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tfwright/120/20299_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tfwright
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="19" data-topic="33803">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Finally, a summary that was given to me a long time ago that explains when to use fixtures vs factories well is:</p>
<ol>
<li>Use fixtures for the setup data (i.e. the data you need to define before you can start writing your test)</li>
<li>Use factories for the data under test, especially because you want the data being tested close to the test itself</li>
</ol>
<p>In my opinion, factories are actually easier to get started as they require less discipline (with bigger costs in the long term), while fixtures are really easy to mess up at the beginning (but pay off if well-structured).</p>
</blockquote>
</aside>
<p>This seems spot on. Working with Rails, fixtures clashed hard with the convention over configuration philosophy, and practically speaking, when you’re working on “rapidly prototyping” a lot of brand new apps, it was much better to have everything self contained in each test. Conversely working on a project that did fixtures <em>poorly</em> was a hellish experience.</p>
<p>But getting acquainted with Elixir/Phoenix has really made me see how much of the “magic” you get with factory generators (like FactoryGirl) is unnecessary an d a potential source of silly gotchas. Putting a little more thought and discipline at the beginning can pay off big, while still allowing the vast majority of the convenience. In the Rails world there was a lot of talk about the 80/20 rule in terms of features, I feel like a similar rule should be applied to convenience: you get 80% of the benefit from 20% of the magic…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="186487" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/split-thread-fixtures-vs-factories-in-elixir/33803/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-186487" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="186487"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>