<?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: Wilberto Morales</title>
    <description>The latest articles on DEV Community by Wilberto Morales (@wilbertom).</description>
    <link>https://dev.to/wilbertom</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%2F435516%2Fdeb79a1e-9336-47d7-89b9-4550dc506571.png</url>
      <title>DEV Community: Wilberto Morales</title>
      <link>https://dev.to/wilbertom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wilbertom"/>
    <language>en</language>
    <item>
      <title>Use Signals to Safely Stop processes</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Fri, 31 Dec 2021 04:05:29 +0000</pubDate>
      <link>https://dev.to/wilbertom/use-signals-to-safely-stop-processes-4n60</link>
      <guid>https://dev.to/wilbertom/use-signals-to-safely-stop-processes-4n60</guid>
      <description>&lt;p&gt;Here are some times you probably don't want your process to stop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When saving data to disk or some other resource.&lt;/li&gt;
&lt;li&gt;When in the middle of some long running job.&lt;/li&gt;
&lt;li&gt;When doing something business critical.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can add signal handlers that place your process into a state of stopping the&lt;br&gt;
next time it is ready.&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;signal&lt;/span&gt;  &lt;span class="c1"&gt;# (1)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;should_quit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;  &lt;span class="c1"&gt;# (2)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;stop_signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SIGUSR1&lt;/span&gt;  &lt;span class="c1"&gt;# (3)
&lt;/span&gt;    &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop_signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# (4)
&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Starting - process id is: &lt;/span&gt;&lt;span class="si"&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;getpid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# (5)
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Send &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop_signal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; to safely stop"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# (6)
&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;should_quit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Doing work, please do not interrupt this."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# (7)
&lt;/span&gt;        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Done with this unit of work"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stopping"&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;on_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# (8)
&lt;/span&gt;    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;should_quit&lt;/span&gt;

    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received request to stop...doing so when it is safe."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;should_quit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# (9)
&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The builtin &lt;a href="https://docs.python.org/3/library/signal.html"&gt;signal&lt;/a&gt; module in Python. Most programming languages will provide a similar module for using signals.&lt;/li&gt;
&lt;li&gt;We use a global variable(&lt;code&gt;should_quit&lt;/code&gt;) to keep track of when the program should stop.&lt;/li&gt;
&lt;li&gt;We are choosing &lt;code&gt;SIGUSR1&lt;/code&gt; for this example. There are many different signals,
some are reserved for special purposes by your OS or programming language.
&lt;code&gt;SIGUSR1&lt;/code&gt; is set aside for programmers to define their own custom handler.&lt;/li&gt;
&lt;li&gt;Here we are saying: when my program receives a &lt;code&gt;SIGUSR1&lt;/code&gt;, I want you to call the &lt;code&gt;on_signal&lt;/code&gt; handler.&lt;/li&gt;
&lt;li&gt;We print the process ID to make it easier to send the signal to the correct process.&lt;/li&gt;
&lt;li&gt;We print the signal to make it easier to send the correct signal. On my OS, behind the scenes &lt;code&gt;SIGUSR1&lt;/code&gt; maps to &lt;code&gt;10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;This line represents some task your program is doing that you do not wish to interrupt.&lt;/li&gt;
&lt;li&gt;A signal handler is a regular function that takes two parameters &lt;code&gt;signum&lt;/code&gt; and &lt;code&gt;frame&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on_signal&lt;/code&gt; simply sets &lt;code&gt;should_quit&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;, the next time we check against it, the programs stops.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is an example run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python program.py
Starting - process &lt;span class="nb"&gt;id &lt;/span&gt;is: 25716
Send 10 to safely stop
Doing work, please &lt;span class="k"&gt;do &lt;/span&gt;not interrupt this.
Done with this unit of work
Doing work, please &lt;span class="k"&gt;do &lt;/span&gt;not interrupt this.
Done with this unit of work
Doing work, please &lt;span class="k"&gt;do &lt;/span&gt;not interrupt this.
Done with this unit of work
Doing work, please &lt;span class="k"&gt;do &lt;/span&gt;not interrupt this.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that our process ID is &lt;code&gt;25716&lt;/code&gt; and the signal is &lt;code&gt;10&lt;/code&gt;. So to send our signal&lt;br&gt;
we execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt; 25716
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Received request to stop...doing so when it is safe.
Done with this unit of work
Stopping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our processs receives the signal and calls our handler but the program resumes&lt;br&gt;
its work without interruption. The next time around, it sees that we requested&lt;br&gt;
to stop and does so.&lt;/p&gt;

</description>
      <category>python</category>
      <category>linux</category>
      <category>systems</category>
    </item>
    <item>
      <title>Making Decisions</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Tue, 31 Aug 2021 04:03:40 +0000</pubDate>
      <link>https://dev.to/wilbertom/making-decisions-31nd</link>
      <guid>https://dev.to/wilbertom/making-decisions-31nd</guid>
      <description>&lt;p&gt;Making decisions can be difficult; here are my models for making them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scorecards
&lt;/h2&gt;

&lt;p&gt;Imagine you need to choose between different vendors for an Anti-Virus. &lt;br&gt;
Looking at alternative vendor websites makes it hard to compare solutions. It's easy to make a choice that doesn't satisfy all the requirements. Having&lt;br&gt;
a scorecard that compares all the solutions makes it easier and reduces mistakes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;AV X&lt;/th&gt;
&lt;th&gt;AV Y&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Windows 8&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows 10&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Patch Management&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monthly Cost&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scorecards are a tool I first learned about from a recruiting book and have repurposed for engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Radar charts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Radar_chart"&gt;Radar Charts&lt;/a&gt; are a great way to compare the&lt;br&gt;
attributes of different solutions. As software engineers, we need to remind ourselves that there are no&lt;br&gt;
silver bullets. Radar charts make this obvious.&lt;/p&gt;

&lt;p&gt;For example, imagine you need to choose between different software architectures. Their "ilities" should be considered—scalability, observability, changeability, reversibility, and so on.&lt;/p&gt;

&lt;p&gt;List the "ilities" that are important to you and graph them&lt;br&gt;
for each alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Costs for being wrong
&lt;/h2&gt;

&lt;p&gt;Keep in mind the cost (usually money and time), risk, long-term consequences, and reversibility of the decision.&lt;/p&gt;

&lt;p&gt;If these aren't severe and you are OK with the consequences, &lt;strong&gt;don't waste time making the decision&lt;/strong&gt;.&lt;br&gt;
Just make it and move on.&lt;/p&gt;

&lt;p&gt;I've seen too many people anguish over choices that they could have made in a few minutes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React Testing Library - Testing a Node Attribute</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Mon, 29 Mar 2021 23:22:45 +0000</pubDate>
      <link>https://dev.to/wilbertom/react-testing-library-testing-a-node-attribute-2ob</link>
      <guid>https://dev.to/wilbertom/react-testing-library-testing-a-node-attribute-2ob</guid>
      <description>&lt;p&gt;You can test HTML node attributes with the &lt;a href="https://www.npmjs.com/package/@testing-library/jest-dom#tohaveattribute"&gt;toHaveAttribute&lt;/a&gt; matcher. When you need more than an equality check, though, you can use &lt;code&gt;getAttribute&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, here is a component that has a &lt;code&gt;mailto&lt;/code&gt; link. Let's test the subject and recipient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mailto:example@example.com?subject=Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could write one test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./component.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/jest-dom/extend-expect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;has a subject and correct recipient&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toHaveAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mailto:example@example.com?subject=Hello&lt;/span&gt;&lt;span class="dl"&gt;"&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;This test case is testing two things at once though, the "and" in the test name gives it&lt;br&gt;
away.&lt;/p&gt;

&lt;p&gt;Lets test each idea seperately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./component.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;has a subject&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sr"&gt;/subject=Hello/&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emails the example email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sr"&gt;/mailto:example@example.com/&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;



</description>
      <category>react</category>
      <category>testing</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Library Testing Functionality</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Wed, 09 Sep 2020 01:47:54 +0000</pubDate>
      <link>https://dev.to/wilbertom/library-testing-functionality-3nh1</link>
      <guid>https://dev.to/wilbertom/library-testing-functionality-3nh1</guid>
      <description>&lt;p&gt;We would save a lot of developer time if libraries included testing functionality. One example of this is the Python &lt;a href="https://requests.readthedocs.io/en/master/"&gt;requests&lt;/a&gt; library. It's a beautiful piece of software that makes dealing with HTTP requests easy. Testing that you're making the correct HTTP requests is not straightforward, though.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use the built-in python &lt;a href="https://docs.python.org/3/library/unittest.mock.html"&gt;mock&lt;/a&gt; library. I won't reiterate points that have been made elsewhere but mocking usually leads to code smells.&lt;/li&gt;
&lt;li&gt;You can use the &lt;a href="https://github.com/getsentry/responses"&gt;responses&lt;/a&gt; library. It helps, but it becomes unmanageable quickly. It's challenging to set up expected responses, especially since there could be multiple per test. Additionally, it seems that it is unmaintained. I have run into bugs around &lt;a href="https://github.com/getsentry/responses/issues/322"&gt;passthrus and random test ordering&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can use another third party testing library. I don't have experience with them and settled on building a personal one. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At work(&lt;a href="https://www.printwithme.com/"&gt;PrintWithMe&lt;/a&gt;) we have multiple internal libraries. For any new one added, we make it a habit to provide testing functionality, including fakes/doubles, fixtures, setup/teardown, and other helper functions.&lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Tips for Code Assignments</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Thu, 20 Aug 2020 18:05:09 +0000</pubDate>
      <link>https://dev.to/wilbertom/tips-for-code-assignments-57l0</link>
      <guid>https://dev.to/wilbertom/tips-for-code-assignments-57l0</guid>
      <description>&lt;p&gt;Over the last six months, I have been reviewing coding assignments while searching for our next Software Engineer at &lt;a href="https://www.printwithme.com/"&gt;PrintWithMe&lt;/a&gt;. Here are some tips I would give developers on the other side of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the programming language you're best at
&lt;/h2&gt;

&lt;p&gt;You might feel this is a good time to test a new programming language you have been learning. The problem is that using a language you don't have real experience with will lead to mistakes. If the reviewer knows the programming language in your submission, they will quickly spot places where you don't measure against experienced developers using that programming language.&lt;/p&gt;

&lt;p&gt;Another reason developers do this is that they feel the need to use the programming language listed in the job posting. Ask about this ahead of time, but in my experience, great companies don't care what programming language you use. They understand that a good developer is a good developer, and picking up a new language will not be a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run your code through tools
&lt;/h2&gt;

&lt;p&gt;Take the time to run your code through formatting, static analysis, and other tools. It shows that you care about code quality, and it will catch common errors. If the person reviewing your code runs it through these tools, they will be put off immediately by warnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test your code
&lt;/h2&gt;

&lt;p&gt;I'm surprised by the number of developers who still don't know about &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; or testing in general. If you're one of them, take the time to learn it and use it on your code submission. If you are applying for any company where high-quality systems are important, tests will be a requirement. Even if they are not specified in the instructions, add them, they will make you stand out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make sure your submission is correct
&lt;/h2&gt;

&lt;p&gt;Sometimes I get submissions that are straight-up wrong. This is because the developer forgot to test against corner cases like when the input is 0, an empty string, or something along those lines.&lt;/p&gt;

&lt;p&gt;After making changes to your code, test &lt;em&gt;everything&lt;/em&gt; again. A few times, candidates would make last-minute changes and forget to test running the program. There's nothing worse than your submission crashing on the first run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write clear documentation
&lt;/h2&gt;

&lt;p&gt;Document how to test and run the code. Add a description of your design decisions. This might be controversial, but I'm going to come right out and say it: reading three paragraphs on why you chose "dynamic algorithms" is boring. Add documentation for humans.&lt;/p&gt;

&lt;p&gt;Even though this is something I will forgive if the code is good, it's a place to stand out. A developer needs to communicate clearly with everyone in the company, not just other developers. Its something a lot of engineers struggle with, myself included. If you show me you are better at it than me, I want you on my team.&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>career</category>
      <category>interview</category>
    </item>
    <item>
      <title>Testing Logger</title>
      <dc:creator>Wilberto Morales</dc:creator>
      <pubDate>Wed, 19 Aug 2020 23:14:19 +0000</pubDate>
      <link>https://dev.to/wilbertom/testing-logger-2i63</link>
      <guid>https://dev.to/wilbertom/testing-logger-2i63</guid>
      <description>&lt;p&gt;Logging is sometimes a part of your requirements. For example, you might want to issue a &lt;code&gt;warning&lt;/code&gt; anytime some security event occurs. I like to test these events using a &lt;code&gt;TestingLogger&lt;/code&gt; class that can stand in place of a real logger.&lt;/p&gt;

&lt;p&gt;First, make your loggers parameters to your functions and classes. &lt;strong&gt;Globals make testing difficult.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logged something!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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





&lt;div class="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;example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logged something!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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



&lt;p&gt;Now you can use the &lt;code&gt;TestingLogger&lt;/code&gt; during tests. If it quacks like a duck, its a duck. Let's make a &lt;code&gt;TestingLogger&lt;/code&gt; that quacks like a logger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestingLogger&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&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;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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



&lt;p&gt;This class implements the methods you will call 99% of the time against a logger. Instead of logging though, it will capture the messages in a &lt;code&gt;messages&lt;/code&gt; list. You can make assertions against this list in your tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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_example_function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TestingLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s"&gt;"Logged something!"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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_example_class&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TestingLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s"&gt;"Logged something!"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

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



&lt;p&gt;You can expand on this idea in many ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capture the log level if you need to assert against them.&lt;/li&gt;
&lt;li&gt;Inherit from &lt;code&gt;list&lt;/code&gt; and use &lt;code&gt;self.append&lt;/code&gt; to capture logs. Then you can make assertions against
the testing logger directly instead of &lt;code&gt;logger.messages&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Capture the &lt;code&gt;str&lt;/code&gt; value of exceptions instead of the instances in &lt;code&gt;TestingLogger.exception&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If passing loggers as parameters is cumbersome, you can create a default when one isn't specified, giving you flexibility in tests and convenience in the rest of the places.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to learn more about this testing style, check out the &lt;a href="https://amzn.to/2Q7TfwB"&gt; Python architecture book&lt;/a&gt;. It is one of the best programming books I have read in a long time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/gp/product/1492052205/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1492052205&amp;amp;linkCode=as2&amp;amp;tag=wilbertom-20&amp;amp;linkId=0bf0441103f5c75fd24e0eee42f22b21"&gt;&lt;img src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;amp;MarketPlace=US&amp;amp;ASIN=1492052205&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL250_&amp;amp;tag=wilbertom-20"&gt;&lt;/a&gt;&lt;a href="//ir-na.amazon-adsystem.com/e/ir?t=wilbertom-20&amp;amp;l=am2&amp;amp;o=1&amp;amp;a=1492052205" class="article-body-image-wrapper"&gt;&lt;img src="//ir-na.amazon-adsystem.com/e/ir?t=wilbertom-20&amp;amp;l=am2&amp;amp;o=1&amp;amp;a=1492052205" width="1" height="1" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As an Amazon Associate, I earn from qualifying purchases&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
      <category>tdd</category>
      <category>logging</category>
    </item>
  </channel>
</rss>
