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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hkrutzer" data-post="1" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/e0b2c6/48.png" class="avatar"> hkrutzer:</div>
<blockquote>
<p>For example, there is a process that handles user chat messages. The process also triggers telemetry based on the messages, and telemetry is captured by another process and queued up to be saved in an analytics database. So the test scenario is: start a chat process, send some messages, and ensure the database contains the correct statistics. I don’t think it is an especially good idea to test this way, but it doesn’t seem entirely unreasonable either.</p>
</blockquote>
</aside>
<p>This feels like two separate layers of testing to me but I just don’t have any experience with telemetry so I can’t answer intelligently.  But it would seem to me you would want to test that a chat message triggers a telemetry event and then a general test that telemetry events are being consumed and saving to the db (and depending on how detailed you wanna get, you could test all your event names are valid).</p>
<p>EDIT: sorry <a class="mention" href="/u/hkrutzer" rel="nofollow">@hkrutzer</a> I realize now you essentially said this already.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301857" 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/integration-testing-is-hard/58406/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-301857" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301857"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="301859" data-post-id="301859">
  <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="sodapopcan" data-post="12" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>you would want to test that a chat message triggers a telemetry event and then a general test that telemetry events are being consumed and saving to the db</p>
</blockquote>
</aside>
<p>This can and should be reformed into sending messages to dedicated OTP process(es) and just assert they are received. Persistence of telemetry is an implementation detail that has zero relevance to your app’s tests.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301859" 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/integration-testing-is-hard/58406/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-301859" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301859"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="301860" data-post-id="301860">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hkrutzer" data-post="10" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/e0b2c6/48.png" class="avatar"> hkrutzer:</div>
<blockquote>
<p>Obviously if you are calling a function which calls insert directly or performs a cast which leads to calling it.</p>
</blockquote>
</aside>
<p>If process A does a cast to process B, then process A can afterwards call <code>:sys.get_state</code> on B and after that returns you are guaranteed that the cast has also been handled. Messages between two processes A and B are always received in the order they are sent, and so the <code>GenServer.call</code> done inside <code>:sys.get_state</code> will be processed after the cast.</p>
<p>Telemetry hooks are always fired from the the process that emits the telemetry event, eg the process calling <code>Repo.insert</code>. So as far as I can tell if your test pid calls a function that calls <code>Repo.insert</code>, and then that has telemetry <code>cast</code> to some other <code>pid2</code>, your test code should be able to <code>:sys.get_state(pid2)</code> and at that point you’re guaranteed to be after it has processed the cast.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301860" data-batch-url="/posts/batch_likers">
                        5
                      </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/integration-testing-is-hard/58406/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-301860" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301860"
                     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="301865" data-post-id="301865">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hkrutzer" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hkrutzer
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sodapopcan" data-post="12" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p>But it would seem to me you would want to test that a chat message triggers a telemetry event and then a general test that telemetry events are being consumed and saving to the db</p>
</blockquote>
</aside>
<p>That is kind of true, but the telemetry is transformed first, so there is an interdependency between the data across the modules and processes.</p>
<p>For example, you fire from process A some telemetry that contains a boolean value. You receive the telemetry in process B, and for some reason you need to transform it into a 0 or 1 and save it into your database. You test these things separately. Now if someone changes some code so that A no longer produces a boolean, but instead produces a string (or a 0 or 1, doesn’t matter). They also change A’s tests. All looks to be fine. But after deployment, B tries to consume the telemetry and now it breaks, because its format has changed.</p>
<p>You can imagine a similar case where data isn’t transformed in this way in B, but instead filtered, merged etc.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301865" 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/integration-testing-is-hard/58406/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-301865" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301865"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="301867" data-post-id="301867">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hkrutzer" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hkrutzer
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="benwilson512" data-post="14" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/48/1457_2.png" class="avatar"> benwilson512:</div>
<blockquote>
<p>If process A does a cast to process B, then process A can afterwards call <code>:sys.get_state</code> on B and after that returns you are guaranteed that the cast has also been handled. Messages between two processes A and B are always received in the order they are sent, and so the <code>GenServer.call</code> done inside <code>:sys.get_state</code> will be processed after the cast.</p>
</blockquote>
</aside>
<p>Thanks! I didn’t think of the <code>:sys.get_state</code> trick. That will probably solve at least this specific case!</p>
<aside class="quote no-group" data-username="benwilson512" data-post="14" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/48/1457_2.png" class="avatar"> benwilson512:</div>
<blockquote>
<p>So as far as I can tell if your test pid calls a function that calls <code>Repo.insert</code>, and then that has telemetry <code>cast</code> to some other <code>pid2</code>, your test code should be able to <code>:sys.get_state(pid2)</code> and at that point you’re guaranteed to be after it has processed the cast.</p>
</blockquote>
</aside>
<p>Not entirely, I have one process (A) that fires telemetry, which is cast to another process (B) and B then performs the insert (and in some cases waits for multiple events, to merge them together). But your suggestion should still work if I <code>get_state(B)</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301867" 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/integration-testing-is-hard/58406/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-301867" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301867"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="301868" data-post-id="301868">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hkrutzer" data-post="6" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/e0b2c6/48.png" class="avatar"> hkrutzer:</div>
<blockquote>
<p>This looks like an actual fallacy namely circular reasoning:</p>
<ol>
<li>You need a behavior because without one, it’s hard to test stuff</li>
<li>When it’s hard to test stuff, you need a behavior</li>
</ol>
</blockquote>
</aside>
<p>I feel you on this view as I felt it at first, but the way the way I see it is that we create mocks for wrappers around services (if we’re following “don’t mock what you don’t own”).  Even if we only end up having one production implementation, it’s still probably a good idea to define a behaviour.  For example, perhaps there are some public functions added to an implementation that aren’t actually part of the contract.  That’s the way I see it, at least, but I’ve been wrong a bunch over the past 24 hours <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" 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="301868" 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/integration-testing-is-hard/58406/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-301868" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301868"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="301869" data-post-id="301869">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hkrutzer" data-post="6" data-topic="58406">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/e0b2c6/48.png" class="avatar"> hkrutzer:</div>
<blockquote>
<p>There is a process A that generates telemetry as a side effect</p>
</blockquote>
</aside>
<p>I haven’t followed the complete discussion, but to me this sounds like the sole reason you have a hard time testing this. Instead of waiting for process A to generate telemetry can you make it do that on command? If so your test can command it to do what it does and you can expect all the downstream effects to happen and assert on the resulting db records.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="301869" 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/integration-testing-is-hard/58406/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-301869" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="301869"
                     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>